-
Notifications
You must be signed in to change notification settings - Fork 13.3k
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
light sleep mode & WiFi & millis() overflow #8913
Comments
since millis() and last_sent are unsigned, the result of the subtraction is right even if millis() overflows and is less then last_sent |
I agree, this is not a dead lock. It will timeout too early. I've reproduced the issue 3 times already but I'm still trying to understand what happen, I'm trying to collect more information. I don't know if the library is doing something like below, I write this just as an example to highlight the concerns:
Or the issue is maybe because I call the native ESP SDK. And it is preventing the Arduino ESP8266 library WiFi class to work properly. Edit:
Issue occurs after approximately 3h55 real up time, corresponding to 1h24 ESP up time (remember clock is idle in light sleep mode) |
no. it will timeout exactly as it should |
You can try this code,
The output:
|
the test is not right because |
I don't see what you mean, Any idea regarding the Wifi that does not connect after 4 hours ? |
sorry, now I get it. If millis() don't use the full bit width of the data type, then the subtraction 'trick' doesn't work. This is bad. CC: @d-a-v |
Yes :) Exactly, millis() doesn't use the full bit width of the data type. And also, millis() does not count time when the chip is in light sleep mode. |
You stop the overflow handler, so works as expected? :) Arduino/cores/esp8266/core_esp8266_wiring.cpp Line 198 in ad9aaef
From memory, forced sleep just does not work properly? It does something like this
What does not seem to work is the 'run cpu sleep' part. edit2: there is also #7979 that helps out with sleep funcs. does the same thing with timers list, though. but, suppose restoring it right ater may somehow make it tick again |
Did anyone check out #7979 and test this issue again based on it? |
Hum, that's one Voodoo thing someone mentioned to do on the Internet, so I did...
Do you mean that if I restore the pointer then I will get the full 32 bits in millis() ? I'll give it a try. I'm not sure yet how #6318 can help, it talks a lot about Deep Sleep.
They say also that the clock is still running for a few ms or us (and someone even suspected that the clock is still running but at a very lower frequency). Looking at the documentation; But I suspect that the ESP SDK documentation is not accurate when they talk about the "idle task" in RTOS SDK has an idle task indeed but, I am not aware that NON-OS SDK has an idle task. So maybe some yield or I don't know what is triggering the final go_to_sleep.
I'm not sure if you mean this : I fixed it like this, so esp_delay does not yields to system for the given duration,
Regarding #7979, |
What do you mean by "the current" library? #7979 gives you |
The library we get by adding the Board Manager, https://arduino.esp8266.com/stable/package_esp8266com_index.json version 3.1.2. |
@Bruno-Muller The Board Manager selects BSPs, a.k.a. Arduino cores - not libraries :-) Possible approach: clone https://github.com/dok-net/arduino-esp8266.git to your /hardware/esp8266com/esp8266 directory, checkout the |
Our questions about SDK currently can only be answered by reading disassembly ourselves or using some prior developments. No need to guess or believe without question any random voodoo from the internet :) My point is light sleep as implemented in NONOS does not really look that useful. Disabling existing timers still adds yet another one through the use of our delay() call, which returns us to the user task after expiring. System time is still ticking forward, timer callbacks can and will be executed, we can even re-enter user task unless explicitly blocking via something like |
Hi, I need to update the status on this, (I haven't touched my project during 1 year, waiting for library updates and bug fixes) Wifi disconnectionHaving updated all the libraries, and changed my WiFi access point. Light Sleep ModeMy workaround to use Light Sleep Mode is functional. However, offering the option to set the sleep mode to millis() functionAnd there is a lack of shared knowledge about millis() not using the full 32 bits. However, the ESP8266 Arduino Library implementation does not meet the official Arduino library reference. regarding the overflow of millis(). |
Hi,
Issue:
WiFi stops working after a few hours when using the light sleep mode.
Description:
I am not sure if the Arduino library is doing well with the time drifting caused by the Light Sleep Mode because the clock is idle. And if the millis() overflow can cause any dead lock issue in the timeout condition to exit loops.
I'm not an expert, I suspect that the WiFi API does not renew and negotiate some WiFi token in a timely manner because millis() is not a good time indicator when we use the light sleep mode.
Steps to reproduce:
Periodically put the ESP8266 in light sleep mode.
Here in my tests, the wake time is around 5s, and sleep time is around 15s.
In setup():
Go to light sleep and wake up functions:
Analysis:
I notice that millis() function is badly understood on the internet, and a lot of people assume that it is 2^32 ms (i.e. 49.7 days) overflow.
I did some measurement and it is clear that millis() expires after 2^32/1000 ms (i.e. 2^32 us, or 71.6 min).
In addition to this, I notice in Arduino ESP8266 library source code that the code is compensating some clock drifting (maybe 826us per some amount of time, I don't recall exactly).
I am not sure that the clock drifting compensation or the overflow can cause side effects on the timeout while loops or exit condition used in the library.
For example, the following line is from the WiFi API, if millis() is less than last_sent, then it could lead to unexpected behavior.
if (millis() - last_sent > (uint32_t) max_wait_ms) {...}
I also noticed that the light sleep mode is badly understood as well. I've seen people measuring current with an oscilloscope and do some arithmancy, trying to guess if light sleep mode works or not, and doing assumption on how it has to be done, with no good reasons.......
Or maybe Google just does not help to find the reliable information lost somewhere on the Internet.
Well, by looking at the source code of Arduino ESP8266 Library source code and the official documentation of ESP 8266, I found out a workable solution to use the light sleep mode (mentioned above).
As a consequence, because the clock is idle during light sleep mode, the millis() function cannot be used to measure the time anymore.
I wonder if millis() is the time source in the WiFi API to trigger the renegotiation of some WiFi token.
That could explain why the wifi stops working.
The text was updated successfully, but these errors were encountered: