ArduinoにRTCつけているけど時刻がすこしずつずれてくるので
rtc.adjust(DateTime(2021,3,1,11,00,00))なんて書いてコンパイルして書き込んで使ってたけど
まあ大体でいいけどと思いながらも、当然ながら10~20秒程度はどうしてもずれるし、だんだんRTCの時刻はずれてくる。となるとたびたび時刻合わせないといけなくなる。
と言うことでESP32開発ボードではNTPでの標準時刻取得できるので、せっかくならその時刻をRTCに書き込もうとプログラム追記。
最初は今までのスケッチに加える形で追加して書いてたら、いじってるうちに急にコンパイルエラーでどこまで戻してもうまくいかないようなと言うか、妙なコンパイルエラーが出たり、どこでバグってるかわからないトホホ状態になってしまいました。
そんな時は、最初からってことで最初から、WifiとRTCだけにして。
やっとうまくいきました。
setupでwifiにつないで、NTP時刻取得出来たら、その時刻をRTCに書込み、loopで1秒おきに表示ってことで作りました。
これで書き込んだRTCを取り外してArduino側にくっつければArduino側の時刻もあってるってことで。
RTCはamazonで買った3足千円のDS3231のやつです。
ちなみに最初にバグった原因はたぶんここです
char rsDTime[20]
yyyy/mm/dd hh:mi:ss
ここのサイズギリギリで19byteにしてました。1byte足りなかったようで、20byteにしないとコンパイルはできても暴走でリブートの繰り返しになってしまいます。C言語初心者のよくハマるところのようで。
スケッチはこんな感じです
/*
* NTP_TimeSet2RTC
WiFi接続テスト最初から再確認
20210320 URK
*///SSID3つどれかつながりますように
#define WID1 "ssid1"
#define WID2 "ssid2"
#define WID3 "携帯テザリングssid3"
#define WPass "password"
#include <Wire.h> //I2C接続用
#include <RTClib.h>
RTC_DS3231 rtc;
// WiFi Setting
#include <WiFi.h>
#include <time.h>
#define JST 3600*9
/***********************
初期設定
***********************/
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println("-------------");
//RTC
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
// Wifi接続トライ
int WiFiCon = WifiConnect(WID1, WPass);
Serial.println("WiFiCon:" + String(WiFiCon) + " WiFi.status:" + String(WiFi.status()) + " WiFi.IP:" + ipToString(WiFi.localIP()));
if (WiFiCon < 1) {
WiFiCon = WifiConnect(WID2, WPass);
Serial.println("WiFiCon:" + String(WiFiCon) + " WiFi.status:" + String(WiFi.status()) + " WiFi.IP:" + ipToString(WiFi.localIP()));
}
if (WiFiCon < 1) {
WiFiCon = WifiConnect(WID3, WPass);
Serial.println("WiFiCon:" + String(WiFiCon) + " WiFi.status:" + String(WiFi.status()) + " WiFi.IP:" + ipToString(WiFi.localIP()));
}
if (WiFiCon < 1) { //WifiだめだったらRTCから時刻取得
Serial.println("Wifiつながらないので RTCから時刻読込");
} else { //OKだったら NTCから時刻取得して RTCに時刻設定
Serial.println("Wifi NTPから時刻読込");
configTzTime("JST-9", "ntp.nict.jp", "ntp.jst.mfeed.ad.jp"); // 2.7.0以降, esp32コンパチ
delay(500);
struct tm *tm;
time_t t;
t = time(NULL);
tm = localtime(&t);
Serial.println(tm);
Serial.println("RTCへ時刻設定");
rtc.adjust(DateTime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec)); //日付と時刻の書き込み
}
}
/************************************
* Main 毎秒時刻表示
*************************************/
void loop() {
char rsDTime[20]; //yyyy/mm/dd_hh:mm:ss で19byte+1必要
DateTime RTCnow = rtc.now();
sprintf(rsDTime, "%02d/%02d/%02d %02d:%02d:%02d", RTCnow.year(), RTCnow.month(), RTCnow.day(), RTCnow.hour(), RTCnow.minute(), RTCnow.second());
Serial.println(rsDTime);
delay(1000);
}
/*********************************************
Wifi 10回トライ ダメだったら0を返す
*********************************************/
int WifiConnect(char *WID, char *Wpass) {
int WIFIid = 0;
WiFi.begin(WID, Wpass);
for (int i = 0; i <= 10; i++) {
if (WiFi.status() == WL_CONNECTED) {
Serial.println("Wifi Connect:" + String(WID));
return 1;
}
Serial.print(".");
delay(500);
}
Serial.println("Wifi Can’t:" + String(WID));
return 0;
}
String ipToString(uint32_t ip) {
String result = "";
result += String((ip & 0xFF), 10);
result += ".";
result += String((ip & 0xFF00) >> 8, 10);
result += ".";
result += String((ip & 0xFF0000) >> 16, 10);
result += ".";
result += String((ip & 0xFF000000) >> 24, 10);
return result;
}













