Closed rin67630 closed 6 years ago
Word on the street is that the internal RTC runs slow, but this seems to handle what you are looking for:
#include <WiFi.h>
#define NTP_SERVER "us.pool.ntp.org"
#define TZ_INFO "MST7MDT6,M3.2.0/02:00:00,M11.1.0/02:00:00" // Americas/Denver
#define SLEEPTIME 1E7 //microseconds
void initFirst() {
#ifdef MYSSID
WiFi.begin(MYSSID,PASSWD);
#else
WiFi.begin();
#endif
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
delay(200);
Serial.println(WiFi.localIP());
struct tm local;
getLocalTime(&local, 10000); // wait up to 10sec to sync
}
void setup() {
Serial.begin(115200);
configTzTime(TZ_INFO, NTP_SERVER);
esp_sleep_wakeup_cause_t wakeup_cause;
wakeup_cause = esp_sleep_get_wakeup_cause();
Serial.println(wakeup_cause);
if (wakeup_cause != 3) initFirst();
}
void loop() {
tm local;
getLocalTime(&local);
Serial.println(&local, "Time set: %B %d %Y %H:%M:%S (%A)");
Serial.println("Entering sleep");
esp_sleep_enable_timer_wakeup(SLEEPTIME);
esp_deep_sleep_start();
}
Thank you for your example. it however prints the time only once after sync, not after deep-sleep
ets Jun 8 2016 00:22:57
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:812
load:0x40078000,len:0
load:0x40078000,len:11404
entry 0x40078a28
0
.........192.168.178.26
Time set: April 05 2018 02:34:56 (Thursday)
Entering sleep
ets Jun 8 2016 00:22:57
rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:812
load:0x40078000,len:0
load:0x40078000,len:11404
entry 0x40078a28
3
ets Jun 8 2016 00:22:57
rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:812
load:0x40078000,len:0
load:0x40078000,len:11404
entry 0x40078a28
3
ets Jun 8 2016 00:22:57
Maybe you need a short delay b/w the printlns and the sleep command, but you should at least get the first couple characters into the buffer before it passes out. It works perfectly on my Heltec wifi kit based board.
@rin67630 What RTC?
The deepsleep function just adds the specified sleep time to the milliseconds counter?
Chuck
@stickbreaker
The deepsleep function just adds the specified sleep time to the milliseconds counter? I don't know the details, the ESP32 Specs do mention a built in RTC. The time is kept current and the ESP returns with the correct time set after a deep sleep, that's what matters.
With the correct coding the time-zone can be reactivated after a deep sleep. So it was just a matter of documentation. Sorry for the inconvenience.
@rin67630 - I saw you closed with the comment using the correct coding it worked, but I am facing exactly the same problem you described. In my setup function I am when starting first time after reset getting the current time with: configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); both offsets are 3600 I am then using getLocalTime(&timeinfo); to read the time and dispaly the time. Everything works fine and then go to deep sleep touchAttachInterrupt(T0, callback, Threshold);
//Configure Touchpad as wakeup source esp_sleep_enable_touchpad_wakeup();
after wake up with touching T0 I come again in my setup there I run the following code if (bootCount++ > 0) { if(!getLocalTime(&timeinfo)){ DPRINTLN("Failed to obtain time"); } else { DPRINT(timeinfo.tm_hour); DPRINT(":"); DPRINTLN(timeinfo.tm_min); ShowTime(timeinfo.tm_hour,timeinfo.tm_min); } }
bootCount is an RTC variable, so this part of the code is only executed after wakeup from deep sleep, meaning the time has been already set by NTP.
However, after deepsleep I am getting an hour earlier (currently no DST and I am in Austria). So seems that the tiomezone settings got lost. My question to @rin67630 - what did you change in your code that timezone corrections did work after deep sleep ?
Just to document this for anyone else looking in the future (as was I when trying to get NTP time working in conjunction with the RTC and deepsleep)... it's possible the change in code was in relation to how the timezone was set.... instead of
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
I use
configTime(0, 0, ntpServer);
// TZ string information: https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
setenv("TZ", "AEST-10", 1);
tzset(); // save the TZ variable
and it works just fine now. Don't forget to repeat the last two lines in the section of your code that DOESN'T enable the wifi & do the NTP lookup, or at least make sure it always runs, else you'll retrieve the un-timezone-corrected time/date ;) Not that I know from experience! 😂😂
I have been able to use configTzTime(TZ_INFO, NTP_SERVER);
instead of the above three statements, but I find it only works for the initial lookup - if the wifi has not connected, the ESP32 resets.
@pfeerick, thank you for "just documenting", solved my problem.
@pfeerick do you have a link to documentation about setenv ? Does the parameter "TZ" only specify the format that is used for the timezone configuration? What does the "1" do?
I don't know if this could be of help to anyone. Setting the time using mktime and settimeofday.
configTime(0, 0, "pool.ntp.org");
//configTime(3600, 0, "pool.ntp.org");
struct tm tm;
getLocalTime(&tm);
//tm.tm_hour = tm.tm_hour + 1;
time_t t = mktime(&tm);
//Serial.printf("Setting time: %s", asctime(&tm));
struct timeval now = { .tv_sec = t + 3600};
settimeofday(&now, NULL);
Hardware:
Board: ESP32 LoLin32 Core Installation/update date: Jun 8 2016 00:22:57 IDE name: Arduino IDE Flash Frequency: 40Mhz Upload Speed: 115200
Description:
The SimpleTime example is the only one that uses the RTC of the ESP32 and provides time beyond deep sleep. However after a deep sleep the time zone settings are lost.
Generally, the SimpleTime example lacks imho compatibilty with the other Arduino time libraries. now(); does not work, I could not find a workaround. second(); to year(); do not work, I found out that _timeinfo.tmsec to _timeinfo.tmyear contains the info as well, but having it the usual way would be nice.
Sketch:
Debug Messages, Serial Output: