Arduino/ESP32/TTGO T-WatchのシステムクロックとRTC周りのメモ 2019/07/02

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からの時刻を取得して、システムクロックを適用する、というもの。

1struct tm timeinfo;
2bool ret = false;
3int retry = 0;
4configTzTime("JST-9", "pool.ntp.org");
5do {
6    ret = getLocalTime(&timeinfo);
7    if (!ret) {
8        Serial.printf("get ntp fail,retry : %d \n", retry++);
9    }
10} while (!ret && retry < 3);

また、システムクロックをRTCに反映するのも簡単。(以下は、RTCモジュールがPCF8563の場合に使うPCF8563_Libraryの場合)

1rtc.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モジュールを使ってみたが、時刻設定はできなかった。

1void syncSystemTimeByRtc()
2{
3    Serial.print("Read RTC :");
4    Serial.println(rtc.formatDateTime(PCF_TIMEFORMAT_YYYY_MM_DD_H_M_S));
5    struct tm dt;
6    getLocalTime(&dt);
7    Serial.printf("getLocalTime is %d:%d:%d\n",dt.tm_hour,dt.tm_min,dt.tm_sec);
8    RTC_Date d = rtc.getDateTime();
9    Serial.printf("  %d,%d,%d,%d,%d,%d\n",d.hour,d.minute,d.second,d.day,d.month,d.year);
10    setTime(d.hour,d.minute,d.second,d.day,d.month,d.year);
11    Serial.println(timeStatus());
12    getLocalTime(&dt);
13    Serial.printf("getLocalTime override RTC clock, %d:%d:%d\n",dt.tm_hour,dt.tm_min,dt.tm_sec);
14    
15}

上記のデバグコードをいれて、画面オフ→オンイベントを起こしてみると、

110:16:18.034 -> LVGL_POWER_IRQ event
210:16:18.034 ->
310:16:18.034 -> PEKShortPressIRQ to off
410:31:15.803 -> PEKShortPressIRQ to on
510:31:15.803 -> bma423_disable:0
610:31:15.803 -> Read RTC :2019-7-2/10:31:15
710:31:15.835 -> getLocalTime is 10:16:9
810:31:15.835 ->   10,31,15,2,7,2019
910:31:15.835 -> 2
1010:31:15.835 -> getLocalTime override RTC clock, 10:16:9
1110:31:24.715 -> RTC time is 2019-7-2/10:31:24
1210:31:24.715 -> getLocalTime is 10:16:17

時刻が設定されていない・・・

UNIXだとどうやってシステムクロック設定できたかな?と調べて見たらsettimeofdayでunixtimeを指定する、ということが判明

1#include <time.h>    // requried for settimeofday
2#include <sys/time.h>// requried for timeval

上記を冒頭に追加した上で、以下を書いた。

1void syncSystemTimeByRtc()
2{
3    Serial.print("Read RTC :");
4    Serial.println(rtc.formatDateTime(PCF_TIMEFORMAT_YYYY_MM_DD_H_M_S));
5    struct tm dt;
6    getLocalTime(&dt);
7    Serial.printf("getLocalTime is %d:%d:%d\n",dt.tm_hour,dt.tm_min,dt.tm_sec);
8    RTC_Date d = rtc.getDateTime();
9    Serial.printf("  %d,%d,%d,%d,%d,%d\n",d.hour,d.minute,d.second,d.day,d.month,d.year);
10    dt.tm_hour = d.hour;
11    dt.tm_min  = d.minute;
12    dt.tm_sec  = d.second;
13    dt.tm_mday  = d.day;
14    dt.tm_mon = d.month-1;
15    dt.tm_year = d.year-1900;
16    time_t timertc = mktime(&dt);
17    Serial.print("RTC unixtime is ");
18    Serial.print(timertc);
19    Serial.print(" ,system unixtime is ");
20    time_t timesys = time(NULL);
21    Serial.println(timesys);
22    struct timeval tv ={
23      .tv_sec = timertc
24    };
25    settimeofday(&tv,NULL);
26     
27    getLocalTime(&dt);
28    Serial.printf("getLocalTime override RTC clock, %d:%d:%d\n",dt.tm_hour,dt.tm_min,dt.tm_sec);
29    
30}

これで期待通りにRTCの時刻をシステムクロックに反映することができるようになった。

113:23:48.103 -> PEKShortPressIRQ to on
213:23:48.103 -> bma423_disable:0
313:23:48.103 -> Read RTC :2019-7-2/13:23:47
413:23:48.103 -> getLocalTime is 13:17:30
513:23:48.103 ->   13,23,47,2,7,2019
613:23:48.103 -> RTC unixtime is 1562041427 ,system unixtime is 1562041050
713:23:48.103 -> getLocalTime override RTC clock, 13:23:47
813:23:57.121 -> RTC time is 2019-7-2/13:23:56
913:23:57.121 -> getLocalTime is 13:23:56

・rtc_cpu_freq_setは非推奨

コンパイル中に以下の警告が・・・

1C:\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]
2 
3                 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しても定義無いし、試しに置き換えてみても定義されてない、というエラーになった。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

This site uses Akismet to reduce spam. Learn how your comment data is processed.

StatCounter - Free Web Tracker and Counter