ArduinoでNTPサーバーにアクセスする

Arduino
この記事は約1分で読めます。

パブリックNTPサーバーにアクセスして現在時刻を手に入れます

ベースにしているのはスケッチの例にあるNTPClientです


/*
* 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アドレス指定できたら小さく出来るかも?(指定出来るようにコントロール出来ないといけないけど)

コメント