firmware icon indicating copy to clipboard operation
firmware copied to clipboard

Showcase: reducing ESP32 power usage by 40% without sleeping

Open phaseloop opened this issue 2 weeks ago • 1 comments

Platform

ESP32

Description

With few bluetooth timing tweaks and migrating to ESP-IDF V5.5 we can cut ESP32 node power usage down to 60 mA and later to 50 mA with some FreeRTOS tweaks.

This requires migrating to pioarduino because PlatformIO refuses to support newer arduino-esp32 3.x versions and we are forced to use ancient and buggy ESP-IDF versions.

This is already done for C6 variants. Nothing crazy with adapting codebase to Arudino 3.x framework - mostly using different ADC mode for battery status.

I did an experiment on my branch with some quick migration hacks and BLE timing changes.

Result below - Heltec V3 before and after, BLE enabled and phone connected.

Image

Image

phaseloop avatar Dec 06 '25 12:12 phaseloop

Cool, what what exactly does this do differently to save so much power?

korbinianbauer avatar Dec 10 '25 12:12 korbinianbauer

Cool, what what exactly does this do differently to save so much power?

You need to ask to expressif , IDF is closed source

miky2k avatar Dec 16 '25 20:12 miky2k

Cool, what what exactly does this do differently to save so much power?

You need to ask to expressif , IDF is closed source

Ok, let me rephrase.

@phaseloop What exactly did you do to save so much power? Just use a newer IDF version and that's it? Or does the newer IDF version provide new/different functionality that you explicitly used?

korbinianbauer avatar Dec 16 '25 21:12 korbinianbauer

The firmware I uploaded had both IDF updated and BLE advertisement interval changed (from 50 ms I guess to around 300 ms) - frankly I'm not sure if this power saving is due to IDF or both changes. I did not investigate it further for now. I don't expect such drastic change to be only caused by interval change.

Changing advertisement interval did nothing on IDF v4 when it comes to power usage which was weird so I assumed there were some bugs with radio not sleeping during interval pauses - it seems I was right. Also IDFv5 and arduino 3.x framework allow to compile and enable "FreeRTOS tickless idle" which will allow to save power even more.

phaseloop avatar Dec 16 '25 21:12 phaseloop

Looks like I took a similar route, with similar incompatibilities discovered...

I just got my Heltec V4 working with current Espressif Toolstack via Pioarduino, dropped idle consumption from 110mA to 48mA

https://github.com/MartinEmrich/meshtastic-firmware/tree/heltec-v4-power/variants/esp32s3/heltec_v4_lp

For now, it does boot (yay), receive Meshtastic packets and the phone app works, so Bluetooth looks ok, too...

MartinEmrich avatar Dec 20 '25 16:12 MartinEmrich

For now, it does boot (yay), receive Meshtastic packets and the phone app works, so Bluetooth looks ok, too...

Wifi ?

miky2k avatar Dec 20 '25 16:12 miky2k

Wifi ?

Just tested, works as well. Idle usage is now jumping around at 130-150mA. I guess not only the Wifi stack consumes more cycles, but also a "ServerAPI" thread is waking up every 100ms.

MartinEmrich avatar Dec 20 '25 16:12 MartinEmrich

I remember we have all power savings in wifi disabled in meshtastic firmware for "performance", there is literally comment like that. I suppose this can be made "dynamic" - different settings if wifi is not connected or changing it if there is no data in some period of time, etc.

@MartinEmrich There is a discussion here https://github.com/meshtastic/firmware/issues/8896 about migrating to newer IDF and Arduino v3 framework - please share your work there too :)

We probably will need to use different package than pioarduino (tasmota) but I suppose there will be no real difference.

phaseloop avatar Dec 20 '25 16:12 phaseloop

Done.

I am quite new to Meshtastic, but what I gathered so far, mid-term Pioarduino seems to be the better way to go (If Arduino is set to stay as a common HAL/lower library across different MCU families for Meshtastic).

I don't know Tasmota, but it seems to be its own project (looks like an ESPHome alternative), where their fork of espressif32-arduino is likely to be tied to their specific needs.

Edit: Fun Fact, ESPHome actually uses pioarduino (https://github.com/platformio/platform-espressif32/issues/1225#issuecomment-2580542667, and I checked my esphome project), so I am using it for a while without knowing :)

MartinEmrich avatar Dec 20 '25 16:12 MartinEmrich

After following a little red herring, I also enabled DFS... idle now goes as low as 40mA.

In turn, the red herring was a recent commit changing lots of BLE related code, which broke BLE for me, I had to rebase to an earlier commit.

MartinEmrich avatar Dec 20 '25 19:12 MartinEmrich

The issue is that switching to pioarduino for esp32 forces developers and rest of project to use Pioarduino IDE instead of Platformio IDE and that breaks a lot of other things.

Yeah, "tasmota" is a different project but I was referring to their esp32/arduino platform repository. There should be no functional difference between tasmota platform-espressif32 and and pioarduino. I did a test with replacing one with another. On the contrary - my understanding is that tasmota repo is developed directly by Espressiff employees and what they do differently than official esp32-arduino (also by Espressif) is that you can use custom sdkconfig (like pioarduino).

Have you tried enabling soft_sleep=true when calling DFS setting? I tried to test it - by enabling FreeRTOS tickless idle during compilation but got stuck with other issues. I suppose getting this to work will bring down power usage even more.

phaseloop avatar Dec 20 '25 20:12 phaseloop