目次
ESP32でネットワーク上から現在時刻を取得する(NTP)
動いている様子
ESP32で現在時刻を取得・表示。
NTPサーバー初めて使いました。正確な時間が取得できます。#ESP32 pic.twitter.com/nSwp0VrdRR— ????????????-???????????????? (@wak_tech) January 12, 2019
参考にさせていただいたサイト
実行環境
ソフトウェア関連
- 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の略語で、ネット上から現在時刻を取得できる通信プロトコルです。
簡単に
- NTPサーバーへUDPの123番ポートへ接続
- 現在時刻を取得
という手順をとります。…ポートへ接続??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
ご覧いただきありがとうございました!
電子回路 機器を自由に扱えるなんてあこがれます
うらやましいなあ
わかりやすい
esp8266 ではgetlocaltime 使えないです
目覚まし時計
作ってみるか
ソースコードをコピペしてすぐに使え、たすかりました。
char s[20]だと1バイト不足していることに気が付きました。