ESP8266のntpの設定は1行で

  • 10
    いいね
  • 0
    コメント

概要

ntp(ネットワーク・タイム・プロトコル)はネット経由で時計を合わせるための通信規約で、ネットワーク上のタイムサーバと同期させることで正確な時刻を簡単に得ることができる。

esp8266 Arduinoでも、利用することができるが、自前でntpのパケットの作成・送受信を行うスケッチの例が提供されているためか、自前でやらなければならないと誤解している人がいるかもしれません。

esp8266 Arduinoにはntpの機能が組み込まれていて、特にライブラリをインクルードしなくても、設定するだけでntp同期の時刻情報を得ることができます。

使い方

configTime()関数で設定を行います。宣言はArduino.hにありますので、特にincludeする必要はありません。

Arduino.h
extern "C" void configTime(long timezone, int daylightOffset_sec,
    const char* server1, const char* server2 = nullptr, const char* server3 = nullptr);

日本で使う場合、timezoneは 3600*9, daylightOffsetは0となります。

ntpの同期が完了すると time()関数がUNIX時間(1970年1月1日0時0分0秒からのうるう秒を含まない秒数)を返すようになるので、これをlocaltime()関数などで変換し利用します。同期が完了するまではtime()関数は0を返すので、変な時刻を表示させたくない場合は、非0が返るまで待つようにすると良いでしょう。 time()やlocaltime()の使用にはtime.hをインクルードする必要があります。

サンプルプログラム

使用例を示します。

clock.ino
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <time.h>

#define WIFI_SSID   "your_wifi_ssid"
#define WIFI_PASSWORD   "your_wifi_password"
#define JST     3600*9

void setup() {
  Serial.begin(115200);
  delay(100);
  Serial.print("\n\nReset:\n");

  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while(WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    delay(500);
  }
  Serial.println();
  Serial.printf("Connected, IP address: ");
  Serial.println(WiFi.localIP());

  configTime( JST, 0, "ntp.nict.jp", "ntp.jst.mfeed.ad.jp");
}

void loop() {
  time_t t;
  struct tm *tm;
  static const char *wd[7] = {"Sun","Mon","Tue","Wed","Thr","Fri","Sat"};

  t = time(NULL);
  tm = localtime(&t);
  Serial.printf(" %04d/%02d/%02d(%s) %02d:%02d:%02d\n",
        tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
        wd[tm->tm_wday],
        tm->tm_hour, tm->tm_min, tm->tm_sec);
  delay(1000);
}

実行時のシリアルモニタは次のようになります。

sc161108a1.png

もう少し詳しい話

configTime(), time()等のソースを見ると、それぞれ sntp.cの対応関数を呼び出しているようで、sntp.cをみると1時間に1回 ntpパケットを投げているようです。