Skip to content

Commit 6e44a89

Browse files
committed
Save some more power when BLE/WiFi is disabled on the companion radio
1 parent f7e92a7 commit 6e44a89

File tree

6 files changed

+76
-3
lines changed

6 files changed

+76
-3
lines changed

examples/companion_radio/MyMesh.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1985,3 +1985,8 @@ bool MyMesh::advert() {
19851985
return false;
19861986
}
19871987
}
1988+
1989+
// Check if there is pending work (packets to send)
1990+
bool MyMesh::hasPendingWork() const {
1991+
return _mgr->getOutboundCount(0xFFFFFFFF) > 0;
1992+
}

examples/companion_radio/MyMesh.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ class MyMesh : public BaseChatMesh, public DataStoreHost {
158158

159159
public:
160160
void savePrefs() { _store->savePrefs(_prefs, sensors.node_lat, sensors.node_lon); }
161+
bool hasPendingWork() const;
161162

162163
private:
163164
void writeOKFrame();

examples/companion_radio/main.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ MyMesh the_mesh(radio_driver, fast_rng, rtc_clock, tables, store
9999
#endif
100100
);
101101

102+
// Power saving timing variables
103+
unsigned long lastActive = 0; // Last time there was activity
104+
unsigned long nextSleepInSecs = 120; // Wait 2 minutes before first sleep
105+
const unsigned long WORK_TIME_SECS = 5; // Stay awake 5 seconds after wake/activity
106+
102107
/* END GLOBAL OBJECTS */
103108

104109
void halt() {
@@ -216,6 +221,9 @@ void setup() {
216221
#ifdef DISPLAY_CLASS
217222
ui_task.begin(disp, &sensors, the_mesh.getNodePrefs()); // still want to pass this in as dependency, as prefs might be moved
218223
#endif
224+
225+
// Initialize power saving timer
226+
lastActive = millis();
219227
}
220228

221229
void loop() {
@@ -225,4 +233,31 @@ void loop() {
225233
ui_task.loop();
226234
#endif
227235
rtc_clock.tick();
236+
237+
// Power saving when BLE/WiFi is disabled
238+
// Don't sleep if GPS is enabled - it needs continuous operation to maintain fix
239+
// Note: Disabling BLE/WiFi via UI actually turns off the radio to save power
240+
if (!serial_interface.isEnabled() && !the_mesh.getNodePrefs()->gps_enabled) {
241+
// Check for pending work and update activity timer
242+
if (the_mesh.hasPendingWork()) {
243+
lastActive = millis();
244+
if (nextSleepInSecs < 10) {
245+
nextSleepInSecs += 5; // Extend work time by 5s if still busy
246+
}
247+
}
248+
249+
// Only sleep if enough time has passed since last activity
250+
if (millis() >= lastActive + (nextSleepInSecs * 1000)) {
251+
#ifdef PIN_USER_BTN
252+
// Sleep for 30 minutes, wake on LoRa packet, timer, or button press
253+
board.enterLightSleep(1800, PIN_USER_BTN);
254+
#else
255+
// Sleep for 30 minutes, wake on LoRa packet or timer
256+
board.enterLightSleep(1800);
257+
#endif
258+
// Just woke up - reset timers
259+
lastActive = millis();
260+
nextSleepInSecs = WORK_TIME_SECS; // Stay awake for 5s after wake
261+
}
262+
}
228263
}

src/helpers/ESP32Board.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <sys/time.h>
1010
#include <Wire.h>
1111
#include "driver/rtc_io.h"
12+
#include "driver/gpio.h"
1213

1314
class ESP32Board : public mesh::MainBoard {
1415
protected:
@@ -56,11 +57,18 @@ class ESP32Board : public mesh::MainBoard {
5657
return raw / 4;
5758
}
5859

59-
void enterLightSleep(uint32_t secs) {
60+
void enterLightSleep(uint32_t secs, int pin_wake_btn = -1) {
6061
#if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(P_LORA_DIO_1) // Supported ESP32 variants
6162
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
6263
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
63-
esp_sleep_enable_ext1_wakeup((1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // To wake up when receiving a LoRa packet
64+
65+
esp_sleep_enable_ext1_wakeup((1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // Wake on LoRa packet
66+
67+
// Wake on button press (active-LOW: pin is HIGH when idle, LOW when pressed)
68+
if (pin_wake_btn >= 0) {
69+
gpio_wakeup_enable((gpio_num_t)pin_wake_btn, GPIO_INTR_LOW_LEVEL);
70+
esp_sleep_enable_gpio_wakeup();
71+
}
6472

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

src/helpers/esp32/SerialWifiInterface.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,38 @@
44
void SerialWifiInterface::begin(int port) {
55
// wifi setup is handled outside of this class, only starts the server
66
server.begin(port);
7+
8+
// Store WiFi credentials for re-enable
9+
#ifdef WIFI_SSID
10+
_ssid = WIFI_SSID;
11+
_password = WIFI_PWD;
12+
_isEnabled = true; // WiFi starts enabled
13+
#else
14+
_ssid = nullptr;
15+
_password = nullptr;
16+
#endif
717
}
818

919
// ---------- public methods
10-
void SerialWifiInterface::enable() {
20+
void SerialWifiInterface::enable() {
1121
if (_isEnabled) return;
1222

1323
_isEnabled = true;
1424
clearBuffers();
25+
26+
// Re-enable WiFi with stored credentials
27+
if (_ssid != nullptr && _password != nullptr) {
28+
WiFi.mode(WIFI_STA);
29+
WiFi.begin(_ssid, _password);
30+
}
1531
}
1632

1733
void SerialWifiInterface::disable() {
1834
_isEnabled = false;
35+
36+
// Actually turn off WiFi to save power
37+
WiFi.disconnect(true); // Disconnect and clear config
38+
WiFi.mode(WIFI_OFF); // Turn off WiFi radio
1939
}
2040

2141
size_t SerialWifiInterface::writeFrame(const uint8_t src[], size_t len) {

src/helpers/esp32/SerialWifiInterface.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ class SerialWifiInterface : public BaseSerialInterface {
88
bool _isEnabled;
99
unsigned long _last_write;
1010
unsigned long adv_restart_time;
11+
const char* _ssid;
12+
const char* _password;
1113

1214
WiFiServer server;
1315
WiFiClient client;
@@ -39,6 +41,8 @@ class SerialWifiInterface : public BaseSerialInterface {
3941
deviceConnected = false;
4042
_isEnabled = false;
4143
_last_write = 0;
44+
_ssid = nullptr;
45+
_password = nullptr;
4246
send_queue_len = recv_queue_len = 0;
4347
received_frame_header.type = 0;
4448
received_frame_header.length = 0;

0 commit comments

Comments
 (0)