M5Stack CORE2でネットから現在時刻を取得

M5Stack NTPサーバー

M5Stack CORE2でWiFi接続によりインターネットでNTPサーバーから現在時刻を取得してLCD画面に年月日時刻を表示します。

目次

NTPサーバーからの時刻取得

ネットに接続された機器の時刻を合わせるためにNTPサーバーというものがあります。NTP(Network Time Protocol)サーバーは国内にもいくつかあるようですが代表的なものとして情報通信研究機構(NICT)の公開NTPサーバー「ntp.nict.jp」があります。

NTPは1900年1月1日0時0分0秒(UTC)からの経過秒数を表しています。よって現在時刻の「年」を表示するときには受信したデータに1900を足す必要があります。また、UTCとは協定世界時のことで日本標準時(JST)を表示するにはUTCから9時間進めた時間(UTC+9)にする必要があります。

WiFiによるインターネット接続

インターネットに接続されているWiFiに接続します。WiFi設定は、WiFi.mode()にて子機(WIFI_STA)設定、WiFi.begin()でSSIDとパスワードを設定します。WiFi接続は、WiFi.status()を実行します。このプログラムでは500ms毎に接続を試みて接続成功が返ってきたらループを抜けるようにしています。

NTPサーバーから時刻取得するプログラム

ArduinoIDEのサンプルスケッチTime.inoを参考に作成しました。NTPサーバーの設定はsetup()の中で実行しています。

時刻取得設定はconfigTime()で行います。各引数ですが、「gmtOffset_sec」はタイムゾーンによる時差設定で、UTCからJSTの時差は9時間であり、9行目の変数設定で3600*9秒となります。 「daylightOffset_sec」はサマータイムの時差設定ですが日本はサマータイムが無いため0秒を設定しています。 「ntpServer」はNTPサーバーのアドレスでNICTのNTP公開サーバーである”ntp.nict.jp”を設定しました。

時刻の取得とLCD表示はサブルーチンprintLocalTime()にしており、loop()から1秒毎に呼び出しています。getLocalTime(&timeinfo)で時間取得すると構造体tmのtimeinfoに値が入ります。timeinfo.tm_yearは1900年が起点の値なので1900を加算します。timeinfo.tm_monは1月は0なので1を加算します。

#include <M5Unified.h>
#include <WiFi.h>

const char* ssid = "**************";    //WiFi SSID
const char* password = "*************"; //WiFi password

const char* ntpServer = "ntp.nict.jp";  //NTPサーバーNICT
const long gmtOffset_sec = 3600 * 9;    //日本のタイムゾーンはGMT+9:00
const int daylightOffset_sec = 0;       //日本はサマータイムなし

void printLocalTime() {
    struct tm timeinfo; //NTPサーバーからの時間情報の構造体

    if (!getLocalTime(&timeinfo)) { //NTPサーバーから時間取得
        M5.Display.println("Failed to obtain time");
        return;
    }
    
    M5.Display.printf("DATE: %04d/%02d/%02d\n", 
        timeinfo.tm_year +1900, //1900年が起点の値 
        timeinfo.tm_mon + 1, //0が1月
        timeinfo.tm_mday);
    
    M5.Display.printf("TIME: %02d:%02d:%02d\n", 
        timeinfo.tm_hour, 
        timeinfo.tm_min, 
        timeinfo.tm_sec);
}

void setup() {   
    auto cfg = M5.config();
    M5.begin(cfg);
    
    M5.Display.setTextSize(2);
    M5.Display.print("--- WiFi NTP server---\n\n");
    M5.Display.print("Connecting");

    WiFi.mode(WIFI_STA);    //子機接続設定
    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) { //WiFi接続
        delay(500);
        M5.Display.print(".");
    }

    M5.Display.println("\n\nWiFi connected!");
    configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);//NTPサーバー設定
}

void loop() {
    M5.Display.setCursor(0, 120);
    M5.Display.setTextSize(3);

    printLocalTime();
    delay(1000);
}
Code language: C++ (cpp)

時刻取得の実行結果

WiFi接続されるとNTPサーバーから現在時刻を取得しLCD表示します。1秒毎に時刻が更新されます。

まとめ

ArduinoライブラリでNTPサーバーの設定関数、現在時刻取得関数、と取得データの構造体が準備されており、これらを使うだけで簡単に時刻表示することができます。NTPサーバーのアドレス設定、タイムゾーンの時差設定をします。注意点は時刻取得値は年は1900年起点であること、月は1月は0であることです。

今回はWiFi通信で毎秒時刻を読み取ってきましたが、M5Stack CORE2に内蔵されているRTC(リアルタイムクロック)を使えば1日1回くらいの時刻合わせでもズレの小さい時計ができるかと思います。今後試してみたいと思います。

目次