Skip to content
Closed
Show file tree
Hide file tree
Changes from 23 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
5 changes: 5 additions & 0 deletions examples/simple_repeater/MyMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1101,3 +1101,8 @@ void MyMesh::loop() {
uptime_millis += now - last_millis;
last_millis = now;
}

// To get the current pending outbound packets at Dispatcher
Comment thread
IoTThinks marked this conversation as resolved.
int MyMesh::getOutboundCount (uint32_t now) const {
return _mgr->getOutboundCount(0xFFFFFFFF);
Comment thread
IoTThinks marked this conversation as resolved.
}
3 changes: 3 additions & 0 deletions examples/simple_repeater/MyMesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,4 +225,7 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
bridge.begin();
}
#endif

// To get the current pending outbound packets at Dispatcher
int getOutboundCount (uint32_t now) const;
};
17 changes: 17 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,16 @@ 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
if(the_mesh.getOutboundCount(0xFFFFFFFF) == 0) { // Nothing more to send. Safe to sleep
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
} else {
nextSleepinSecs += 5; // To give 5 more seconds to send
}
}
#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 {
}
};

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

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

void enterLightSleep(uint32_t secs) {
#if defined(CONFIG_IDF_TARGET_ESP32S3) // Supported ESP32 variants
if (rtc_gpio_is_valid_gpio((gpio_num_t)P_LORA_DIO_1)) { // Only enter sleep mode if P_LORA_DIO_1 is RTC pin
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
}
#endif
}

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 +101,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