Arduino本体には時計機能が無い為、時間の管理にはRTCモジュール等を使用する。
HiLetgo 3個セット DS3231 AT24C32 時計モジュール リアル時間時計モジュール IICモジュール RTCモジュール Arduinoに対応 [並行輸入品]
RTCモジュールも購入直後は時間情報が無い為、なんらかの形で時刻設定が必要となる。
良くRTCの時計合わせで紹介されている手法として、スケッチ書き込み時の日時にRTCを合わせる
RTC.adjust(DateTime(__DATE__, __TIME__));
のコードがあるが、スケッチ書き込み時の時間に合わせる為、このままだとArduinoが起動する度にスケッチ書き込み時の時間に調整されてしまう。このため、一度スケッチを書き込んだ後上記コードを削除してもう一度スケッチを書き込む必要がある。
購入直後は古い時刻になっているため、「スケッチ書き込み時の時間より時計が遅ければスケッチ書き込み時の時間に合わせる」事で、スケッチ書き込み時にのみ時間を調整し、以降Arduino起動後は時計が進んでいるので時刻調整が発生しない様に出来る。
DateTime now;
//RTCから現在時刻を取得する
now = RTC.now();
//RTCから取得した時間よりスケッチをコンパイルした時間が新しい場合、コンパイル時間に合わせる
DateTime compiled = DateTime(__DATE__, __TIME__);
if (now.unixtime() < compiled.unixtime()) {
RTC.adjust(DateTime(__DATE__, __TIME__));
}
これで時計が全く合っていないRTCモジュールや、時間が遅れているRTCモジュールはスケッチ書き込み時に時刻調整が行われる。
RTCモジュールの時計が進んでいる場合は調整されないのでスケッチ書き込み時に必ず正確な時間になる訳ではない。
DS3232RTCライブラリ等、上記APIが使えずRTC.setのAPIがある場合は下記の様にする。(https://github.com/JChristensen/DS3232RTC/blob/master/examples/alarm_ex1/alarm_ex1.ino)
//スケッチ書き込み時間をtime_t形式で取得
time_t compileTime()
{
const time_t FUDGE(10); //fudge factor to allow for upload time, etc. (seconds, YMMV)
const char *compDate = __DATE__, *compTime = __TIME__, *months = "JanFebMarAprMayJunJulAugSepOctNovDec";
char compMon[4], *m;
strncpy(compMon, compDate, 3);
compMon[3] = '\0';
m = strstr(months, compMon);
tmElements_t tm;
tm.Month = ((m - months) / 3 + 1);
tm.Day = atoi(compDate + 4);
tm.Year = atoi(compDate + 7) - 1970;
tm.Hour = atoi(compTime);
tm.Minute = atoi(compTime + 3);
tm.Second = atoi(compTime + 6);
time_t t = makeTime(tm);
return t + FUDGE; //add fudge factor to allow for compile time
}
void setup() {
time_t timenow, compiletime;;
timenow = RTC.get();
compiletime = compileTime();
if (timenow < compiletime)
RTC.set(compiletime);