Powered By 特殊電子回路

最終更新日 平成26年5月15日

English

トップ ページチュートリアル仕様・機能 ダウンロード マニュアルWebコンパイラ

RXduinoのサンプルコード

ツイート

サンプルコード集に戻る

NTPで時計を合わせる

起動した後、n キーを押すとNTPで時計を合わせます。

// RXduino sample programs.
// (C)2012-2014 Copyright TokushuDenshiKairo Inc.

#include <rxduino.h>
#include <Ethernet.h>
#include <rtc.h>
#include <time.h>

TEthernet Ethernet;
BOOL onReceiveUDP(unsigned char dest_ip[4], unsigned char src_ip[4],
	unsigned short dest_port,unsigned  short src_port, unsigned char *data, short datalen);
	
bool ether_init = false;

#if RTC_LIBRARY_VERSION >= 0x01060000
 #define _MYRTC RXRTC
#else
 #define _MYRTC RTC
#endif

void ShowRegs(const char *mes)
{
	printf("%s\n",mes);
	printf("SOSCWTCR=%02X\n",*(volatile unsigned char *)0x000800A3);
	printf("SOSCCR=%02X\n",*(volatile unsigned char *)0x00080033);
	printf("RCR1=%02X\n",*(volatile unsigned char *)0x0008c422);
	printf("RCR2=%02X\n",*(volatile unsigned char *)0x0008c424);
	printf("RCR3=%02X\n",*(volatile unsigned char *)0x0008c426);
	printf("RCR4=%02X\n",*(volatile unsigned char *)0x0008c428);
}

bool EtherInit()
{
    byte mac[] = {2,0,0,0,0,1};
    Ethernet.begin(mac);
    Ethernet.registUdpHandler(onReceiveUDP);
	printf("My ip addr = %s\n",Ethernet.localIP());
	ether_init = true;
	return Ethernet.isLinkup();
}

void ShowHelp()
{
	printf("USAGE:\n");
	printf(" a: Adjust RTC to someday\n");
	printf(" s: Show registers\n");
	printf(" l: Enter osc into low power mode (but it may not able to continue operating)\n");
	printf(" r: Reboot this application again\n");
	printf(" f: Reboot gr-firmware \n");
	printf(" d: Renrew ipaddress by DHCP.\n");
	printf(" n: Sync to NTP server (ntp.nict.jp) \n");
	printf(" h ?: Show this help \n");
	printf("\n");
}

void setup()
{
	pinMode(PIN_LED0, OUTPUT);
	pinMode(PIN_LED1, OUTPUT);
	pinMode(PIN_LED2, OUTPUT);
	pinMode(PIN_LED3, OUTPUT);
	pinMode(PIN_SW  , INPUT);

	digitalWrite(PIN_LED0, 1);
	Serial.begin(38400, SCI_AUTO);
	Serial.setDefault();
	digitalWrite(PIN_LED1, 1);

	printf("------------------------------\n");
	printf("RX RTC test program 2\n");
	printf("------------------------------\n");
	printf("This program diagnoses and initializes RTC.\n");
	ShowHelp();
//	ShowRegs("Default registers");
	int ret = _MYRTC::begin();
/*
	if(ret < 2)
	{
		_MYRTC::setDateTime( 2013, 1, 2, 2, 14, 00 );
	}
*/
//	printf("rtc init result=%d\n",ret);

//	ShowRegs("After initialization");
}

unsigned long lasttime = 0;

void loop()
{
	if(Serial.available())
	{
		char c = Serial.read();
		if(c == 'a') // adjust
		{
			_MYRTC::setDateTime( 2013, 2, 22,  8, 17, 20 );
		}
		if(c == 's') // show registers
		{
			ShowRegs("Current registers");
		}
		if(c == 'l') // low power mode
		{
			*(volatile unsigned char *)0x0008c426   = 0x03; // RTCDV=001
			ShowRegs("Low power mode");
		}
		if(c == 'r') // reboot and launch this application again
		{
			printf("Reboot userapp\n");delay(100);
			system_reboot(REBOOT_USERAPP); 
		}
		if(c == 'f') // reboot and launch gr firmware
		{
			printf("Reboot firmware\n");delay(100);
			system_reboot(REBOOT_FIRMWARE); 
		}
		if((c == '?') || (c == 'h'))
		{
			ShowHelp(); 
		}
		if(c == 'd')
		{
			if(!ether_init) EtherInit();
			if(Ethernet.isLinkup())
			{
				printf("Renew IP address with DHCP...");
				if(Ethernet.dhcp())
				{
					printf("Success! My ip addr = %s\n",Ethernet.localIP());
				}
				else
				{
					printf("failed\n");
				}
			}
		}
		if(c == 'n')
		{
			if(!ether_init) EtherInit();
			if(Ethernet.isLinkup())
			{
				printf("NTP test : ntp.nict.jp is ");
				byte *ip = Ethernet.gethostbyname("ntp.nict.jp");
				printf("Server address: %d.%d.%d.%d\n",ip[0],ip[1],ip[2],ip[3]);
				unsigned char buf[12*4];
				memset(buf,0,12*4);
				buf[0] = 0xe3; // 閏秒:警告 バージョン4 クライアント
				buf[1] = 0x00; // 階層不明
				buf[2] = 0x04; // 8秒間隔
				buf[3] = 0xfa;
				buf[5] = 0x01;
				buf[9] = 0x01;
				Ethernet.sendUDP(ip,123,buf,12*4);
			}
			else
			{
				printf("Ether is not connected\n");
			}
		}
	}
	if(millis() - lasttime >= 1000)
	{
		int year,mon,day,hour,min,sec;
	    _MYRTC::getDateTime( year, mon, day, hour, min, sec );
		printf("%04d/%02d/%02d %02d:%02d:%02d\n",year, mon, day, hour, min, sec);
		lasttime = millis();
	}
}

BOOL onReceiveUDP(
	unsigned char dest_ip[4],
	unsigned char src_ip[4],
	unsigned short dest_port,
	unsigned short src_port,
	unsigned char *data, // UDPパケットのデータ部
	short datalen          // UDPパケットのデータの長さ(ヘッダは含まない)
)
{
	if(dest_port == 123) // NTP受信!
	{
		unsigned char LeapIndicator =  data[0] >> 6;
		unsigned char VersionNumber = (data[0] >> 3) & 0x07;
		unsigned char Mode          = (data[0] >> 0) & 0x07;
		unsigned char Stratum       = data[1];
		signed char Precision       = data[3];
		char ReferenceID[5];
		memcpy(ReferenceID,&data[12],4);
		ReferenceID[4] = '\0';
		unsigned long TransTimeH = (data[40] << 24) | (data[41] << 16) | (data[42] << 8) | data[43];
		
		printf("NTPv%d length=%d Mode:",VersionNumber,datalen);
		switch(Mode)
		{
			case 0:	printf("Reserved, "); break;
			case 1:	printf("Synmetic Active, "); break;
			case 2:	printf("Synmetic Client, "); break;
			case 3:	printf("Client, "); break;
			case 4:	printf("Server, "); break;
			case 5:	printf("Broadcast, "); break;
			case 6:	printf("Reserved for NTP control, "); break;
			case 7:	printf("Reserved for private, "); break;
			default:printf("Undefined, "); break;
		}
		printf("Leap indicator:(%d)\n",LeapIndicator);
		printf("Stratum %d\n",Stratum);
		printf("precisiton %d\n",Precision);
		printf("Reference-ID: %s\n",ReferenceID);

		// NTP時刻をUNIX時刻に変換
		time_t t = TransTimeH - 2208988800UL;
		t += 9*60*60; // 日本標準時に変換
		struct tm *t_st = localtime(&t);
		printf("Transit Timestamp %s\n",asctime(t_st));
		printf("Set RTC datetime with NTP result.\n");
		
		int year,mon,day,hour,min,sec;
		year  = t_st->tm_year;
		mon   = t_st->tm_mon + 1;
		day   = t_st->tm_mday;
		hour  = t_st->tm_hour;
		min   = t_st->tm_min;
		sec   = t_st->tm_sec;

		_MYRTC::setDateTime(year,mon,day,hour,min,sec);
		return TRUE;
	}

	return false; // この関数で処理したことにしない
}


  

動作イメージ

最初はめちゃくちゃな時間を指していますが、NTPで通信した後は正しい時間になっています。

 

 

 


サンプルコード集に戻る

 

(C)2012-2014 特殊電子回路株式会社 All Rights Reserved