TTGO T-watchの腕時計の時刻表示がおかしいので調べていったことのメモ
・T-Watchでは画面オフ時にシステムクロックが止まる
T-watchでは左側の端っこボタンを押すと画面がオフになる。
この処理は、power_handle関数内の「LVGL_POWER_IRQ」イベントの「axp.isPEKShortPressIRQ()」( 左側の端っこボタン =PEKキー)で行われている。
オフ時に「rtc_clk_cpu_freq_set(RTC_CPU_FREQ_2M)」を実行して、CPU周波数を落としている(240M→2M)
これによりOS内のシステムクロックの進みも劇的に遅くなって、ほぼ止まっているように見える。
このことがあるので、T-Watchのソフトウェアでは、システムクロックからではなく、RTC上の時計から時刻を取得しているようだった。
・システムクロックの設定方法はsettimeofday(UNIX)
Arduino/ESP32環境でシステムクロックを簡単に設定する手法はNTPからの時刻を取得して、システムクロックを適用する、というもの。
struct tm timeinfo;
bool ret = false;
int retry = 0;
configTzTime("JST-9", "pool.ntp.org");
do {
ret = getLocalTime(&timeinfo);
if (!ret) {
Serial.printf("get ntp fail,retry : %d \n", retry++);
}
} while (!ret && retry < 3);
また、システムクロックをRTCに反映するのも簡単。(以下は、RTCモジュールがPCF8563の場合に使うPCF8563_Libraryの場合)
rtc.setDateTime(timeinfo.tm_year, timeinfo.tm_mon + 1, timeinfo.tm_mday, timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
しかし、逆にRTCからシステムクロックに対して時刻を反映させる手法がよく分からない。
RTCモジュールがDS1307RTCの場合の事例があるので Michael MargolisさんによるTimeモジュールを使ってみたが、時刻設定はできなかった。
void syncSystemTimeByRtc()
{
Serial.print("Read RTC :");
Serial.println(rtc.formatDateTime(PCF_TIMEFORMAT_YYYY_MM_DD_H_M_S));
struct tm dt;
getLocalTime(&dt);
Serial.printf("getLocalTime is %d:%d:%d\n",dt.tm_hour,dt.tm_min,dt.tm_sec);
RTC_Date d = rtc.getDateTime();
Serial.printf(" %d,%d,%d,%d,%d,%d\n",d.hour,d.minute,d.second,d.day,d.month,d.year);
setTime(d.hour,d.minute,d.second,d.day,d.month,d.year);
Serial.println(timeStatus());
getLocalTime(&dt);
Serial.printf("getLocalTime override RTC clock, %d:%d:%d\n",dt.tm_hour,dt.tm_min,dt.tm_sec);
}
上記のデバグコードをいれて、画面オフ→オンイベントを起こしてみると、
10:16:18.034 -> LVGL_POWER_IRQ event
10:16:18.034 ->
10:16:18.034 -> PEKShortPressIRQ to off
10:31:15.803 -> PEKShortPressIRQ to on
10:31:15.803 -> bma423_disable:0
10:31:15.803 -> Read RTC :2019-7-2/10:31:15
10:31:15.835 -> getLocalTime is 10:16:9
10:31:15.835 -> 10,31,15,2,7,2019
10:31:15.835 -> 2
10:31:15.835 -> getLocalTime override RTC clock, 10:16:9
10:31:24.715 -> RTC time is 2019-7-2/10:31:24
10:31:24.715 -> getLocalTime is 10:16:17
時刻が設定されていない・・・
UNIXだとどうやってシステムクロック設定できたかな?と調べて見たらsettimeofdayでunixtimeを指定する、ということが判明
#include <time.h> // requried for settimeofday
#include <sys/time.h>// requried for timeval
上記を冒頭に追加した上で、以下を書いた。
void syncSystemTimeByRtc()
{
Serial.print("Read RTC :");
Serial.println(rtc.formatDateTime(PCF_TIMEFORMAT_YYYY_MM_DD_H_M_S));
struct tm dt;
getLocalTime(&dt);
Serial.printf("getLocalTime is %d:%d:%d\n",dt.tm_hour,dt.tm_min,dt.tm_sec);
RTC_Date d = rtc.getDateTime();
Serial.printf(" %d,%d,%d,%d,%d,%d\n",d.hour,d.minute,d.second,d.day,d.month,d.year);
dt.tm_hour = d.hour;
dt.tm_min = d.minute;
dt.tm_sec = d.second;
dt.tm_mday = d.day;
dt.tm_mon = d.month-1;
dt.tm_year = d.year-1900;
time_t timertc = mktime(&dt);
Serial.print("RTC unixtime is ");
Serial.print(timertc);
Serial.print(" ,system unixtime is ");
time_t timesys = time(NULL);
Serial.println(timesys);
struct timeval tv ={
.tv_sec = timertc
};
settimeofday(&tv,NULL);
getLocalTime(&dt);
Serial.printf("getLocalTime override RTC clock, %d:%d:%d\n",dt.tm_hour,dt.tm_min,dt.tm_sec);
}
これで期待通りにRTCの時刻をシステムクロックに反映することができるようになった。
13:23:48.103 -> PEKShortPressIRQ to on
13:23:48.103 -> bma423_disable:0
13:23:48.103 -> Read RTC :2019-7-2/13:23:47
13:23:48.103 -> getLocalTime is 13:17:30
13:23:48.103 -> 13,23,47,2,7,2019
13:23:48.103 -> RTC unixtime is 1562041427 ,system unixtime is 1562041050
13:23:48.103 -> getLocalTime override RTC clock, 13:23:47
13:23:57.121 -> RTC time is 2019-7-2/13:23:56
13:23:57.121 -> getLocalTime is 13:23:56
・rtc_cpu_freq_setは非推奨
コンパイル中に以下の警告が・・・
C:\Users\osakanataro\Documents\Arduino\TTGO-T-Watch-mod\TTGO-T-Watch-mod.ino:328:17: warning: 'void rtc_clk_cpu_freq_set(rtc_cpu_freq_t)' is deprecated [-Wdeprecated-declarations]
rtc_clk_cpu_freq_set(RTC_CPU_FREQ_240M);
「 https://github.com/espressif/arduino-esp32/blob/master/tools/sdk/include/soc/soc/rtc.h 」を確認したところ、「 rtc_clk_cpu_freq_config_set 」に置き換わった、とある。
・・・あるんだけど、 rtc_clk_cpu_freq_config_set に関する資料がでてこないってどういうこと???
grepしても定義無いし、試しに置き換えてみても定義されてない、というエラーになった。