M5 CoreInk RTCのコト+NTPから時刻ゲット
↑の続きと言えば続きなのですが、今回はちょっと温度計はお休みにして、RTC(リアルタイムクロック)方面のお勉強です。
まずサンプル。
サンプルスケッチ
これまた階層が深いのですが、
スケッチ例ー>M5-CoreInk->RTC_BM8653 とひらいてみます。
さくっと実行。
これまたシンプルな画面さんですね。
あれ? 時間おかしくない??
日付も変だし・・・(今日は12月21日)
実はこれ、開始時間はプログラム・ソース内で決め打ちになっているのです。
ソースを見てみましょう。
#include "M5CoreInk.h"
Ink_Sprite InkPageSprite(&M5.M5Ink);
RTC_TimeTypeDef RTCtime;
RTC_DateTypeDef RTCDate;
char timeStrbuff[64];
void flushTime(){
M5.rtc.GetTime(&RTCtime);
M5.rtc.GetData(&RTCDate);
sprintf(timeStrbuff,"%d/%02d/%02d %02d:%02d:%02d",
RTCDate.Year,RTCDate.Month,RTCDate.Date,
RTCtime.Hours,RTCtime.Minutes,RTCtime.Seconds);
InkPageSprite.drawString(10,100,timeStrbuff);
InkPageSprite.pushSprite();
}
void setupTime(){
RTCtime.Hours = 23;
RTCtime.Minutes = 33;
RTCtime.Seconds = 33;
M5.rtc.SetTime(&RTCtime);
RTCDate.Year = 2020;
RTCDate.Month = 11;
RTCDate.Date = 6;
M5.rtc.SetData(&RTCDate);
}
void setup() {
M5.begin();
if( !M5.M5Ink.isInit())
{
Serial.printf("Ink Init faild");
while (1) delay(100);
}
M5.M5Ink.clear();
delay(1000);
//creat ink refresh Sprite
if( InkPageSprite.creatSprite(0,0,200,200,true) != 0 )
{
Serial.printf("Ink Sprite creat faild");
}
setupTime();
}
void loop() {
flushTime();
delay(15000);
}
ほらこんなかんじ。
void setupTime() の中で、RTCtime とか、 RTCDate とかのメンバに
2020年11月6日23時33分33秒という決まった値を突っ込んでいます。
その後、15秒おきに flushTime() が呼ばれて、そこの中で(2020/11/6 23:33:33から)加算された日時を取得して画面にプロットしている……。ダケ。のようです><
なーんだーー。リアルタイムクロックとかいうから、ちゃんと普通の時計みたいに正確な時間がわかるのかとおもったら、最初に現実の時間を教えないといけないようです(あたりまえ。そういえば普通の時計だってそうですわね)
NTPから現実時刻取得
しゃあないので、ネットでNTP(Network Time Protocol(ネットワーク・タイム・プロトコル、NTP))さんを使って現実の時刻をとってきましょう。
WiFiに接続できるようにして、NTPサーバから時刻の取得は configTime 関数を使います。
configTime 関数の使い方は
↑らへんを参考にします。
と、がりがりプログラミングしている間に(?)
↑まさにM5 CoreInk用のNTP Clockなんていうところを発見してしまいましたw
そのまま真似したいところだけれどぐっとこらえて(?)ところどころ参考にしつつ、自前でつくりなおしたのがこちら!
プログラムソース
// MoStack CoreInk用、 NTPサーバから日時を取得、RTCを使って15秒ごとに時刻を表示
#include "M5CoreInk.h"
#include <WiFi.h>
#include <time.h>
const String SSID = ""; // ← WiFiのSSIDを入れる
const String WF_KEY = "";// ← WiFiのパスキーを入れる
static const char *wd[7] = {"Sun","Mon","Tue","Wed","Thr","Fri","Sat"};
#define JST 3600*9
tm timeinfo;
time_t now;
Ink_Sprite InkPageSprite(&M5.M5Ink);
RTC_TimeTypeDef RTCtime;
RTC_DateTypeDef RTCDate;
char timeStrbuff[64];
void flushTime(){
M5.rtc.GetTime(&RTCtime);
M5.rtc.GetData(&RTCDate);
sprintf(timeStrbuff,"%d/%02d/%02d %02d:%02d:%02d",
RTCDate.Year,RTCDate.Month,RTCDate.Date,
RTCtime.Hours,RTCtime.Minutes,RTCtime.Seconds);
InkPageSprite.drawString(10,100,timeStrbuff);
InkPageSprite.pushSprite();
showTime(timeinfo);
}
void setupTime(){
RTCtime.Minutes = timeinfo.tm_min;
RTCtime.Seconds = timeinfo.tm_sec;
RTCtime.Hours = timeinfo.tm_hour;
RTCDate.Year = timeinfo.tm_year+1900;
RTCDate.Month = timeinfo.tm_mon+1;
RTCDate.Date = timeinfo.tm_mday;
RTCDate.WeekDay = timeinfo.tm_wday;
M5.rtc.SetTime(&RTCtime);
M5.rtc.SetData(&RTCDate);
char timeStrbuff[64];
sprintf(timeStrbuff, "%d/%02d/%02d %02d:%02d:%02d",
RTCDate.Year, RTCDate.Month, RTCDate.Date,
RTCtime.Hours, RTCtime.Minutes, RTCtime.Seconds);
Serial.println("[NTP] in: " + String(timeStrbuff));
}
void setup_wifi(){
// Connect to an access point
if(SSID.length() == 0 ){
// SSIDの設定を最初にしていなかったら、
WiFi.begin(); // Connect to the access point of the last connection
} else {
// SSIDに何か文字列が入っていたら
Serial.print("Connect to :");
Serial.println( SSID );
char SSIDbuff[64];
char KeyBuff[64];
sprintf(SSIDbuff,"%s",SSID);
sprintf(KeyBuff,"%s",WF_KEY);
WiFi.begin(SSIDbuff, KeyBuff); // Or, Connect to the specified access point
}
//
Serial.print("Connecting to Wi-Fi ");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" CONNECTED");
}
void showTime(tm localTime) {
//Serial.print("[NTP] ");
Serial.print(localTime.tm_mday);
Serial.print('/');
Serial.print(localTime.tm_mon + 1);
Serial.print('/');
Serial.print(localTime.tm_year - 100);
Serial.print('(');
Serial.print(wd[localTime.tm_wday]);
Serial.print(")-");
Serial.print(localTime.tm_hour);
Serial.print(':');
Serial.print(localTime.tm_min);
Serial.print(':');
Serial.println(localTime.tm_sec);
}
bool getNTPtime(int sec) {
{
Serial.print("[NTP] sync.");
uint32_t start = millis();
do {
time(&now);
localtime_r(&now, &timeinfo);
Serial.print(".");
delay(10);
} while (((millis() - start) <= (1000 * sec)) && (timeinfo.tm_year < (2016 - 1900)));
if (timeinfo.tm_year <= (2016 - 1900)) return false; // the NTP call was not successful
Serial.print("now ");
Serial.println(now);
//saveRtcData();
setupTime();
char time_output[30];
strftime(time_output, 30, "%a %d-%m-%y %T", localtime(&now));
Serial.print("[NTP] ");
Serial.println(time_output);
}
return true;
}
void setup() {
M5.begin();
Serial.begin(115200);
delay(50);
setup_wifi();
// Set ntp time to local
//configTime(9 * 3600, 0, ntpServer);
configTime( JST, 0, "ntp.nict.jp", "ntp.jst.mfeed.ad.jp");
if (getNTPtime(10)) { // wait up to 10sec to sync
} else {
Serial.println("[NTP] Time not set");
ESP.restart();
}
showTime(timeinfo);
M5.Speaker.tone(2700,200);
delay(100);
M5.Speaker.mute();
if( !M5.M5Ink.isInit())
{
Serial.printf("Ink Init faild");
while (1) delay(100);
}
M5.M5Ink.clear();
delay(1000);
//creat ink refresh Sprite
if( InkPageSprite.creatSprite(0,0,200,200,true) != 0 )
{
Serial.printf("Ink Sprite creat faild");
}
setupTime();
}
void loop() {
flushTime();
delay(15000);
}
GitHubにも入れておきました
プログラム冒頭の
const String SSID = ""; // ← WiFiのSSIDを入れる
const String WF_KEY = "";// ← WiFiのパスキーを入れる
↑のところにWiFiのSSIDとキーを入れておくと、起動時にNTPサーバへ接続して日時を取ってくるかんじです。
実行すると、ピッて音が鳴ってNTPから時刻を取得してきて、
こんな感じになるはずです。え? かわってないじゃんって?w
シンプル過ぎてわかりにくいですがw
ちゃんと日時が「現在」になってますよーぉー。
シリアルモニタも
このように、現在の日時になっていることが分かります。
実は、参考にした NTP Clock そのままでも別に良いのですけど、あちらは見た目の表示部分が妙に凝っていて、ソースファイルもいくつかに分割されてしまっていて理解しにくいところがあるので、あえて今回はNTP+RTCのみでシンプル表示なプログラムにしてみました☆
綺麗化(これがまたCoreInkだとけっこう面倒くさい><)はまた次回にまわしまーす☆
よろしければサポートお願いします!いただいたサポートはクリエイターとしての活動費にさせていただきます!感謝!,,Ծ‸Ծ,,