diff --git a/README.md b/README.md index 17ad80c..3a72b2c 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ void receiver_loop() { } if (time_to_send_timesync()) { - time_send_timesync(self_short_id); // 60s for first 10 min, then hourly + time_send_timesync(self_short_id); // 60s for first 10 min, then hourly if RTC is present } mqtt_loop(); @@ -242,8 +242,10 @@ inline constexpr uint16_t EXPECTED_SENDER_IDS[NUM_SENDERS] = { 0xF19C }; - Defaults: `pool.ntp.org` and `time.nist.gov`. ## RTC (DS3231) - Optional DS3231 on the I2C bus. Connect SDA to GPIO21 and SCL to GPIO22 (same bus as the OLED). +- Enable/disable with `ENABLE_DS3231` in `include/config.h`. - Receiver time sync packets set the RTC. - On boot, if no LoRa time sync has arrived yet, the sender uses the RTC time as the initial `ts_utc`. +- When no RTC is present or enabled, the receiver keeps sending time sync every 60 seconds. ## Build Environments - `lilygo-t3-v1-6-1`: production build diff --git a/src/rtc_ds3231.cpp b/src/rtc_ds3231.cpp index 1b1d91f..e68fcfc 100644 --- a/src/rtc_ds3231.cpp +++ b/src/rtc_ds3231.cpp @@ -13,6 +13,23 @@ static uint8_t dec_to_bcd(uint8_t val) { return static_cast(((val / 10) << 4) | (val % 10)); } +static time_t timegm_fallback(struct tm *tm_utc) { + if (!tm_utc) { + return static_cast(-1); + } + char *old_tz = getenv("TZ"); + setenv("TZ", "UTC0", 1); + tzset(); + time_t t = mktime(tm_utc); + if (old_tz) { + setenv("TZ", old_tz, 1); + } else { + unsetenv("TZ"); + } + tzset(); + return t; +} + static bool read_registers(uint8_t start_reg, uint8_t *out, size_t len) { if (!out || len == 0) { return false; @@ -77,7 +94,7 @@ bool rtc_ds3231_read_epoch(uint32_t &epoch_utc) { tm_utc.tm_year = year - 1900; tm_utc.tm_isdst = 0; - time_t t = timegm(&tm_utc); + time_t t = timegm_fallback(&tm_utc); if (t <= 0) { return false; }