Skip to content
Closed
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a4d59d4
To support powersaving mode with lightsleep at 9mA
IoTThinks Nov 16, 2025
2d9077b
To support lightsleep
IoTThinks Nov 16, 2025
6988834
To support powersaving mode with lightsleep at 9mA
IoTThinks Nov 16, 2025
9e9b280
To support powersaving mode with lightsleep at 9mA
IoTThinks Nov 16, 2025
c16102b
To support powersaving mode with lightsleep at 9mA
IoTThinks Nov 16, 2025
d0c342f
To support powersaving mode with lightsleep at 9mA
IoTThinks Nov 16, 2025
1f9806c
To support powersaving mode with lightsleep at 9mA
IoTThinks Nov 16, 2025
b54028e
To awake for 2 minutes in first boot / restart to support Repeater se…
IoTThinks Nov 19, 2025
0e77f9e
Modify sleep duration and wake-up behavior
IoTThinks Nov 22, 2025
56df774
Modify sleep method to accept seconds parameter
IoTThinks Nov 22, 2025
3599a26
Modify sleep function to take seconds as parameter
IoTThinks Nov 22, 2025
c33cd2b
Modify sleep function to accept duration parameter
IoTThinks Nov 22, 2025
d86f596
Modify sleep function to accept duration parameter
IoTThinks Nov 22, 2025
d8954fa
Refactor HeltecV3Board: Remove light sleep methods
IoTThinks Nov 24, 2025
adae43b
Remove light sleep functions
IoTThinks Nov 24, 2025
745566e
Refactor HeltecV4Board by removing light sleep methods
IoTThinks Nov 24, 2025
e636996
Implement light sleep and sleep methods
IoTThinks Nov 24, 2025
f94412b
Enable power saving mode in platformio.ini
IoTThinks Nov 24, 2025
97d7eeb
To support ESP32S3 and validate RTC GPIO
IoTThinks Nov 30, 2025
822c249
Disable powersaving mode in platformio.ini
IoTThinks Nov 30, 2025
20ab10f
To get the current pending outbound packets at Dispatcher
IoTThinks Dec 5, 2025
acee014
To get the current pending outbound packets at Dispatcher
IoTThinks Dec 5, 2025
b97fb20
To postpone sleep to further 5s if there is pending outbound
IoTThinks Dec 5, 2025
dd18ae7
Renamed getOutboundCount in MyMesh to hasPendingWork()
IoTThinks Dec 22, 2025
4bc4d5a
Merge branch 'dev' into dev
IoTThinks Dec 22, 2025
79be9ca
Update src/helpers/ESP32Board.h
IoTThinks Dec 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions examples/simple_repeater/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ void halt() {

static char command[160];

#ifdef POWERSAVING_MODE
unsigned long lastActive = millis(); // mark last active time
Comment thread
IoTThinks marked this conversation as resolved.
Outdated
unsigned long nextSleepinSecs = 120; // next sleep in seconds. First time is 2m to send advert and do repeater setup.
#endif

void setup() {
Serial.begin(115200);
delay(1000);
Expand Down Expand Up @@ -117,4 +122,12 @@ void loop() {
ui_task.loop();
#endif
rtc_clock.tick();

#ifdef POWERSAVING_MODE
if (millis() - lastActive > nextSleepinSecs * 1000) {
Comment thread
IoTThinks marked this conversation as resolved.
Outdated
board.sleep(1800); // To sleep. Wake up after 30 minutes or when receiving a LoRa packet
lastActive = millis();
nextSleepinSecs = 5; // Default: To work for 5s and sleep again
}
#endif
}
3 changes: 2 additions & 1 deletion src/MeshCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class MainBoard {
virtual void onAfterTransmit() { }
virtual void reboot() = 0;
virtual void powerOff() { /* no op */ }
virtual void sleep(uint32_t secs) { /* no op */ }
virtual uint32_t getGpio() { return 0; }
virtual void setGpio(uint32_t values) {}
virtual uint8_t getStartupReason() const = 0;
Expand Down Expand Up @@ -86,4 +87,4 @@ class RTCClock {
}
};

}
}
20 changes: 20 additions & 0 deletions src/helpers/ESP32Board.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <rom/rtc.h>
#include <sys/time.h>
#include <Wire.h>
#include <WiFi.h>

class ESP32Board : public mesh::MainBoard {
protected:
Expand Down Expand Up @@ -42,6 +43,23 @@ class ESP32Board : public mesh::MainBoard {
#endif
}

void enterLightSleep (uint32_t secs) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A better solution would be to use the GPIO wakeup source

GPIO Wakeup (Light-sleep Only)
In addition to EXT0 and EXT1 wakeup sources described above, one more method of wakeup from external inputs is available in Light-sleep mode. With this wakeup source, each pin can be individually configured to trigger wakeup on high or low level using gpio_wakeup_enable() function. Unlike EXT0 and EXT1 wakeup sources, which can only be used with RTC IOs, this wakeup source can be used with any IO (RTC or digital).

Should be like this

void enterLightSleep(uint32_t s){
  pinMode(P_LORA_DIO_1,INPUT);
  esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
  gpio_wakeup_enable((gpio_num_t)P_LORA_DIO_1,GPIO_INTR_HIGH_LEVEL);
  esp_sleep_enable_gpio_wakeup();
  if(s>0) esp_sleep_enable_timer_wakeup((uint64_t)s*1000000ULL);
  esp_light_sleep_start();
}

void sleep(uint32_t s) override {
  if(WiFi.getMode()==WIFI_MODE_NULL) enterLightSleep(s);
}

Then at the top you gotta add.

#include "esp_sleep.h"
#include "driver/gpio.h"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zjs81 I see.
There are some boards with bad design to use non RTC pins as wakeup pins.
For now, which boards are they in MeshCore's supported boards?

These boards will have issues if required to deepsleep as the wakeup pins without PULL UP/DOWN will be floating in deepsleep.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zjs81 Let me use and test your GPIO wakeup to maximize the compability for any ESP32-based board.
Thanks a lot. 👯

@IoTThinks IoTThinks Nov 29, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zjs81 I tested.
The wakeup via GPIO will not work for DIO1 of sx1262.

Dio1 of sx1262 will have short rising HIGH.
GPIO wake up may trigger many times and crash esp32 when trying to wakeup.
Let me see if any work around.

In my experience, I always use ext0 and ext1 for dio1 of sx1262.

esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // To wake up when receiving a LoRa packet

if (secs > 0) {
esp_sleep_enable_timer_wakeup(secs * 1000000); // To wake up every hour to do periodically jobs
}

esp_light_sleep_start(); // CPU enters light sleep
}

void sleep(uint32_t secs) override {
if (WiFi.getMode() == WIFI_MODE_NULL) { // WiFi is off ~ No active OTA, safe to go to sleep
enterLightSleep(secs); // To wake up after "secs" seconds or when receiving a LoRa packet
}
}

uint8_t getStartupReason() const override { return startup_reason; }

#if defined(P_LORA_TX_LED)
Expand Down Expand Up @@ -78,6 +96,8 @@ class ESP32Board : public mesh::MainBoard {
#endif
}



Comment thread
IoTThinks marked this conversation as resolved.
Outdated
const char* getManufacturerName() const override {
return "Generic ESP32";
}
Expand Down
1 change: 1 addition & 0 deletions variants/heltec_v3/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ build_flags =
-D MAX_NEIGHBOURS=50
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
-D POWERSAVING_MODE=1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really like the fact that we are enabling this for specific boards only. I know this can be rolled out to other boards later, but it will likely be confusing for some users if some boards show a different behavior than others (for example CLI accessibility after the initial 2 minute period).

@IoTThinks IoTThinks Dec 22, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, we will have power saving to all boards soon by default. All will have the same powersaving behaviors.
However due to large user base of MeshCore, we would like to see the impact of the change to Heltec v3/v4 first.

build_src_filter = ${Heltec_lora32_v3.build_src_filter}
+<helpers/ui/SSD1306Display.cpp>
+<../examples/simple_repeater>
Expand Down
1 change: 1 addition & 0 deletions variants/heltec_v4/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ build_flags =
-D MAX_NEIGHBOURS=50
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
-D POWERSAVING_MODE=1
build_src_filter = ${Heltec_lora32_v4.build_src_filter}
+<helpers/ui/SSD1306Display.cpp>
+<../examples/simple_repeater>
Expand Down
1 change: 1 addition & 0 deletions variants/xiao_s3_wio/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ build_flags =
-D MAX_NEIGHBOURS=50
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
-D POWERSAVING_MODE=1
lib_deps =
${Xiao_S3_WIO.lib_deps}
${esp32_ota.lib_deps}
Expand Down