/*
* 週間天気予報を表示する
* 毎日決まった時間に表示を更新、消去
*
* ESP.reset()/ESP.resart()ではRTC User
Memoryがクリアされない。
* この性質を利用して時刻設定を行う。
* 初回起動時のみNTPに時刻問い合わせ。
* RTC User Memoryに現在日時を設定し強制Reset。
* 復帰時にRTC User Memoryから時刻を取り出して設定。
*
* int ON[] = {7, 0}; // 表示更新時刻
* int OFF[] = {23, 35}; // 表示消去時刻
*
*/
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <Adafruit_GFX.h> //
https://github.com/adafruit/Adafruit-GFX-Library
#include
<Fontx.h>
// https://github.com/h-nari/Fontx
#include <Humblesoft_GFX.h>
// https://github.com/h-nari/Humblesoft_GFX
#include <Humblesoft_ILI9341.h> //
https://github.com/h-nari/Humblesoft_ILI9341
#include <WiFiUdp.h>
#include <TimeLib.h> //
https://github.com/PaulStoffregen/Time
#include <time.h>
#define TAGMAX 10
#define LENMAX 128
#define LAYOUT 1 // 横書き 小さい文字 7日分
//#define LAYOUT 2 // 横書き 大きい文字 2日分
//#define LAYOUT 3 // 縦書き 小さい文字 7日分
//#define LAYOUT 4 // 縦書き 大きい文字 3日分
IMPORT_BIN("/fontx/ILGH16XB.FNT", ILH16XB);
//16ドット半角ゴシックフォント
IMPORT_BIN("/fontx/ILGZ16XB.FNT", ILZ16XB);
//16ドット全角ゴシックフォント
//IMPORT_BIN("/fontx/ILMH16XB.FNT", ILH16XB);
//16ドット半角明朝フォント
//IMPORT_BIN("/fontx/ILMZ16XB.FNT", ILZ16XB);
//16ドット全角明朝フォント
extern const uint8_t ILH16XB[], ILZ16XB[];
Humblesoft_ILI9341 tft = Humblesoft_ILI9341();
RomFontx fontx(ILH16XB,ILZ16XB);
const char* ssid = "Your SSID";
const char* password = "Your Password";
HTTPClient http;
//RTC memory(512Byte)の定義
struct {
uint32_t crc32; // CRC(4 Byte)
uint8_t data[472]; // User Data(512-4-36)
struct tm compile; // Compile Date & time(36
Byte)
} rtcData;
// UDPローカルポート番号
unsigned int localPort = 2390;
// NTPタイムサーバIPアドレス(ntp.nict.jp NTP server)
IPAddress timeServer(133, 243, 238, 164);
// NTPパケットバッファサイズ
const int NTP_PACKET_SIZE= 48;
// NTP送受信用パケットバッファ
byte packetBuffer[NTP_PACKET_SIZE];
// 最後に時刻を確認した時間(ミリ秒)
unsigned long lastCheckTime = 0;
// コンパイルした日時
struct tm ctm;
// Udpクラス
WiFiUDP udp;
struct TAG {
uint8_t StartName;
uint8_t StartValue;
uint8_t TagPos;
unsigned char TagName[LENMAX];
unsigned char TagCurrent[LENMAX];
uint8_t ValueCount;
unsigned char TagValue[TAGMAX][LENMAX];
};
struct TAG description;
struct TAG title;
int ON[] = {7, 0}; // 表示更新時刻
int OFF[] = {23, 35}; // 表示消去時刻
void httpPrint(int len, uint8_t *buff) {
char ch[2];
ch[1] = 0;
for(int i=0; i<len; i++) {
ch[0] = buff[i];
if (isAlphaNumeric(ch[0])) {
Serial.printf("%c",ch[0]);
} else if
(strstr("\"!#$%&'()=-<> ;:/,.@[]+*",ch)) {
Serial.printf("%c",ch[0]);
} else if (ch[0] == 0x0a) {
Serial.printf("\n");
} else {
//
Serial.printf("0x%02x",ch[0]);
Serial.printf("*");
}
}
}
void initTag(struct TAG* hoge,char* name) {
hoge->StartName=0;
hoge->StartValue=0;
hoge->TagPos=0;
strcpy((char *)hoge->TagName,name);
memset(hoge->TagCurrent,0,sizeof(hoge->TagCurrent));
hoge->ValueCount=0;
memset(hoge->TagValue,0,sizeof(hoge->TagValue));
}
void addTagCurrent(struct TAG* hoge, char ch) {
int pos;
pos=hoge->TagPos;
if (pos == LENMAX-1) return;
hoge->TagCurrent[pos]=ch;
hoge->TagCurrent[++pos]=0;
(hoge->TagPos)++;
}
void startTag(struct TAG* hoge) {
hoge->StartName=1;
hoge->TagPos=0;
if (hoge->StartValue) {
hoge->StartValue=0;
(hoge->ValueCount)++;
}
}
void endTag(struct TAG* hoge) {
hoge->StartName=0;
hoge->TagPos=0;
if (strcmp ((char *)hoge->TagName, (char
*)hoge->TagCurrent) == 0) {
if (hoge->ValueCount ==
TAGMAX) return;
hoge->StartValue=1;
}
}
void addTagValue(struct TAG* hoge, char ch) {
int pos;
int count;
pos=hoge->TagPos;
count=hoge->ValueCount;
if (pos == LENMAX-1) return;
hoge->TagValue[count][pos]=ch;
hoge->TagValue[count][++pos]=0;
(hoge->TagPos)++;
}
void dumpTag(struct TAG hoge) {
int i;
Serial.printf("\nTagName=%s\n",hoge.TagName);
Serial.printf("TagCurrent=%s\n",hoge.TagCurrent);
Serial.printf("ValueCount=%d\n",hoge.ValueCount);
for(i=0;i<hoge.ValueCount;i++){
Serial.printf("TagValue[%d]=%s\n",i,hoge.TagValue[i]);
}
}
void httpParse(int len, uint8_t *buff, struct TAG *hoge) {
int i;
char ch;
for(i=0;i<len;i++) {
ch=buff[i];
if (ch == '<') {
startTag(hoge);
} else if (ch == '>') {
endTag(hoge);
} else {
if
(hoge->StartName) addTagCurrent(hoge,ch);
if
(hoge->StartValue) addTagValue(hoge,ch);
}
}
}
/*
* 指定した漢字で文字列を分解する
*/
void splitUTF8(char *in, char* utf8, char* out1, char*
out2) {
int pos=0;
int len=strlen(in);
char wk[4]={0};
// Serial.printf("len=%d\n",len);
out1[pos]=0;
out2[0]=0;
for(int i=0;i<len;) {
//
Serial.printf("%d>%02x\n",i,in[i]);
if (in[i] < 0x80) {
out1[pos++]=in[i];
out1[pos]=0;
i++;
} else {
wk[0]=in[i];
wk[1]=in[i+1];
wk[2]=in[i+2];
//
Serial.printf("wk=%02x%02x%02x utf8=%02x%02x%02x\n",
//
wk[0],wk[1],wk[2],utf8[0],utf8[1],utf8[2]);
if (strcmp(wk,utf8) == 0) {
//
Serial.printf("len-i=%d\n",len-i);
memcpy(out2,&in[i],len-i);
out2[len-i]=0;
return;
} else {
out1[pos++]=wk[0];
out1[pos++]=wk[1];
out1[pos++]=wk[2];
out1[pos]=0;
}
// delay(10);
i=i+3;
}
}
}
/*
* 指定した漢字を削除する
*/
void removeUTF8(char *in, char* utf8, char* out1) {
int pos=0;
int len=strlen(in);
char wk[4]={0};
// Serial.printf("len=%d\n",len);
out1[0]=0;
for(int i=0;i<len;) {
//
Serial.printf("%d>%02x\n",i,in[i]);
if (in[i] < 0x80) {
out1[pos++]=in[i];
out1[pos]=0;
i++;
} else {
wk[0]=in[i];
wk[1]=in[i+1];
wk[2]=in[i+2];
//
Serial.printf("wk=%02x%02x%02x utf8=%02x%02x%02x\n",
//
wk[0],wk[1],wk[2],utf8[0],utf8[1],utf8[2]);
if (strcmp(wk,utf8) != 0) {
out1[pos++]=wk[0];
out1[pos++]=wk[1];
out1[pos++]=wk[2];
out1[pos]=0;
}
// delay(10);
i=i+3;
}
}
}
/*
* 指定した文字で文字列を分解する
*/
void splitASCII(char *in, char ascii, char* out1, char*
out2) {
int pos=0;
int len=strlen(in);
// Serial.printf("len=%d\n",len);
out1[pos]=0;
out2[0]=0;
for(int i=0;i<len;) {
// Serial.printf("%d>%02x
%02x\n",i,in[i],ascii);
if (in[i] < 0x80) {
if (in[i] == ascii) {
memcpy(out2,&in[i],len-i);
out2[len-i]=0;
return;
}
out1[pos++]=in[i];
out1[pos]=0;
i++;
} else {
out1[pos++]=in[i];
out1[pos++]=in[i+1];
out1[pos++]=in[i+2];
out1[pos]=0;
i=i+3;
}
}
}
void displayHTML(int layout) {
int httpCode;
initTag(&description,"description");
initTag(&title,"title");
Serial.printf("[HTTP]begin..\n");
http.begin("weather.livedoor.com", 80,
"/forecast/rss/area/230010.xml");
httpCode = http.GET();
if(httpCode > 0){
Serial.printf("[HTTP] GET ... code:
%d\n",httpCode);
if(httpCode == HTTP_CODE_OK) {
Serial.printf("[HTTP]
OK\n");
int len = http.getSize();
uint8_t buff[128] = {0};
WiFiClient *stream =
http.getStreamPtr();
while(http.connected()
&& (len > 0 || len == -1)){
size_t size =
stream->available();
if(size){
if(size > sizeof buff) size = sizeof buff;
int
c = stream->readBytes(buff,size);
//
httpPrint(c,buff);
httpParse(c,buff,&description);
httpParse(c,buff,&title);
}
delay(1);
}
Serial.printf("[HTTP]
Disconnected\n");
// dumpTag(description);
// dumpTag(title);
char address1[32];
char address2[32];
char tdate[32];
char weater[32];
char temp[64];
char temph[32];
char templ[32];
char in[LENMAX];
char out[LENMAX];
tft.setCursor(0, 0);
tft.setFont(&fontx);
tft.fillScreen("BLACK");
int loopMax;
//#if defined(LAYOUT) && LAYOUT == 1
if (layout == 1) {
tft.setTextSize(1);
tft.setRotation(3);
loopMax=description.ValueCount;
}
//#endif
//#if defined(LAYOUT) && LAYOUT == 2
if (layout == 2) {
tft.setTextSize(2);
tft.setRotation(3);
loopMax=4;
}
//#endif
//#if defined(LAYOUT) && LAYOUT == 3
if (layout == 3) {
tft.setTextSize(1);
tft.setRotation(4);
loopMax=description.ValueCount;
}
//#endif
//#if defined(LAYOUT) && LAYOUT == 4
if (layout == 4) {
tft.setTextSize(2);
tft.setRotation(4);
loopMax=5;
}
//#endif
//#if defined(LAYOUT) && LAYOUT > 2
if (layout > 2) {
strcpy(in,(char
*)title.TagValue[0]);
splitASCII(in,'-',address1,out);
strcpy(in,&out[1]);
splitASCII(in,'-',address2,out);
tft.printf("%s%s\n\n",address1,address2);
}
//#endif
for(int
i=2;i<loopMax;i++) {
//
tft.printf("%s\n",description.TagValue[i]);
strcpy(in,(char
*)description.TagValue[i]);
splitUTF8(in,"の",tdate,out);
tft.setTextColor("WHITE");
if
(strstr(tdate,"(土)") != 0) tft.setTextColor("CYAN");
if
(strstr(tdate,"(日)") != 0) tft.setTextColor("RED");
tft.printf("%s",tdate);
//#if defined(LAYOUT) && LAYOUT == 2
if (layout == 2) {
tft.printf("\n");
//#endif
}
//#if defined(LAYOUT) && LAYOUT == 4
if (layout == 4) {
tft.printf("\n");
//#endif
}
strcpy(in,out);
splitUTF8(in,"は",weater,out);
strcpy(in,&out[3]);
splitUTF8(in,"、",weater,out);
tft.setTextColor("WHITE");
//#if defined(LAYOUT) && LAYOUT == 2
if (layout == 2) {
tft.printf("
%s ",weater);
//#else
} else {
tft.printf("
%s\n",weater);
//#endif
}
//#if defined(LAYOUT) && LAYOUT < 4
if (layout < 4) {
strcpy(in,&out[3]);
splitUTF8(in,"で",temp,out);
strcpy(in,temp);
splitASCII(in,'
',temph,templ);
strcpy(in,temph);
removeUTF8(in,"は",temph);
strcpy(in,templ);
removeUTF8(in,"は",templ);
tft.printf("%s%s\n",temph,templ);
}
//#endif
delay(10);
}
} else {
Serial.printf("[HTTP]
Server response Not OK\n");
}
} else {
Serial.printf("[HTTP] GET... failed,
error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
}
// Calculate CRC
uint32_t calculateCRC32(const uint8_t *data, size_t
length)
{
uint32_t crc = 0xffffffff;
while (length--) {
uint8_t c = *data++;
for (uint32_t i = 0x80; i > 0; i
>>= 1) {
bool bit = crc &
0x80000000;
if (c & i) {
bit = !bit;
}
crc <<= 1;
if (bit) {
crc ^=
0x04c11db7;
}
}
}
return crc;
}
// Print RTC memory
void printMemory(int sz) {
char buf[3];
// for (int i = 0; i < sizeof(rtcData); i++) {
for (int i = 0; i < sz; i++) {
sprintf(buf, "%02X", rtcData.data[i]);
Serial.print(buf);
if ((i + 1) % 32 == 0) {
Serial.println();
}
else {
Serial.print(" ");
}
}
Serial.println();
}
// Connect AP
void setup_wifi() {
// We start by connecting to a WiFi network
Serial.println();
Serial.println();
Serial.print("Wait for WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
// send an NTP request to the time server at the given
address
unsigned long sendNTPpacket(IPAddress& address)
{
Serial.println("sending NTP packet...");
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI,
Version, Mode
packetBuffer[1] = 0; //
Stratum, or type of clock
packetBuffer[2] = 6; //
Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock
Precision
// 8 bytes of zero for Root Delay & Root
Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
udp.beginPacket(address, 123); //NTP requests are
to port 123
udp.write(packetBuffer, NTP_PACKET_SIZE);
udp.endPacket();
}
/*
* UnixTimeをYY/MM/DD hh:mm:ssで表示する
*/
void showTime(char * title, time_t timet) {
Serial.print(title);
Serial.print(":");
Serial.print(year(timet));
Serial.print("/");
Serial.print(month(timet));
Serial.print("/");
Serial.print(day(timet));
Serial.print(" ");
Serial.print(hour(timet));
Serial.print(":");
Serial.print(minute(timet));
Serial.print(":");
Serial.println(second(timet));
}
/*
* 現在日時をYY/MM/DD hh:mm:ssで表示する
*/
void showNow(char * title) {
Serial.print(title);
Serial.print(":");
Serial.print(year());
Serial.print("/");
Serial.print(month());
Serial.print("/");
Serial.print(day());
Serial.print(" ");
Serial.print(hour());
Serial.print(":");
Serial.print(minute());
Serial.print(":");
Serial.println(second());
}
const char *monthName[12] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
// dow() 曜日を示す数値を戻す[0-Sunday, 1-Monday etc.]
int dow(int y, int m, int d) {
static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2,
4};
// y -= m < 3;
if (m < 3) y--;
return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
}
// コンパイル時間をtm構造体に格納
bool buildTime(const char *str, struct tm *tm)
{
int Hour, Min, Sec;
if (sscanf(str, "%d:%d:%d", &Hour, &Min,
&Sec) != 3) return false;
tm->tm_hour = Hour;
tm->tm_min = Min;
tm->tm_sec = Sec;
return true;
}
// コンパイル年月日をtm構造体に格納
bool buildDate(const char *str, struct tm *tm)
{
char Month[12];
int Day, Year;
uint8_t monthIndex;
if (sscanf(str, "%s %d %d", Month, &Day,
&Year) != 3) return false;
for (monthIndex = 0; monthIndex < 12;
monthIndex++) {
if (strcmp(Month,
monthName[monthIndex]) == 0) break;
}
if (monthIndex >= 12) return false;
tm->tm_mday = Day;
tm->tm_mon = monthIndex + 1;
tm->tm_year = Year-1900;
tm->tm_wday = dow(Year, tm->tm_mon,
tm->tm_mday);
tm->tm_yday = 0;
tm->tm_isdst = 0;
return true;
}
// tm構造体の表示
void displayTM(char *title, struct tm hoge) {
Serial.print(title);
Serial.print(" year=");
Serial.print(hoge.tm_year);
Serial.print(" mon=");
Serial.print(hoge.tm_mon);
Serial.print(" mday=");
Serial.print(hoge.tm_mday);
Serial.print(" hour=");
Serial.print(hoge.tm_hour);
Serial.print(" min=");
Serial.print(hoge.tm_min);
Serial.print(" sec=");
Serial.print(hoge.tm_sec);
Serial.print(" wday=");
Serial.print(hoge.tm_wday);
Serial.print(" yday=");
Serial.print(hoge.tm_yday);
Serial.print(" isdst=");
Serial.print(hoge.tm_isdst);
Serial.println();
}
// tm構造体の比較
int compTM(struct tm tm1, struct tm tm2) {
if (tm1.tm_year != tm2.tm_year) return 1;
if (tm1.tm_mon != tm2.tm_mon) return 1;
if (tm1.tm_mday != tm2.tm_mday) return 1;
if (tm1.tm_hour != tm2.tm_hour) return 1;
if (tm1.tm_min != tm2.tm_min) return 1;
if (tm1.tm_sec != tm2.tm_sec) return 1;
if (tm1.tm_wday != tm2.tm_wday) return 1;
return 0;
}
void setup() {
Serial.begin(9600);
delay(500);
Serial.println();
Serial.println();
Serial.println("Wake Up");
Serial.print("__TIME__=[");
Serial.print(__TIME__);
Serial.print("] __DATE__=[");
Serial.print(__DATE__);
Serial.println("]");
// コンパイルした日時を求める
buildDate(__DATE__, &ctm);
buildTime(__TIME__, &ctm);
displayTM("[ctm]",ctm);
Serial.print("sizeof(ctm)=");
Serial.println(sizeof(ctm));
// RTC memoryからデータを読み込む
if (ESP.rtcUserMemoryRead(0, (uint32_t*)
&rtcData, sizeof(rtcData))) {
Serial.println("Read: ");
printMemory(10);
// 読み込んだデータでCRC32を計算する
uint32_t crcOfData =
calculateCRC32(((uint8_t*) &rtcData) + 4,
sizeof(rtcData) - 4);
Serial.print("CRC32 of data: ");
Serial.println(crcOfData, HEX);
Serial.print("CRC32 read from RTC: ");
Serial.println(rtcData.crc32, HEX);
// CRC32が一致しないので初回起動時
if (crcOfData != rtcData.crc32) {
Serial.println("CRC32 in
RTC memory doesn't match CRC32 of data. Data is probably
invalid!");
Serial.println("sizeof(rtcData.data)=" +
String(sizeof(rtcData.data)));
for (int i = 0; i <
sizeof(rtcData.data); i++) {
rtcData.data[i]
= 0;
}
}
// CRC32が一致したのでResetからの復帰、あるいは再コンパイル
else {
Serial.println("CRC32 check
ok, data is probably valid.");
// コンパイル日時を比較
displayTM("[compile]",rtcData.compile);
if (compTM(ctm,
rtcData.compile) == 1) {
Serial.println("Compile Date & Time doesn't match.");
rtcData.data[0]
= 0;
} else {
Serial.println("Compile Date & Time match.");
}
}
}
// NTPクライントモード
if (rtcData.data[0] == 0) {
// Wifi接続
setup_wifi();
Serial.println("Starting UDP");
udp.begin(localPort);
// 最初の時刻リクエストを送信
sendNTPpacket(timeServer);
// HTTPクライアントモード
} else {
// 時刻設定
showNow("Before");
setTime(rtcData.data[3],rtcData.data[4],rtcData.data[5],
rtcData.data[2],rtcData.data[1],rtcData.data[0]);
showNow("After");
// Wifi接続
setup_wifi();
// start tft
tft.begin();
// HTML表示
displayHTML(LAYOUT);
}
}
void loop() {
// NTPサーバからのパケット受信(初回起動時のみ)
int cb = udp.parsePacket();
if (cb) {
Serial.print("packet received,
length=");
Serial.println(cb);
// バッファに受信データを読み込む
udp.read(packetBuffer,
NTP_PACKET_SIZE); // read the packet into the buffer
// 時刻情報はパケットの40バイト目からはじまる4バイトのデータ
unsigned long highWord =
word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord =
word(packetBuffer[42], packetBuffer[43]);
//
NTPタイムスタンプは64ビットの符号無し固定小数点数(整数部32ビット、小数部32ビット)
// 1900年1月1日0時との相対的な差を秒単位で表している
// 小数部は切り捨てて、秒を求めている
unsigned long secsSince1900 = highWord
<< 16 | lowWord;
Serial.print("Seconds since Jan 1 1900
= " );
Serial.println(secsSince1900);
// NTPタイムスタンプをUNIXタイムに変換する
// UNITタイムは1970年1月1日0時からはじまる
// 1900年から1970年の70年を秒で表すと2208988800秒になる
const unsigned long seventyYears =
2208988800UL;
// NTPタイムスタンプから70年分の秒を引くとUNIXタイムが得られる
unsigned long epoch = secsSince1900 -
seventyYears;
Serial.print("Unix time = ");
Serial.println(epoch);
showTime("UTC",epoch);
showTime("JST",epoch + (9 * 60 * 60));
// Timeライブラリに時間を設定(UNIXタイム)
// 日本標準時にあわせるために+9時間しておく
setTime(epoch + (9 * 60 * 60));
// 現在の時間を設定
rtcData.data[0] = year();
rtcData.data[1] = month();
rtcData.data[2] = day();
rtcData.data[3] = hour();
rtcData.data[4] = minute();
rtcData.data[5] = second();
// コンパイル日時を格納
memcpy(&(rtcData.compile),
&ctm, sizeof(ctm));
// CRC32を再計算
rtcData.crc32 =
calculateCRC32(((uint8_t*) &rtcData) + 4,
sizeof(rtcData) - 4);
// RTC memoryにデータを書き込む
if (ESP.rtcUserMemoryWrite(0,
(uint32_t*) &rtcData, sizeof(rtcData))) {
Serial.println("Write: ");
printMemory(10);
}
// Reset
Serial.println("Now reset......");
WiFi.disconnect();
ESP.reset();
while(1) {}
}
static int counter = 0;
static int interval = 30;
long now = millis();
// 時刻確認
if (lastCheckTime == 0) lastCheckTime = now;
if (now - lastCheckTime > 1000) { // 1秒経過
lastCheckTime = now;
counter++;
if (counter > interval) {
showNow("Current Date &
Time");
if (hour() == ON[0]
&& minute() == ON[1]) { // 表示の更新
displayHTML(LAYOUT);
interval = 60;
// 次回は60秒後に時刻確認
} else if (hour() == OFF[0]
&& minute() == OFF[1]) { // 表示の消去
tft.fillScreen("BLACK");
interval = 60;
// 次回は60秒後に時刻確認
#if 0
//ここを有効にすると、表示OFFにした後で時刻合わせを行う
// CRC32をクリア
rtcData.crc32 =
0;
// RTC
memoryにデータを書き込む
if
(ESP.rtcUserMemoryWrite(0, (uint32_t*) &rtcData,
sizeof(rtcData))) {
Serial.println("Write: ");
printMemory(10);
}
// Reset
Serial.println("Now reset......");
WiFi.disconnect();
ESP.reset();
while(1) {}
#endif
} else {
interval = 30;
// 次回は30秒後に時刻確認
}
counter=0;
}
}
}
|