時刻の設定
今回は時刻を設定してみましょう。
setTimeによる時刻設定
起動後に時刻を自分で選択して設定するにはsetTime関数を使います。
この関数を使うにはTimeライブラリが必要になります。
GitHub - PaulStoffregen/Time: Time library for Arduino
ここからダウンロードしてください。
時刻を設定するコード
こちらがコードです。
#include <M5Stack.h> #include <WiFi.h> #include <time.h> #include <TimeLib.h> #define SET_TIME_NUM 4 // 時刻設定可能数 #define SEL_TYPE_TIME 0 // 時刻設定 #define SEL_TYPE_OK 1 // OK #define SEL_TYPE_CANCEL 2 // CANCEL const char* ssid = "YOUR_SSID"; ←変更箇所 const char* password = "YOUR_PASS"; ←変更箇所 const char* ntpServer = "ntp.nict.jp"; // NTPサーバ const long gmtOffset_sec = 3600 * 9; const int daylightOffset_sec = 0; // 矢印表示情報構造体 typedef struct TS_TRIANGLE_POS { unsigned char ucX[3]; unsigned char ucY[3]; unsigned int uiColor; } TS_TRIANGLE_POS; // 設定時刻情報構造体 typedef struct TS_SET_TIME { unsigned char ucMin; unsigned char ucMax; unsigned char ucVal; } TS_SET_TIME; // ▲表示 const TS_TRIANGLE_POS gtsUpArrow[SET_TIME_NUM] = { {{ 55, 63, 59},{ 70, 70, 63},WHITE}, // 時 10の位 {{ 95,103, 99},{ 70, 70, 63},WHITE}, // 時 1の位 {{185,193,189},{ 70, 70, 63},WHITE}, // 分 10の位 {{225,233,229},{ 70, 70, 63},WHITE}, // 分 1の位 }; // ▼表示 const TS_TRIANGLE_POS gtsDownArrow[SET_TIME_NUM] = { {{ 55, 63, 59},{115,115,122},WHITE}, // 時 10の位 {{ 95,103, 99},{115,115,122},WHITE}, // 時 1の位 {{185,193,189},{115,115,122},WHITE}, // 分 10の位 {{225,233,229},{115,115,122},WHITE}, // 分 1の位 }; // 設定時刻 TS_SET_TIME gtsSetTime[SET_TIME_NUM] = { { 0, 2, 0 }, // 時 10の位 { 0, 9, 0 }, // 時 1の位 { 0, 5, 0 }, // 分 10の位 { 0, 9, 0 }, // 分 1の位 }; unsigned char gucGetTime = 0; unsigned char gucSelNumIdx = 0; unsigned char gucSelType = SEL_TYPE_TIME; struct tm timeinfo; void setup() { // m5stack初期化 M5.begin(); //connect to WiFi M5.Lcd.print("Connecting to YOUR_SSID "); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); M5.Lcd.print("."); } M5.Lcd.println(" CONNECTED"); //init and get the time configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); // 設定した時刻を取得 if(!getLocalTime(&timeinfo)){ M5.Lcd.println("Failed to obtain time"); return; } // 時刻の設定 setTime(timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec, timeinfo.tm_mday, timeinfo.tm_mon, timeinfo.tm_year + 1900); //disconnect WiFi as it's no longer needed WiFi.disconnect(true); WiFi.mode(WIFI_OFF); // BLACK Screen M5.Lcd.fillScreen(BLACK); // 横線 M5.Lcd.drawFastHLine(0, 220, 320, WHITE); // 縦線 M5.Lcd.drawFastVLine(106, 220, 20, WHITE); M5.Lcd.drawFastVLine(219, 220, 20, WHITE); // 矢印 M5.Lcd.fillTriangle( 49, 232, 53, 224, 57, 232,WHITE ); M5.Lcd.fillTriangle( 159, 224, 163, 232, 167, 224,WHITE ); M5.Lcd.fillTriangle( 269, 224, 277, 228, 269, 232,WHITE ); // テキストサイズ指定 M5.Lcd.setTextSize(2); // OK M5.Lcd.setCursor(120, 160); M5.Lcd.print("OK"); // Cancel M5.Lcd.setCursor(120, 180); M5.Lcd.print("CANCEL"); } void loop() { unsigned char aucSetHour = 0; unsigned char aucSetMin = 0; delay(100); // delay(1); M5.update(); // Aボタン if (M5.BtnA.wasPressed()) { // 時刻設定中 if( SEL_TYPE_TIME == gucSelType ) { // 数値を更新 if( gtsSetTime[gucSelNumIdx].ucVal < gtsSetTime[gucSelNumIdx].ucMax ) { gtsSetTime[gucSelNumIdx].ucVal++; } } else { gucSelType = SEL_TYPE_OK; } } // Bボタン if (M5.BtnB.wasPressed()) { // 時刻設定中 if( SEL_TYPE_TIME == gucSelType ) { // 数値を更新 if( gtsSetTime[gucSelNumIdx].ucVal > gtsSetTime[gucSelNumIdx].ucMin ) { gtsSetTime[gucSelNumIdx].ucVal--; } } else { gucSelType = SEL_TYPE_CANCEL; } } // Cボタン if (M5.BtnC.wasPressed()) { // ▲表示を消す M5.Lcd.fillTriangle( gtsUpArrow[gucSelNumIdx].ucX[0], gtsUpArrow[gucSelNumIdx].ucY[0], gtsUpArrow[gucSelNumIdx].ucX[1], gtsUpArrow[gucSelNumIdx].ucY[1], gtsUpArrow[gucSelNumIdx].ucX[2], gtsUpArrow[gucSelNumIdx].ucY[2], BLACK ); // ▼表示を消す M5.Lcd.fillTriangle( gtsDownArrow[gucSelNumIdx].ucX[0], gtsDownArrow[gucSelNumIdx].ucY[0], gtsDownArrow[gucSelNumIdx].ucX[1], gtsDownArrow[gucSelNumIdx].ucY[1], gtsDownArrow[gucSelNumIdx].ucX[2], gtsDownArrow[gucSelNumIdx].ucY[2], BLACK ); // 選択数値更新 if( gucSelNumIdx < (SET_TIME_NUM - 1)) { gucSelNumIdx++; } else { // 時刻設定中 if( SEL_TYPE_TIME == gucSelType ) { M5.Lcd.fillTriangle( 269, 224, 277, 228, 269, 232,BLACK ); // テキストサイズ指定 M5.Lcd.setTextSize(1); // ENTER M5.Lcd.setCursor(250, 224); M5.Lcd.print("ENTER"); gucSelType = SEL_TYPE_OK; } else { // ENTERを黒く塗りつぶし M5.Lcd.fillRect(220, 221, 200, 19, BLACK); // OK if( SEL_TYPE_OK == gucSelType ) { aucSetHour = (gtsSetTime[0].ucVal * 10 + gtsSetTime[1].ucVal); aucSetMin = (gtsSetTime[2].ucVal * 10 + gtsSetTime[3].ucVal); // 時刻の設定 setTime( aucSetHour, aucSetMin, 0 , day(), month(), year() ); } gucSelType = SEL_TYPE_TIME; gucSelNumIdx = 0; // ▶表示 M5.Lcd.fillTriangle( 269, 224, 277, 228, 269, 232,WHITE ); } } } // 時刻設定中 if( SEL_TYPE_TIME == gucSelType ) { // ▲表示 M5.Lcd.fillTriangle( gtsUpArrow[gucSelNumIdx].ucX[0], gtsUpArrow[gucSelNumIdx].ucY[0], gtsUpArrow[gucSelNumIdx].ucX[1], gtsUpArrow[gucSelNumIdx].ucY[1], gtsUpArrow[gucSelNumIdx].ucX[2], gtsUpArrow[gucSelNumIdx].ucY[2], gtsUpArrow[gucSelNumIdx].uiColor ); // ▼表示 M5.Lcd.fillTriangle( gtsDownArrow[gucSelNumIdx].ucX[0], gtsDownArrow[gucSelNumIdx].ucY[0], gtsDownArrow[gucSelNumIdx].ucX[1], gtsDownArrow[gucSelNumIdx].ucY[1], gtsDownArrow[gucSelNumIdx].ucX[2], gtsDownArrow[gucSelNumIdx].ucY[2], gtsDownArrow[gucSelNumIdx].uiColor ); } // OK選択中 if( SEL_TYPE_OK == gucSelType ) { M5.Lcd.fillTriangle( 100, 164, 108, 168, 100, 172,WHITE ); M5.Lcd.fillTriangle( 100, 184, 108, 188, 100, 192,BLACK ); } // Cancel選択中 if( SEL_TYPE_CANCEL == gucSelType ) { M5.Lcd.fillTriangle( 100, 164, 108, 168, 100, 172,BLACK ); M5.Lcd.fillTriangle( 100, 184, 108, 188, 100, 192,WHITE ); } // 時刻設定中 if( SEL_TYPE_TIME == gucSelType ) { M5.Lcd.fillTriangle( 100, 164, 108, 168, 100, 172,BLACK ); M5.Lcd.fillTriangle( 100, 184, 108, 188, 100, 192,BLACK ); } // 時刻表示の更新 printLocalTime(); // 設定時刻表示の更新 setLocalTime(); } void printLocalTime() { // テキストサイズ指定 M5.Lcd.setTextSize(2); // カーソル位置を設定 M5.Lcd.setCursor(50,0); M5.Lcd.printf("%04d-%02d-%02d %02d:%02d:%02d" ,year() ,month() ,day() ,hour() ,minute() ,second() ); // 起動時の時刻を保存 if( 0 == gucGetTime ) { gucGetTime = 0xff; // 時 10の位 gtsSetTime[0].ucVal = (hour() / 10); // 時 1の位 gtsSetTime[1].ucVal = (hour() % 10); // 分 10の位 gtsSetTime[2].ucVal = (minute() / 10); // 分 1の位 gtsSetTime[3].ucVal = (minute() % 10); } } void setLocalTime() { // テキストサイズ指定 M5.Lcd.setTextSize(4); // 時 10の位 M5.Lcd.drawNumber(gtsSetTime[0].ucVal, 50, 80); // 時 1の位 M5.Lcd.drawNumber(gtsSetTime[1].ucVal, 90, 80); M5.Lcd.setCursor(130, 80); M5.Lcd.print("h"); // 分 10の位 M5.Lcd.drawNumber(gtsSetTime[2].ucVal, 180, 80); // 分 1の位 M5.Lcd.drawNumber(gtsSetTime[3].ucVal, 220, 80); M5.Lcd.setCursor(260, 80); M5.Lcd.print("m"); }
ちゃんと時刻が変更されました。
起動時はntpサーバから時刻を取ってきて、あとで自分でも変更できるようにした。#m5stack pic.twitter.com/ZQ4MSLlIW7
— yamanonono (@yamano_no_no) September 23, 2019