diff --git a/examples/simple_repeater/main.cpp b/examples/simple_repeater/main.cpp index 8c745613e..f5d00be20 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); @@ -110,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); @@ -125,14 +131,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 } } } 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() { 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