Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

ESP8266のntpの設定は1行で

概要

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

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

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

追記: 2020/05/24:

esp8266 arduino ver 2.7.0以降、従来説明した方法では時刻が18時間ずれるようになりました。従来は configTime()関数で設定を行ってましたが、2.7.0以降は configTzTime()関数を使用することをお勧めします。

使い方

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

Arduino.h
// esp32 api compatibility
inline void configTzTime(const char* tz, const char* server1,
    const char* server2 = nullptr, const char* server3 = nullptr)

日本で使う場合、tzは "JST-9"となります。tzに指定可能な文字列はTZ.hを参照してください。

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"); // esp8266/arduino ver 2.6.3まで有効
  // configTime( -JST, 0, "ntp.nict.jp", "ntp.jst.mfeed.ad.jp"); // 2.7.0, 2.7.1ならこれでも可
  configTzTime("JST-9", "ntp.nict.jp", "ntp.jst.mfeed.ad.jp");   // 2.7.0以降, esp32コンパチ
}

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("ESP8266/Arduino ver%s :  %04d/%02d/%02d(%s) %02d:%02d:%02d\n",
        __STR(ARDUINO_ESP8266_GIT_DESC),
        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);
}

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

sc200524a.PNG

もう少し詳しい話

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

h_nari
3Dプリントとか電子工作とかプログラミングしています。
http://blog3.narimatu.net/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away