logo elektroda
logo elektroda
X
logo elektroda

ESP8266 connecting to the network after ESP.deepSleepInstant() command

Zubiik 2058 19
Best answers

How can I make an ESP8266 reconnect to Wi‑Fi/network after using ESP.deepSleepInstant() to minimize wake-up current?

Call `WiFi.mode(WIFI_SHUTDOWN)` before entering `ESP.deepSleepInstant()`, because `deepSleepInstant()` puts the chip to sleep immediately and does not wait for Wi‑Fi to shut down first [#19349251] The thread’s author confirmed that with this change the ESP resumed normal operation after sleep and could connect/send again; `ESP.deepSleep()` also behaved the same in this case [#19349328]
Generated by the language model.
ADVERTISEMENT
Treść została przetłumaczona polish » english Zobacz oryginalną wersję tematu
  • #1 19348836
    Zubiik
    Level 15  
    Hi. Looking to get my module working on batteries, I decided to use the espNow functionality and deepSleep. And now I'm experimenting with different ways of putting the microcontroller to sleep, it turns out that probably the least current-consuming mode is
    Code: C / C++
    Log in, to see the code
    It allows the maximum reduction of time and current consumption during restarting as you can see on the attached oscillogram
    ESP8266 connecting to the network after ESP.deepSleepInstant() command The problem is that I don't know how I can connect to the network after such a sleep. At the moment, part of the setup(); function looks like this
    Code: C / C++
    Log in, to see the code


    Putting the esp to sleep in
    Code: C / C++
    Log in, to see the code
    mode causes the module to connect to the slave esp_now however this time is already ~300ms
  • ADVERTISEMENT
  • Helpful post
    #2 19349251
    Anonymous
    Level 1  
  • #3 19349328
    Zubiik
    Level 15  
    khoam wrote:
    Does this mean that esp_now_init() returns a code different from zero?
    I haven't actually checked this.
    khoam wrote:
    Try calling WiFi.mode(WIFI_SHUTDOWN) before calling deepSleepInstant().
    You are a master :) regardless of whether I call ESP.deepSleepInstant() or ESP.deepSleep(); ESP resumes transmitting after sleep. Another mAh saved. The last bottleneck in my application is the BME280 which initialises in about 100ms. Anyway, now from waking up by reading the BME and sending it via esp_now (great stuff by the way, and I've seen practically no examples with this protocol on the Polish web) it takes 300ms with the biggest current draw of 60mA taking only 100ms. HUGE thanks!
    ESP8266 connecting to the network after ESP.deepSleepInstant() command .
  • #4 19349564
    Anonymous
    Level 1  
  • #5 19349615
    Zubiik
    Level 15  
    khoam wrote:
    Actually, I'm not surprised. Imagine that in the code of the Adafruit_BME280::init() function, a delay(100) command is inserted at the very end. I have no idea why
    .
    And it's a shambles :/ interestingly I tried to get around this delay because from the waveforms it seemed that after 15ms the BME was ready to work i.e. the last frame was sent to it after that time. However, trying to read earlier than the begin() function finished was not giving correct results. I don't want to duplicate posts because I also asked about solving this problem on forbot. There I described in more detail what and how https://forbot.pl/forum/topic/19799-bme280-dl...as-inicjalizacji/?tab=comments#comment-161442
    And so I thought there must be something wrong with this lib from Adafruit because it's impossible that such a chip takes so long to start.
  • ADVERTISEMENT
  • Helpful post
    #6 19349632
    Anonymous
    Level 1  
  • #7 19349640
    Zubiik
    Level 15  
    khoam wrote:
    Fast you can change this delay(100) to e.g. delay(10) and check that it initialises correctly. This is in the library file Adafruit_BME280.cpp, around line 135.
    That's how I was combining it too. The problem is that a while ago I messed up the last ESP that receives data and sends to the server, I will see via uart what happens after modifying the libs.

    Added after 12 [minutes]: .

    khoam wrote:
    There is no I2C hardware controller on the ESP8266, so that 400 kHz is a pipe dream
    .
    I just combined as much as possible to make the esp work as short as possible. I don't want to make excuses ...
    ESP8266 connecting to the network after ESP.deepSleepInstant() command .
    This is the SCL line ;) although probably if the esp was loaded more then the sampling would probably drop below 100kHz

    Added after 44 [minutes]:

    So I checked this delay in the functions from BME. Unfortunately any delay other than 100ms in the while loop (isReadingCalibration()); returns the result of the nan measurement, which is not a number in float encoding.
    I will check later this library from bosch
  • #8 19349804
    Anonymous
    Level 1  
  • ADVERTISEMENT
  • #9 19349810
    Zubiik
    Level 15  
    khoam wrote:
    I didn't mean delay() in the while loop (isReadingCalibration()), but it's at the end of the Adafruit_BME280::init()
    Well understood that delay I was changing, fact it's not in the loop, my mistake.
  • Helpful post
    #10 19349838
    Anonymous
    Level 1  
  • #11 19350960
    Zubiik
    Level 15  
    OK I took this library from sparkfun, and now about 233ms elapses from reset to ESP sleep. This includes 100ms for start up and 40ms for measuring and sending data, where the current peak is 93mA in 10ms. Unfortunately I am not able to determine if the data is being sent correctly because as I wrote before, yesterday I fried myself an ESP that was working as a slave, tomorrow it will be new. I think that these results are very good, I intend to take measurements once every 10...15 minutes so the battery must last for a year (although I haven't counted it exactly yet), especially that the data will be sent only if the values of the new measurement are different from the values of the previous measurement,for this I will use the RTC memory.
  • ADVERTISEMENT
  • #12 19353095
    Zubiik
    Level 15  
    So it works. No problem connecting to the slave, nor does the slave make problems when connecting to the network when you need to send data. I am impressed how low the power consumption of these esps can go. I think they can compete with NRF chips. Oddly enough, I could only find one topic about espNow on the internet, hmm why not post something about it in the future? To conclude this offtopic, I would like to share my results. As far as the oscilloscope measured it correctly, with all the measuring and sending it came out 7mAs, sometimes it is a bit less sometimes more.
    ESP8266 connecting to the network after ESP.deepSleepInstant() command .
  • #13 19353109
    Anonymous
    Level 1  
  • #14 19353143
    Zubiik
    Level 15  
    khoam wrote:
    But if you are happy with the results ....
    Haha meaning I know what to do :) I'm running on esp 07 the one with the ceramic antenna, I blew the leds right away, same in the BME module the 3.3V stabiliser. BME is in FORCE mode. At the moment I still want to polish the code so that it doesn't send data when the last measurement is the same as the current one. Well, and generally do some tidying up. The esp12E works as a slave
  • #15 19357162
    krzbor
    Level 29  
    In order to save energy, we usually use deep-sleep. ESP has another interesting CH_PD pinout offering even lower power consumption. Of course there is the problem of wake-up, but if we have an RTC, it is worth thinking about a circuit with an alarm. Such a circuit can periodically wake everything up.
  • #16 19357560
    Zubiik
    Level 15  
    As far as I understood the documentation, when ch_pd is in low state, even rtc doesn't work. Yes, it is possible to combine with additional microcontroller e.g. attiny4 or similar, which would control this leg. This was on my mind when I was trying to do this project, but after trying Deep sleep I decided that this function meets my expectations.
  • #17 19357931
    Anonymous
    Level 1  
  • #18 19358368
    krzbor
    Level 29  
    You wrote RTC. I thought you meant a "real" RTC e.g. type DS1337. Otherwise my statement makes no sense :) .
  • #19 19358620
    Zubiik
    Level 15  
    krzbor wrote:
    I thought you meant the "real" RTC
    Well I didn't specify also cool. One other thought occurs to me.... If you look at these oscillograms you can see that the microcontroller itself takes about 80ms to start. I guess that's how long it takes to start oscillator and stabilize PLL, couldn't it be somehow speeded up?
  • #20 19358628
    Anonymous
    Level 1  

Topic summary

✨ The discussion revolves around optimizing the ESP8266 microcontroller for battery operation using ESP.deepSleepInstant() and ESP-NOW functionality. The user seeks to minimize power consumption while ensuring reliable network connectivity after waking from deep sleep. Key suggestions include using WiFi.mode(WIFI_SHUTDOWN) before deep sleep to manage power effectively and exploring alternative libraries for the BME280 sensor to reduce initialization delays. The conversation highlights the importance of minimizing delays in sensor initialization and data transmission to achieve low power consumption, with successful results reported in terms of current draw and operational efficiency. The user also considers using RTC memory to store sensor states to further enhance performance.
Generated by the language model.

FAQ

TL;DR: On ESP8266 + ESP‑NOW, expect ~300 ms wake‑to‑send; "ESP resumes transmitting after sleep." Configure deep sleep and wake sequence correctly to reconnect fast and save mAh. This FAQ distills working steps for battery‑powered ESP8266 builders, plus sensor tips and pitfalls. [Elektroda, Zubiik, post #19349328]

Why it matters: Battery IoT nodes need fast, reliable wake cycles to save energy without dropping packets.

Quick Facts

How do I reconnect ESP‑NOW quickly after ESP.deepSleepInstant()?

Use WiFi.mode(WIFI_SHUTDOWN) before ESP.deepSleepInstant(). It cleanly turns Wi‑Fi off. On wake, set station mode, init ESP‑NOW, and add your peer on the known channel. “Try calling WiFi.mode(WIFI_SHUTDOWN) before calling deepSleepInstant().” How‑To: 1. WiFi.mode(WIFI_SHUTDOWN); ESP.deepSleepInstant(...). 2. After wake: WiFi.mode(WIFI_STA); esp_now_init(). 3. esp_now_add_peer(..., WIFI_CHANNEL, ...), then send. [Elektroda, khoam, post #19349251]

What wake‑to‑send time should I expect with ESP‑NOW?

Real measurements showed about 300 ms from wake to reading BME280 and sending via ESP‑NOW. The largest current draw was around 60 mA for 100 ms. With correct setup, sub‑second cycles are achievable on batteries. [Elektroda, Zubiik, post #19349328]

How can I reduce BME280 initialization time on ESP8266?

Use the SparkFun BME280 library instead of Adafruit’s. One build measured about 233 ms from reset to sleeping again after switching. Keep the sensor in forced mode and take one sample per wake to minimize time active. [Elektroda, Zubiik, post #19350960]

Why does Adafruit_BME280 init wait 100 ms, and can I change it?

Adafruit_BME280::init() ends with delay(100), which adds startup latency. You can try reducing that delay and validate readings. Or switch to a driver without that pause. “You can change this delay(100) to e.g. delay(10) and check that it initialises correctly.” [Elektroda, khoam, post #19349632]

I get NaN from BME280 when I reduce delays. What’s happening?

Changing timing in the calibration phase can break measurements and return NaN. Keep the calibration wait intact. If you reduce the final delay, test across many wakes to ensure stability. Consider an alternative library if problems persist. [Elektroda, Zubiik, post #19349640]

Does ESP8266 really do 400 kHz I2C with BME280?

No. ESP8266 has no hardware I2C; Wire is bit‑banged. Fast‑mode 400 kHz is unreliable. Use conservative speeds that your code and sensor can sustain. “There is no I2C hardware controller on the ESP8266, so 400 kHz is a pipe dream.” [Elektroda, khoam, post #19349632]

Does WiFi.setOutputPower(0) reduce reconnection time?

Tests showed it did not change timing. It lowered instantaneous RF power and current instead. Keep it for energy or emission limits, but do not expect faster wake‑to‑send. [Elektroda, Zubiik, post #19348836]

Should I use WAKE_NO_RFCAL to speed up wake?

Yes, when your channel is fixed. Using ESP.deepSleep(..., WAKE_NO_RFCAL) enabled quick ESP‑NOW reconnection, with about 300 ms total time observed. Skipping RF calibration trims wake overhead. [Elektroda, Zubiik, post #19348836]

Can I beat deep‑sleep current by pulling CHIP_EN (CH_PD) low instead?

Yes. Pulling CHIP_EN low powers the ESP8266 off even more than deep‑sleep. You will need an external RTC or alarm circuit to wake it periodically by toggling enable or reset. [Elektroda, krzbor, post #19357162]

What happens to RTC memory if CHIP_EN is low?

CHIP_EN low removes power from the whole chip. RTC memory does not retain contents in this state. Do not rely on RTC retention when power‑gating via CHIP_EN. [Elektroda, khoam, post #19357931]

Why does boot after wake take ~80 ms before my code runs?

Startup time includes the boot ROM “spitting out diagnostic information on the UART.” Disabling it requires rebuilding Arduino Core and the underlying NonOS SDK. Plan this fixed overhead into your energy budget. [Elektroda, khoam, post #19358628]

How do I persist state across deep sleep to skip sensor init?

Use RTC memory to store minimal state, such as last readings or init flags. After wake, replay configuration and skip full driver initialization when safe. This can further shorten active time. [Elektroda, khoam, post #19353109]

How do I estimate battery life for periodic ESP‑NOW sensor packets?

Start with measured energy per cycle. One build observed roughly 7 mAs per read+send. Multiply by wake frequency to budget capacity. Validate your math with new measurements after each change. [Elektroda, Zubiik, post #19353095]

What Wi‑Fi mode should I set before ESP‑NOW init?

Use WiFi.mode(WIFI_STA) at startup. It did not change timing in tests, and leaving station mode enabled kept ESP‑NOW working correctly. Then initialize ESP‑NOW and add peers. [Elektroda, Zubiik, post #19348836]

esp_now_init() returns non‑zero after wake; how can I fix it?

A non‑zero return means initialization failed. Shut Wi‑Fi down before sleeping, then reinitialize on wake. “Try calling WiFi.mode(WIFI_SHUTDOWN) before calling deepSleepInstant().” Verify you add the peer on the correct channel and retry if needed. [Elektroda, khoam, post #19349251]
Generated by the language model.
ADVERTISEMENT