2022年5月10日火曜日

ESP32の時間の扱い方メモ

 ESP32とArduinoIDEにおける、時間関係の情報。

time.hライブラリに含まれているらしいのですが、includeしなくても使えました。(2022年5月現在)


struct tm timeinfo;

time_tを変換してstruct tm型にすると、時間や日付などの表示がやりやすくなる


struct tm {

        int     tm_sec;         // 0~60(60 は閏秒)
        int     tm_min;         // 0~59
        int     tm_hour;        // 0~23
        int     tm_mday;        // 月内の日 0~31
        int     tm_mon;         // 1月を0とする月 0~11
        int     tm_year;        // 1900年を0とする年
        int     tm_wday;        // 日曜日を0とする曜日
        int     tm_yday;        // 1月1日を 0 とする日 0~365
        int     tm_isdst;       // サマータイム
        long    tm_gmtoff;      // グリニッジ時刻からのオフセット
        char    *tm_zone;       // タイムゾーン
};


time_t time;

 1970年1月1日0時00分00秒からの秒数. 64bit
時差などを計算するときはtime_t型が便利。
注:32bitで定義されている場合、もうすぐオーバーフローするのでまずいらしいです。

mktime() 

time_t mktime(struct tm * timeinfo)

struct tmをtime_tに変換する


localtime_r() 

struct tm * localtime_r(const time_t *timep, struct tm * timeinfo);

time_t型からstruct tmを得る

注:localtime()という関数があるが、ヤバいらしいのでlocaltime_rのほうがいいです。


例 現在時刻から9時間後の時刻と日付を表示する

  struct tm timeinfo_JST;
  time_t time; 
  time = mktime(&timeinfo);
  time  = time1 + 3600 * 9;
  localtime_r( &time1, &timeinfo_JST);
  Serial.print("JST:");
  Serial.println(&timeinfo_JST, "%A, %B %d %Y %H:%M:%S");


そのほかの時間関係の関数

getLocalTime()

bool getLocalTime(struct tm * timeinfo)
bool getLocalTime(struct tm * timeinfo, uint32_t msec)

ローカル時刻(RTCのカウンタ値?)を取得する。

timeinfo : struct tm
msec : タイムアウト default=5000
戻り値
true : 成功
false:失敗。configTime()で時間を設定せずにgetLocalTimeした場合などに出る

失敗する例 configtimeをしていないため、RTCが初期値のまま。
struct tm timeinfo;
void setup() {
    Serial.begin(115200);
    // configTime(0, 0, "ntp.nict.jp"); 
    if (getLocalTime(&timeinfo) == false) {
        Serial.print("can't get local time");
    }
}


configTime()

void configTime(long gmtOffset_sec, int daylightOffset_sec, const char * server1, const char * server2, const char * server3)

NTCサーバからの情報をもとにRTCを設定する

gmtOffset_sec : GMTとローカル時刻との差 JSTなら9*3600
daylightOffset_sec:サマータイム。JSTなら常に0
server1, server2, server3:NTPサーバのアドレス。1つでいい。


ほかにもいくつか時間に関する関数があるらしいですが、とりあえず上の4つを知っていれば間に合いそうです。


参照:ArduinoIDEの、スケッチ例>ESP32>time>SimpleTime


時間に関するその他の情報

configTimeで設定したgmtOffsetは、DeepSleepすると0に戻るので注意

前回の記事を参照


解決策としては、RTCはGMTでリセットし、表示するときに一度time_tにして+9時間して、再度struct tmにして表示する

void printJST(struct tm timeinfo) {
  struct tm timeinfo_JST;
  time_t time1; //typedef long time_t; 
  time1 = mktime(&timeinfo);
  time1 = time1 + 3600 * 9;
  localtime_r( &time1, &timeinfo_JST);
  Serial.print("JST:");
  Serial.println(&timeinfo_JST, "%A, %B %d %Y %H:%M:%S");
}








0 件のコメント:

コメントを投稿