-
Notifications
You must be signed in to change notification settings - Fork 7.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inaccurate timing (IDFGH-4893) #6687
Comments
esp-idf/components/esp32/Kconfig Lines 539 to 571 in 39cbf2f
|
CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y
# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set
# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set
# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set
# CONFIG_ESP32_RTC_CLK_SRC_INT_RC is not set
# CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set
# CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set
CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256=y
CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 |
sntp_deep_sleep_drift.zip
The basic idea was to have a minimal sample : on power on reset once wifi connection is established and ntp_sync performed. To be noted: I haven't really looked into temperature compensation thus observation was made in my well temperated room at about 18-22 °C. |
Hello, I will post for the first time. |
Interesting, tomocchi3411 ended up using the same compensation mechanism (modifying slow clk cal register). If his conclusion is correct, that the 150kHz slow clock speed changes between power modes, this explaines why it's possible to actually compensate. It would be interesting to hear from espressif what could cause this and if there is a state of the chip e.g. wake up stub or something to measure the actual deep sleep slow clock frequency. Otherwise it might be tedious to measure the compensation factor for each chip. |
Thank you for your prompt reply, parapilot. I think the reason why the oscillator frequency of the 150kHz Slow Clock fluctuates is the temperature drift and voltage change. |
Hi tomocchi3411. Your explanation sounds reasonable. I measured temperature drift against ambient over days without thinking about stronger short term changes of substrate temperature. Hower you're right that changes in power consumption and voltage level have a high short term impact on substrate temperature and RC frequency. Thus a first speculation could be that part of the problem is the disfunctional internal temperature point which was removed over time. |
Hi parapilot, thank you for your reply. 10:50:19.655 -> 2022/04/01(Fri)_10:50:19.750 from WiFi 10:55:17.104 -> 2022/04/01(Fri)_10:55:19.753 from internal rtc 11:00:16.928 -> 2022/04/01(Fri)_11:00:19.752 from internal rtc 11:05:16.946 -> 2022/04/01(Fri)_11:05:19.751 from internal rtc 11:50:17.093 -> 2022/04/01(Fri)_11:50:19.744 from internal rtc 12:30:16.750 -> 2022/04/01(Fri)_12:30:19.739 from internal rtc 12:50:16.635 -> 2022/04/01(Fri)_12:50:19.736 from internal rtc 15:50:16.907 -> 2022/04/01(Fri)_15:50:19.712 from internal rtc At first, the RTC time synchronized with NTP and the PC time are almost the same, but after 10 minutes, the RTC will advance by about 3 seconds. |
Thank your suggestions very much. I has konwn that the time is more accurate when RTC clk source is 150KHz RC by trying all the internal clock sources. This deviation is within my tolerance. Your discussions wil help me further reduce the time deviation. |
@tomocchi3411, I wanted to thank you for your comments and code. I have an ESP32 project that gets the current time from an NTP server, runs for about 2 hours, then goes into deep sleep mode for 22 hours (it wakes up the next day and repeats the process). While it is deep sleeping the rtc time keeping is not very accurate, and the app would consequently wake up several minutes early every day. I ran your rtc calibration sketch to determine the proper calibration offset, and incorporated that into my own sketch and now the ESP32 keeps much better time when in deep sleep mode. I thought it was a clever solution, although I can find very little documentation about using the RTC_CNTL_STORE1_REG register to fine tune the rtc clock, so kudos to you for figuring that one out. Also, your code to blink an LED while in deep sleep is genius. I had never seen that done before. I learned a lot looking over your sketches. |
@moose4lord Thank you for comments, helittr and moose4lord. PC Time RTC Time T(us) Freq(kHz) Rate temp(C) The above is the actual measurement, Freq(kHz) is the RTC clock frequency of 8.5MHz/256, and temp(C) is the temperature(Celsius) of the ESP32 measured with a thermistor . Looking at this, the clock frequency doesn't seem to be affected by temperature. |
Thanks for the update @tomocchi3411. I was initially pretty happy with your calibration code using the internal RC oscillator, but the longer I ran it, the more variation I saw in the deep sleep timing. It was much better than my old uncalibrated setup, but over the course of a week or two, I would see the deep sleep times start to drift. I suspected the drift was due to temperature variation throughout the week, so I ran some experiments putting the ESP32 in my refrigerator and I did see quite a bit of temperature instability, especially when the ESP32 is undergoing temperature transitions. I live in Vermont and my project is outside, so the temperature varies considerable throughout the year. I was not looking forward to recalibrating every season. :) So when I saw your new code using the 8.5MHz/256 oscillator, it was good news. I've done a little testing and I agree, that oscillator seems much more stable. And it only adds about 20uA to the deep sleep current draw, which is OK for me. I'll integrate your new code into my project and let you know how it goes. |
Hello @tomocchi3411, sorry it's taken so long to reply. I got distracted by other projects, but now I'm back to investigating the ESP32 sleep timing issue. Using your latest calibration code and 8.5MHz/256 clock source, I was able to get sleep timing results similar to yours for a two hour sleep time:
Unfortunately, if I extend the sleep time to four hours, I start to see some timing instability:
I modified your testSlowClockAutocalib3 sketch (see attached) to ramp the sleep time from 3 minutes to 8 hours, periodically resyncing with the SMTP server, hoping it would converge on a very accurate value for RTC_CLOCK_RATE. Unfortunately, it didn't converge on a value:
I don't know, it seems the longer the ESP is in deep sleep mode, the more unstable the timing gets. The 8.5MHz/256 clock does help a lot, so I appreciate your help with that. My app sleeps for about 22 hours every day and tries to wake up at a specific time. I'm content that it usually wakes up within a couple minutes of the correct time, but it bugs me that I can't get it any better than that. You mentioned you had some experience with external crystal oscillators. Does an external crystal provide better stability than the 8.5MHz/256 oscillator? |
@igrr Any thoughts/tips on this? |
Thanks for reporting an interesting experiment, @moose4lord In your code autocal4 and in my testSlowClockAutocalib3, The calibration value rtcClkPeriodCalib is the product of two parameters: I don't know if the source of the RTC clock (8.5MHz/256) is a crystal or an oscillator, but the RTC frequency changes depending on the environment. By the way, regarding the external crystal, what I used before was not a crystal, but an external RTC called DS3234s. Although it is highly accurate and can be battery backuped, it is not recommended because it is more expensive than ESP32. I wish moose4lord the best of luck with the project and will help if I can. |
Hi! The fix below that we have right now (not merged yet) helps to fix it but it rises consumption in the deep sleep from 4-5uA to 13uA. diff --git a/components/esp_hw_support/port/esp32/rtc_sleep.c b/components/esp_hw_support/port/esp32/rtc_sleep.c
index de16b48d38bbbf1bef1cb06d204a76c1472594b2..5321a1e888eec5f84b6a4a80e526b4f576035ece 100644
--- a/components/esp_hw_support/port/esp32/rtc_sleep.c
+++ b/components/esp_hw_support/port/esp32/rtc_sleep.c
@@ -108,11 +108,13 @@ void rtc_sleep_get_default_config(uint32_t sleep_flags, rtc_sleep_config_t *out_
out_config->dig_dbias_slp = RTC_CNTL_DBIAS_0V90;
out_config->rtc_dbias_wak = RTC_CNTL_DBIAS_1V10;
out_config->rtc_dbias_slp = RTC_CNTL_DBIAS_0V90;
+ out_config->dbg_atten = !(sleep_flags & RTC_SLEEP_PD_INT_8M) ? RTC_CNTL_DBG_ATTEN_NODROP : RTC_CNTL_DBG_ATTEN_DEFAULT;
} else {
out_config->dig_dbias_wak = RTC_CNTL_DBIAS_1V10;
out_config->dig_dbias_slp = !((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? RTC_CNTL_DBIAS_1V10 : RTC_CNTL_DBIAS_0V90;
out_config->rtc_dbias_wak = RTC_CNTL_DBIAS_1V10;
out_config->rtc_dbias_slp = !((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? RTC_CNTL_DBIAS_1V10 : RTC_CNTL_DBIAS_0V90;
+ out_config->dbg_atten = RTC_CNTL_DBG_ATTEN_NODROP;
}
}
@@ -207,7 +209,6 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PU);
} else {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN);
- REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN, 0);
}
REG_SET_FIELD(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_XTL_FORCE_PU, cfg.xtal_fpu);
@@ -226,6 +227,7 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DBIAS_WAK, cfg.rtc_dbias_wak);
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, cfg.dig_dbias_wak);
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_SLP, cfg.dig_dbias_slp);
+ REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN, cfg.dbg_atten);
REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_DEEP_SLP_REJECT_EN, cfg.deep_slp_reject);
REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_LIGHT_SLP_REJECT_EN, cfg.light_slp_reject);
diff --git a/components/soc/esp32/include/soc/rtc.h b/components/soc/esp32/include/soc/rtc.h
index aa2b6f7fc99a30ab99dc7ef94c27c424204b7f59..338c464ff15eda50b9e419386312785b1ca7f650 100644
--- a/components/soc/esp32/include/soc/rtc.h
+++ b/components/soc/esp32/include/soc/rtc.h
@@ -502,6 +502,7 @@ typedef struct rtc_sleep_config_s {
uint32_t xtal_fpu : 1; //!< keep main XTAL powered up in sleep
uint32_t deep_slp_reject : 1; //!< enable deep sleep reject
uint32_t light_slp_reject : 1; //!< enable light sleep reject
+ uint32_t dbg_atten : 2; //!< voltage parameter
} rtc_sleep_config_t;
#define RTC_SLEEP_PD_DIG BIT(0) //!< Deep sleep (power down digital domain)
diff --git a/components/soc/esp32/include/soc/rtc_cntl_reg.h b/components/soc/esp32/include/soc/rtc_cntl_reg.h
index aec51adf6a4bea61b8b6dc14305631391a06a346..edb7553f20120b88ef58ea78945ea5a7ce4ea6ae 100644
--- a/components/soc/esp32/include/soc/rtc_cntl_reg.h
+++ b/components/soc/esp32/include/soc/rtc_cntl_reg.h
@@ -1067,6 +1067,8 @@
#define RTC_CNTL_DBG_ATTEN_V 0x3
#define RTC_CNTL_DBG_ATTEN_S 24
#define RTC_CNTL_DBG_ATTEN_DEFAULT 3
+#define RTC_CNTL_DBG_ATTEN_NODROP 0
+
#define RTC_CNTL_REG (DR_REG_RTCCNTL_BASE + 0x7c)
/* RTC_CNTL_FORCE_PU : R/W ;bitpos:[31] ;default: 1'd1 ; */
/*description: RTC_REG force power up*/ cc @lennyJL Note. This is not the final version of this fix. |
…lock on ESP32 Related to: #6687
Is this power consumption implact only when RTC_CLK_SRC_INT_8MD256=y ? |
@KonstantinKondrashov I cannot find this fix in any stable branches. |
@AxelLin For this fix, Yes. |
This fix has been merged into the master branch, but not yet backported. Still need to wait. |
…lock on ESP32 Related to: #6687
…lock on ESP32 Related to: #6687
…lock on ESP32 Related to: #6687
Thanks for reporting, feel free to reopen. |
Environment
Problem Description
The ESP32's time is not accurate.After five minutes of deepsleep, the time was more than some seconds behind the actual time.
Do you have any idea about this? how should i do to fix this problem?
Debug Logs
I recorded the print time of the log.
The text was updated successfully, but these errors were encountered: