I'm developing a device that can go to deep sleep while maintaining the RTC clock working during that period of sleep.
I'm using the ESP32 Dev module with an external 32.768KHz to be able to keep the internal RTC as accurate as possible, but I found that in deep sleep the clock has a drift of 1 second every 350 seconds (approximately).
I tried to use adjtime(&adjustVal, NULL) function to slowly correct the drift but it seems every time the ESP goes to sleep this function won't do anything.
My example implementation consists of a setup method that will print the time to serial, configure the RTC clock to external 32KHz and goes to deep sleep for 10 seconds with a timer wakeup event.
Every 350 seconds (35 wakeups) I adjust the time for 1 second, but no matter if I instructed 40 seconds, it doesn't do anything to the timer.
This is the code
void setup() {
char message_buf1[150];
// put your setup code here, to run once:
Serial.begin(115200);
// WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); // disable detector
configureIO();
myPower.begin(PWR_SENSE_IN, BAT_SENS_AD, BAT_SENS_CTRL, BAT_CHARGING);
Counter = 0;
timerSetup();
configureRTC();
if (bootCount == 1) {
// Connect to Wi-Fi
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(250);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected.");
// Init and get the time
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
printLocalTime();
// disconnect WiFi as it's no longer needed
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
} else {
sprintf(message_buf1, "Hora de inicio datetimeRTC =%s",
ctime(&RTCTime));
Serial.print(message_buf1);
}
sprintf(message_buf1, "Inicio de configuracion RTCTime=(%ld) ",
RTCTime); Serial.print(message_buf1); sprint(message_buf1, "datetimeRTC
=%s", ctime(&RTCTime)); Serial.println(message_buf1);
Serial.flush();
esp_deep_sleep_start();
Serial.println("This will never be printed");
}
void timerSetup(void)
{
time(&RTCTime);
localtime_r(&RTCTime, &timeinfo);
setenv("TZ", "<-05>5", 1);
tzset();
timerMux = portMUX_INITIALIZER_UNLOCKED;
timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, &onTimer, true);
timerAlarmWrite(timer, 1000000, true); // 1seg
timerAlarmEnable(timer);
}
void configureRTC(void) {
timeval adjustment;
timeval oldDelta;
++bootCount;
timeAdjCounter += TIME_TO_SLEEP;
Serial.printf("Boot number: %d and timeAdjCounter :%d \r\n", bootCount,
timeAdjCounter);
if (adjtime(NULL, &oldDelta) == 0) {
Serial.printf("Delta still processing %ld.%ld\n\r", oldDelta.tv_sec,
oldDelta.tv_usec);
}
if (timeAdjCounter >= ADJ_COUNTER_VAL) {
timeAdjCounter = 0;
adjustment.tv_sec -= 1;
adjtime(&adjustment, &oldDelta);
Serial.printf(
"*** Ajuste de reloj ejecutado - OldDelta (%ld s).(%ld ms)****** "
"\n\r",
oldDelta.tv_sec, oldDelta.tv_usec / 1000);
}
print_slow_clock_source();
setExternalCrystalAsRTCSource();
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) +
" Seconds");
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
}
Anyone can point me if the adjtime routine has no effect if the ESP32 go to sleep right after calling it?
Thank you
Ernesto Pareja