NTPサーバから時刻を取得してM5Stackに表示する
はじめに
M5Stackのスケッチ例に「TFT_Clock_Digital」というものがあります。
TFT_Clock_Digital pic.twitter.com/7TpLEJwhfg
— クラクス (@kuracux) 2018年10月7日
デジタル時計のように時刻が画面上に表示され1秒ごとに変化しますが、表示される時刻はコンパイルした時刻が基準となります。
(厳密には違うと思いますが大雑把な認識としてだとお思いください。)
そのため、例えば15:47:00にコンパイルした場合、電源を入れる度に15:47:00がまず表示され、そこから1秒ごとに表示される時刻が変化します。
しかしながら、そのままでは時計としての役割を果たせないため、NTPサーバから時刻を取得して現在の時刻を表示できるものを作成しましたのでご紹介します。
完成品
画面に表示されている文字列の見た目はTFT_Clock_Digitalと同様ですが、こちらは電源ボタンを押して再度起動しても隣の時計とほぼ同じ時刻を表示してくれます。
NTPサーバーから取得した時刻をM5StackのTFT_Clock_Digitalで表示してみました pic.twitter.com/W3zUNAq9F6
— クラクス (@kuracux) 2018年10月3日
準備物
- M5Stack Gray
- 出版社/メーカー: スイッチサイエンス
- メディア: おもちゃ&ホビー
- この商品を含むブログを見る
※M5Stackであればどのシリーズ(Basic,FIRE等)でも問題ないと思います。
1.下記のスケッチを書き込む
スケッチ例にある「TFT_Clock_Digital」と「SimpleTime」の合わせ技となっております。
以下にそれぞれのスケッチ例がありますので、参考になるかと思います。
- TFT_Clock_Digital
ファイル→スケッチ例→M5Stack→Advanced→Display→TFT_Clock_Digital
- SimpleTime
ファイル→スケッチ例→ ESP32→Time→SimpleTime
#include <M5Stack.h> #include <WiFi.h> #include "time.h" const char* ssid = ""; const char* password = ""; const char* ntpServer = "ntp.jst.mfeed.ad.jp"; const long gmtOffset_sec = 9 * 3600; const int daylightOffset_sec = 0; static uint8_t conv2d(const char* p); // Forward declaration needed for IDE 1.6.x uint8_t hh = conv2d(__TIME__), mm = conv2d(__TIME__ + 3), ss = conv2d(__TIME__ + 6); // Get H, M, S from compile time byte xcolon = 0, xsecs = 0; void setup(void) { Serial.begin(115200); M5.begin(); M5.Lcd.fillScreen(TFT_BLACK); M5.Lcd.setTextSize(1); M5.Lcd.setTextColor(TFT_YELLOW, TFT_BLACK); //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 configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); struct tm timeinfo; if (!getLocalTime(&timeinfo)) { Serial.println("Failed to obtain time"); return; } //disconnect WiFi as it's no longer needed WiFi.disconnect(true); WiFi.mode(WIFI_OFF); } void loop() { struct tm timeinfo; if (!getLocalTime(&timeinfo)) { Serial.println("Failed to obtain time"); return; } hh = timeinfo.tm_hour; mm = timeinfo.tm_min; ss = timeinfo.tm_sec; // Update digital time int xpos = 0; int ypos = 85; // Top left corner ot clock text, about half way down int ysecs = ypos + 24; // Draw hours and minutes if (hh < 10) xpos += M5.Lcd.drawChar('0', xpos, ypos, 8); // Add hours leading zero for 24 hr clock xpos += M5.Lcd.drawNumber(hh, xpos, ypos, 8); // Draw hours xcolon = xpos; // Save colon coord for later to flash on/off later xpos += 29; if (mm < 10) xpos += M5.Lcd.drawChar('0', xpos, ypos, 8); // Add minutes leading zero xpos += M5.Lcd.drawNumber(mm, xpos, ypos, 8); // Draw minutes xsecs = xpos; // Sae seconds 'x' position for later display updates if (ss % 2) { // Flash the colons on/off M5.Lcd.setTextColor(0x39C4, TFT_BLACK); // Set colour to grey to dim colon M5.Lcd.drawChar(':', xcolon, ypos - 8, 8); // Hour:minute colon xpos += M5.Lcd.drawChar(':', xsecs, ysecs, 6); // Seconds colon M5.Lcd.setTextColor(TFT_YELLOW, TFT_BLACK); // Set colour back to yellow }else{ M5.Lcd.drawChar(':', xcolon, ypos - 8, 8); // Hour:minute colon xpos += M5.Lcd.drawChar(':', xsecs, ysecs, 6); // Seconds colon } //Draw seconds if (ss < 10) xpos += M5.Lcd.drawChar('0', xpos, ysecs, 6); // Add leading zero M5.Lcd.drawNumber(ss, xpos, ysecs, 6); // Draw seconds } // Function to extract numbers from compile time string static uint8_t conv2d(const char* p) { uint8_t v = 0; if ('0' <= *p && *p <= '9') v = *p - '0'; return 10 * v + *++p - '0'; }