|
ProtoCore v0.0.1
Deterministic, zero-heap network stack for embedded targets
|
An ESP32 forgets the date and time every time it loses power. This example adds a real-time clock (RTC) - a tiny chip with its own coin-cell battery that keeps ticking for years - so the board knows the correct time the instant it boots, with no internet. It is written for a beginner, and it is a nice first soldering/wiring project.
Without a clock, a freshly powered ESP32 thinks it is 1970 until it can reach a time server. That breaks anything time-sensitive: log timestamps, TLS certificate checks, scheduled tasks. On an offline network there may be no time server at all. A ~$2 RTC module (a DS3231 is the accurate, popular choice; a DS1307 also works) solves it for good.
| RTC module pin | ESP32 pin |
|---|---|
VCC | 3V3 |
GND | GND |
SDA | GPIO 21 |
SCL | GPIO 22 |
(21/22 are the ESP32's default I2C pins. If your board uses different ones, change Wire.begin(SDA, SCL) - the driver calls plain Wire.begin().) Pop the coin cell into the module so it keeps time when unplugged.
Open Rtc.ino, set your SSID/PASSWORD, upload, and open the Serial Monitor at 115200. On a brand-new module you will see:
The clever part: the first time the board reaches the internet it reads the correct time from NTP and writes it into the RTC chip. From then on the RTC is the source of truth.
Unplug the ESP32, wait a bit, and plug it back in with WiFi turned off or unavailable. This time it already knows the time - from the battery-backed chip:
No network needed. That is what an RTC buys you.
pc_time_now() asks your registered time sources best-first. Here the RTC is source #1, so your whole app just calls pc_time_now() and gets good time offline. Chain it with GPS (example 58) and upstream NTP for the full picture - GPS (best) -> RTC (offline) -> NTP - and feed it to the NTP server (example 58) to serve time to your entire LAN.
RTC at boot: 0 every time, even after setting.** The coin cell is missing, dead, or in backwards - the chip cannot keep time without it. Also check the SDA/SCL wires are not swapped.VCC/GND and that SDA->21, SCL->22. A quick I2C scanner sketch should find a device at address 0x68.The feature lives in the library, so its flags must reach the whole build:
(The Arduino IDE reads the flags from build_opt.h beside the sketch automatically.)
The DS1307/DS3231 store the time in seven BCD registers (each nibble is one decimal digit) at I2C address 0x68. pc_rtc_read_epoch() reads those seven bytes and pc_rtc_regs_to_epoch() converts them - handling 12/24-hour encoding, leap years, and the chip's clock-halt/century bits - into a Unix timestamp; pc_rtc_set_epoch() does the reverse to set the chip. All the date math is fixed-point and heap-free, and the conversions are unit-tested on a PC across the 2000-2099 range (that round-trip test caught a real 32-bit overflow past 2038 - see test/test_rtc). Only the register read/write touches I2C.