インターネットに接続して正確な時刻を取得する with Arduino IDE
はじめに
ESP32は、起動している限り時刻を進めてくれます。
ただし、起動直後は1970年1月1日午前0時0分0秒(UNIXエポック)からスタートします。また、時刻を刻む内蔵RTCの精度はあまりよくなく、1日で数分はズレると言われています。
そのため、インターネットにつなげられる環境であれば、NTPは利用した方が良いでしょう。時刻が合っていると、異常時のログ収集などでも便利です。
UNIX時間についての詳細はWikipediaへ。

開発環境
OS : Windows 11 Pro
ESP32:ESP-WROOM-32
統合開発環境 : Arduino IDE 2.3.2
Arduino core for the ESP32:2.0.17
使用ライブラリ:なし
使用パーツ
ESP32開発ボード(38Pin)

作業内容
スケッチ作成
使用API:sntp_set_time_sync_notification_cb() / configTime()
#include <WiFi.h>
#include "time.h"
const char* ssid = "xxxxxx";
const char* password = "xxxxxx";
const char* ntpServer1 = "ntp.nict.jp";
const char* ntpServer2 = "time.google.com";
const char* ntpServer3 = "ntp.jst.mfeed.ad.jp";
const long gmtOffset_sec = 9 * 3600;
const int daylightOffset_sec = 0;
void printLocalTime()
{
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println("Failed to obtain time");
return;
}
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}
// Callback function (get's called when time adjusts via NTP)
void timeavailable(struct timeval *t)
{
Serial.println("Got time adjustment from NTP!");
}
void setup()
{
Serial.begin(115200);
//connect to WiFi
Serial.printf("Connecting to %s ", ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" CONNECTED");
//init and get the time
sntp_set_time_sync_notification_cb( timeavailable );
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2, ntpServer3);
printLocalTime();
//disconnect WiFi as it's no longer needed
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
}
void loop()
{
delay(1000);
printLocalTime();
}
コード説明
[ssid]と[password]の内容は変更します。
const char* ssid = "xxxxxx";
const char* password = "xxxxxx";
NTPを使用しているコードは43行目と44行目です。
sntp_set_time_sync_notification_cb( timeavailable );
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2, ntpServer3);
1つ目の[sntp_set_time_sync_notification_cb()]は、NTPの時刻修正実行時にコールバックする関数を設定できます。
sntp_set_time_sync_notification_cb(引数)
sntp_sync_time_cb_t callback | 実行時にコールバックする関数 |
2つ目の[configTime()]が、NTPの設定になり、この関数を実行することでNTP機能が開始します。
日本のローカル時刻はGMTと9時間の差があるため、[9 * 3600]で9時間を設定してます。NTPサーバは最大3つまで設定することができます。server1が優先され、時刻修正できない場合はserver2,server3にトライしてくれます。
configTime(引数)
gmtOffset_sec | GMTとローカル時刻との差(単位は秒)。 |
daylightOffset_sec | 夏時間で進める時間(単位は秒)。 |
server1, server2, server3 | NTPサーバ。最低一つ設定する。 |
configTime()を実行することで、1時間に1回時刻修正を実施してくれます。
動作確認
実行すると、以下のようにシリアルポートに出力されます。

[Got time adjustment from NTP!]が表示されているので、時刻修正成功です!
その後、1秒毎に時刻が表示されています。
もし、「‘sntp_set_time_sync_notification_cb’ was not declared in this scope」と表示されてエラーとなった場合は、「#include “esp_sntp.h”」を追加してください。
ESP32C3 DevModule では、なぜか上記のエラーが発生しました。
固定IPアドレスでNTP利用時の注意点
固定IPアドレスを取得してWifi接続する方法はこちら👇
固定IPアドレスでWifi接続する場合、gatewayやdnsの設定をしておかないと外部と通信できないため、NTPも失敗してしまうので注意です。
まとめ
[configTime()]で時刻修正を依頼しておくだけで、定期的に時刻修正してくれるので、かなり手軽にできますね。常時インターネットに接続しておくような場合はかなり便利なので、おすすめです。
また、時刻を取得する方法については少し躓いたことがあるので、別記事で記載しようと思います。
コメント