ESP32でネットワーク上から現在時刻を取得する(NTP)

Pocket

ESP32でネットワーク上から現在時刻を取得する(NTP)

動いている様子

参考にさせていただいたサイト

実行環境

ソフトウェア関連

  • windows10 home
  • Arduino 1.8.5
  • ESP32 core for arduino 1.0.0

使用部品

ソースコード(コピペで動く)

#include <WiFi.h>
 
const char *ssid = "YOUR SSID";
const char *password = "YOUR PASSWORD";
 
void setup() { 
  Serial.begin(115200);
  
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();

  if (WiFi.begin(ssid, password) != WL_DISCONNECTED) {
    ESP.restart();
  }
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
  }
  
  Serial.println("Connected to the WiFi network!");
  
  configTime(9 * 3600L, 0, "ntp.nict.jp", "time.google.com", "ntp.jst.mfeed.ad.jp");//NTPの設定
}

struct tm timeInfo;//時刻を格納するオブジェクト
char s[20];//文字格納用

void loop() {
  getLocalTime(&timeInfo);//tmオブジェクトのtimeInfoに現在時刻を入れ込む
  sprintf(s, " %04d/%02d/%02d %02d:%02d:%02d",
          timeInfo.tm_year + 1900, timeInfo.tm_mon + 1, timeInfo.tm_mday,
          timeInfo.tm_hour, timeInfo.tm_min, timeInfo.tm_sec);//人間が読める形式に変換
  delay(1000);
  Serial.println(s);//時間をシリアルモニタへ出力
}

解説

NTPとは

NTPとはNetwork Time Protocolの略語で、ネット上から現在時刻を取得できる通信プロトコルです。
簡単に

  1. NTPサーバーへUDPの123番ポートへ接続
  2. 現在時刻を取得

という手順をとります。…ポートへ接続??UDP??
この辺りの詳細はともかく、ArduinoのESP32ライブラリには標準で簡単にNTPを使えるものが入っています

NTPサーバ―への接続と時刻の取得

NTPサーバーへの接続・時刻の取得には以下の2つの関数を使います。

configTime(9 * 3600L, 0, "ntp.nict.jp", "time.google.com", "ntp.jst.mfeed.ad.jp");
getLocalTime(&timeInfo);

これらの関数はArduino>hardware>espressif>esp32>cores>esp32>Arduino.hの中で見つけることができました。


configTime()

ntpの設定をする関数。

引数 引数の内容
1 オフセット時間(秒) 日本の場合標準時+9h = 9×3600 sec
2 daylight offset サマータイム等の設定。日本なら必要なしなので0
3つめ以降 ntpサーバーのURL 日本ならば日本標準時グループのサーバーを第一に使うべき

これに従い、

configTime(9 * 3600L, 0, "ntp.nict.jp", "time.google.com", "ntp.jst.mfeed.ad.jp");

としました。正直3つも必要ではないので、time.google.comまででも十分かと思います。


getLocalTime()

現在の時刻を取得する関数。

引数 引数の内容
1 tmオブジェクト 時刻情報を格納しておく変数。今回はtimeInfoというオブジェクトを生成して入れ込んでいる

使い方としては

struct tm timeInfo;//tmオブジェクトのtimeInfoを用意
getLocalTime(&timeInfo);//tmオブジェクトのtimeInfoに現在時刻を入れ込む

です。これでもう時刻がtimeInfoオブジェクトに入りました。

tmオブジェクト(timeInfo)からの時刻の取り出し

tm.tm_year

で1900年から何年経ったかが取得できます。同様にして

tm.tm_mom

で月が0~11の値で取得可能。つまり実際の月に変換するには1を足す必要があります。

文字を保存しておく配列をsとすると、以下のようにして人間が読める形式に変換できます。

char s[20];
sprintf(s, " %04d/%02d/%02d %02d:%02d:%02d",
          timeInfo.tm_year + 1900, timeInfo.tm_mon + 1, timeInfo.tm_mday,
          timeInfo.tm_hour, timeInfo.tm_min, timeInfo.tm_sec);//人間が読める形式に変換

これでsに文字列が入りました。あとはこれを画面に表示するなりすることが可能です。今回はLCDなどは繋いでいなかったので、シリアルモニタに出力しました。

Serial.println(s);

まとめ

今回取得した正確な時間を使えば、ネット同期時計などが作れますね。

決まった時間に音が鳴るような目覚まし時計としてもいいかもしれません。
次はESP32でOLEDディスプレイ「SSD1306」にHello-world表示してみたと組み合わせて実際に時計を作ってみようと思います。

twitterアカウントの方で最新記事のお知らせや記事にならないような小さな情報を小出ししています。もしよろしければフォローお願いいたしますm(__)m

ご覧いただきありがとうございました!

Pocket

関連記事   ESP32のタッチセンサ3つを使って8個の状態を表してみた

3件のコメント

  1. 電子回路 機器を自由に扱えるなんてあこがれます
    うらやましいなあ

返信を残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です