From 20fbf7aa734046cf33bbfb101dadd0d048757320 Mon Sep 17 00:00:00 2001 From: Frieder Schrempf Date: Tue, 16 Dec 2025 20:36:37 +0100 Subject: [PATCH 1/4] variants: RAK4631: Enable RF module reset pin There is no reason to not use the reset pin as the RAK4630/31 module has it connected internally. Signed-off-by: Frieder Schrempf --- variants/rak4631/RAK4631Board.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/variants/rak4631/RAK4631Board.h b/variants/rak4631/RAK4631Board.h index a181256b0..343f4ebff 100644 --- a/variants/rak4631/RAK4631Board.h +++ b/variants/rak4631/RAK4631Board.h @@ -7,7 +7,7 @@ // LoRa radio module pins for RAK4631 #define P_LORA_DIO_1 47 #define P_LORA_NSS 42 -#define P_LORA_RESET RADIOLIB_NC // 38 +#define P_LORA_RESET 38 #define P_LORA_BUSY 46 #define P_LORA_SCLK 43 #define P_LORA_MISO 45 From 25c241575ff7502b4e4e59961f6bd964e94267f1 Mon Sep 17 00:00:00 2001 From: Frieder Schrempf Date: Fri, 2 Jan 2026 11:57:36 +0100 Subject: [PATCH 2/4] simple_repeater: Use constexpr variables for powersaving timings This makes the code easier to read and allows for easier changing of the hardcoded values. Signed-off-by: Frieder Schrempf --- examples/simple_repeater/main.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/examples/simple_repeater/main.cpp b/examples/simple_repeater/main.cpp index 8c745613e..c4ffc16a3 100644 --- a/examples/simple_repeater/main.cpp +++ b/examples/simple_repeater/main.cpp @@ -20,8 +20,12 @@ void halt() { static char command[160]; // For power saving +constexpr unsigned long ACTIVE_TIME_SEC_INUSE = 2 * 60; // 2 minutes +constexpr unsigned long ACTIVE_TIME_SEC_IDLE = 5; // 5 seconds +constexpr unsigned long IDLE_PERIOD_SEC = 30 * 60; // 30 minutes + unsigned long lastActive = 0; // mark last active time -unsigned long nextSleepinSecs = 120; // next sleep in seconds. The first sleep (if enabled) is after 2 minutes from boot +unsigned long nextSleepinSecs = ACTIVE_TIME_SEC_INUSE; // next sleep in seconds void setup() { Serial.begin(115200); @@ -125,14 +129,14 @@ void loop() { #endif rtc_clock.tick(); - if (the_mesh.getNodePrefs()->powersaving_enabled && // To check if power saving is enabled + if (the_mesh.getNodePrefs()->powersaving_enabled && the_mesh.millisHasNowPassed(lastActive + nextSleepinSecs * 1000)) { // To check if it is time to sleep if (!the_mesh.hasPendingWork()) { // No pending work. Safe to sleep - board.sleep(1800); // To sleep. Wake up after 30 minutes or when receiving a LoRa packet + board.sleep(IDLE_PERIOD_SEC); // 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 + nextSleepinSecs = ACTIVE_TIME_SEC_IDLE; // Default: To work for 5s and sleep again } else { - nextSleepinSecs += 5; // When there is pending work, to work another 5s + nextSleepinSecs += ACTIVE_TIME_SEC_IDLE; // When there is pending work, to work another 5s } } } From fbcb16a2b4251160fdd2ec9074e5a0c750096abb Mon Sep 17 00:00:00 2001 From: Frieder Schrempf Date: Fri, 2 Jan 2026 12:00:28 +0100 Subject: [PATCH 3/4] simple_repeater: Extend active interval on serial CLI activity When a CLI command is issued through the serial interface, extend the timeout for going to sleep to give the user more time for issuing more commands. Signed-off-by: Frieder Schrempf --- examples/simple_repeater/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/simple_repeater/main.cpp b/examples/simple_repeater/main.cpp index c4ffc16a3..f5d00be20 100644 --- a/examples/simple_repeater/main.cpp +++ b/examples/simple_repeater/main.cpp @@ -114,6 +114,8 @@ void loop() { Serial.print('\n'); command[len - 1] = 0; // replace newline with C string null terminator char reply[160]; + lastActive = millis(); + nextSleepinSecs = ACTIVE_TIME_SEC_INUSE; the_mesh.handleCommand(0, command, reply); // NOTE: there is no sender_timestamp via serial! if (reply[0]) { Serial.print(" -> "); Serial.println(reply); From 9a659fafb5abc7189e13ccd3fc49c9e00520b3af Mon Sep 17 00:00:00 2001 From: Frieder Schrempf Date: Fri, 2 Jan 2026 12:03:34 +0100 Subject: [PATCH 4/4] Support sleep for NRF52 boards by suspending the main task This uses the core functions suspendLoop() and resumeLoop() to suspend the main task and put the CPU in a low power idle mode. The wakeup occurs either through the specified timeout using a timer interrupt or through an RX interrupt from the radio module. Signed-off-by: Frieder Schrempf --- src/helpers/NRF52Board.cpp | 11 +++++++++++ src/helpers/NRF52Board.h | 1 + src/helpers/radiolib/RadioLibWrappers.cpp | 5 +++++ 3 files changed, 17 insertions(+) diff --git a/src/helpers/NRF52Board.cpp b/src/helpers/NRF52Board.cpp index c0d58314e..6adef893c 100644 --- a/src/helpers/NRF52Board.cpp +++ b/src/helpers/NRF52Board.cpp @@ -4,6 +4,7 @@ #include static BLEDfu bledfu; +static SoftwareTimer sleep_timer; static void connect_callback(uint16_t conn_handle) { (void)conn_handle; @@ -17,10 +18,20 @@ static void disconnect_callback(uint16_t conn_handle, uint8_t reason) { MESH_DEBUG_PRINTLN("BLE client disconnected"); } +static void sleep_timer_callback(TimerHandle_t xTimerID) { + resumeLoop(); +} + void NRF52Board::begin() { startup_reason = BD_STARTUP_NORMAL; } +void NRF52Board::sleep(uint32_t secs) { + sleep_timer.begin(secs * 1000, sleep_timer_callback, NULL, false); + sleep_timer.start(); + suspendLoop(); +} + void NRF52BoardDCDC::begin() { NRF52Board::begin(); diff --git a/src/helpers/NRF52Board.h b/src/helpers/NRF52Board.h index 0d6c0a431..9cec307f2 100644 --- a/src/helpers/NRF52Board.h +++ b/src/helpers/NRF52Board.h @@ -14,6 +14,7 @@ class NRF52Board : public mesh::MainBoard { virtual uint8_t getStartupReason() const override { return startup_reason; } virtual float getMCUTemperature() override; virtual void reboot() override { NVIC_SystemReset(); } + virtual void sleep(uint32_t secs); }; /* diff --git a/src/helpers/radiolib/RadioLibWrappers.cpp b/src/helpers/radiolib/RadioLibWrappers.cpp index e34078211..15b4c307d 100644 --- a/src/helpers/radiolib/RadioLibWrappers.cpp +++ b/src/helpers/radiolib/RadioLibWrappers.cpp @@ -22,6 +22,11 @@ static void setFlag(void) { // we sent a packet, set the flag state |= STATE_INT_READY; + +#ifdef NRF52_PLATFORM + // NRF52 uses suspendLoop() for powersaving, resume on RX interrupt here + if (state & STATE_RX) resumeLoop(); +#endif } void RadioLibWrapper::begin() {