パブリックNTPサーバーにアクセスして現在時刻を手に入れます
ベースにしているのはスケッチの例にあるNTPClientです
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* UdpNtpClientV1 | |
*/ | |
#include <SPI.h> | |
#include <Ethernet.h> | |
#include <EthernetUdp.h> | |
/* | |
* LANシールド | |
* 4, 10, 11, 12, 13 | |
* SPI: 11, 12, 13 | |
* LAN: 10 | |
*/ | |
// Macアドレス | |
byte mac[] = {0x90, 0xA2, 0xDA, 0x74, 0x3D, 0x5D}; | |
//UDPパケット待受用ポート | |
unsigned int udpLocalPort = 8888; | |
// NTPサーバー | |
char timeServer[] = "ntp.nict.jp"; | |
//NTPパケットのサイズ | |
#define NTPPACEKTSIZE 48 | |
//バッファー | |
byte packetBuffer[NTPPACEKTSIZE]; | |
//Udpインスタtンス | |
EthernetUDP Udp; | |
void setup() { | |
Serial.begin(9600); | |
while(!Serial); //シリアル接続があるまで待機 | |
Serial.println("StartUp"); | |
//DHCPで立ち上げ | |
if( Ethernet.begin(mac) == 0) { | |
Serial.println("DHCPError"); //HDCP失敗 | |
} | |
Serial.print("Server IP: "); | |
Serial.println(Ethernet.localIP()); //IPアドレス出力 | |
Udp.begin(udpLocalPort); //待受ポートを指定してUdp接続開始 | |
} | |
void loop() { | |
delay(10000); | |
sendNTPpacket(timeServer); | |
viewTime(); | |
Ethernet.maintain(); //DHCP周りの更新 | |
} | |
int viewTime() { | |
//パケットデータがあったら(受け取っていたら) | |
if( Udp.parsePacket()) { | |
//必要分だけバッファに読み込み | |
Udp.read(packetBuffer,NTPPACEKTSIZE); | |
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); | |
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); | |
//1900年からの経過秒数 | |
unsigned long secsSince1900 = highWord << 16 | lowWord; | |
//UnixTime | |
const unsigned long seventyYears = 2208988800UL; | |
unsigned long epoch = secsSince1900 – seventyYears; | |
Serial.print("UnixTime: "); | |
Serial.println(epoch); | |
//JST | |
Serial.print("JST Time is "); | |
//Serial.print((epoch % 86400L) / 3600); //時(UTC) | |
Serial.print( ((epoch % 86400L) / 3600 + 9) + ( ((epoch % 86400L) / 3600 + 9) >= 24? -24:0)); //時(JST) | |
Serial.print(':'); | |
if( ((epoch % 3600) / 60) < 10) | |
Serial.print('0'); //十分以下場合は桁合わせに'0'を追加 | |
Serial.print((epoch % 3600) / 60); //分 | |
Serial.print(':'); | |
if((epoch % 60) < 10) | |
Serial.print('0'); //十秒以下の場合は桁合わせに(ry | |
Serial.println(epoch % 60 ); | |
} | |
} | |
void sendNTPpacket(char* address) { | |
// packetBufferを0で初期化 | |
memset(packetBuffer, 0, NTPPACEKTSIZE); | |
packetBuffer[0] = 0b11100011; | |
packetBuffer[1] = 0; | |
packetBuffer[2] = 6; | |
packetBuffer[3] = 0xEC; | |
packetBuffer[12] = 49; | |
packetBuffer[13] = 0x4E; | |
packetBuffer[14] = 49; | |
packetBuffer[15] = 52; | |
//パケット送信開始 | |
Udp.beginPacket(address, 123); | |
Udp.write(packetBuffer, NTPPACEKTSIZE); | |
//パケット送信終了 | |
Udp.endPacket(); | |
} |
実はほとんど同じ、
変更しているところは日本時刻に変えてるぐらいしか覚えてないな. . .w
コメントも日本語に(分かる範囲、一部感)しているけどまだまだ変更するところがありそう
一部よく分ってないところがあるからそこも知りたいな. . .
今後追加したい機能
- シリアル通信を初めなくても通信を始める
- 更新間隔を長めに
- 日本時間に変換するところもっとマシなものないかな
- メモリをスケッチに35%、変数に31%使ってるのでできれば減らしたい
- DHCPじゃなくてIPアドレス指定できたら小さく出来るかも?(指定出来るようにコントロール出来ないといけないけど)
コメント