mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-04-20 22:13:47 +00:00
Added powersaving to all ESP32 boards with RTC-supported DIO1
Added CLI to enable/disable powersaving
This commit is contained in:
parent
0c3fb918b2
commit
5c6c15942b
7 changed files with 68 additions and 2 deletions
|
|
@ -1115,3 +1115,8 @@ void MyMesh::loop() {
|
|||
uptime_millis += now - last_millis;
|
||||
last_millis = now;
|
||||
}
|
||||
|
||||
// To get the current pending work
|
||||
int MyMesh::hasPendingWork() const {
|
||||
return _mgr->getOutboundCount(0xFFFFFFFF);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -225,4 +225,7 @@ public:
|
|||
bridge.begin();
|
||||
}
|
||||
#endif
|
||||
|
||||
// To get the current pending work
|
||||
int hasPendingWork() const;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,12 +19,19 @@ void halt() {
|
|||
|
||||
static char command[160];
|
||||
|
||||
// For power saving
|
||||
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
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(1000);
|
||||
|
||||
board.begin();
|
||||
|
||||
// For power saving
|
||||
lastActive = millis(); // mark last active time since boot
|
||||
|
||||
#ifdef DISPLAY_CLASS
|
||||
if (display.begin()) {
|
||||
display.startFrame();
|
||||
|
|
@ -117,4 +124,15 @@ void loop() {
|
|||
ui_task.loop();
|
||||
#endif
|
||||
rtc_clock.tick();
|
||||
|
||||
if (the_mesh.getNodePrefs()->powersaving_enabled && // To check if power saving is enabled
|
||||
the_mesh.millisHasNowPassed(lastActive + nextSleepinSecs * 1000)) { // To check if it is time to sleep
|
||||
if (the_mesh.hasPendingWork() == 0) { // No pending work. 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; // When there is pending work, to work another 5s
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ public:
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
|
|||
file.read((uint8_t *)&_prefs->bridge_baud, sizeof(_prefs->bridge_baud)); // 131
|
||||
file.read((uint8_t *)&_prefs->bridge_channel, sizeof(_prefs->bridge_channel)); // 135
|
||||
file.read((uint8_t *)&_prefs->bridge_secret, sizeof(_prefs->bridge_secret)); // 136
|
||||
file.read(pad, 4); // 152
|
||||
file.read((uint8_t *)&_prefs->powersaving_enabled, sizeof(_prefs->powersaving_enabled)); // 152
|
||||
file.read((uint8_t *)&_prefs->gps_enabled, sizeof(_prefs->gps_enabled)); // 156
|
||||
file.read((uint8_t *)&_prefs->gps_interval, sizeof(_prefs->gps_interval)); // 157
|
||||
file.read((uint8_t *)&_prefs->advert_loc_policy, sizeof (_prefs->advert_loc_policy)); // 161
|
||||
|
|
@ -145,7 +145,7 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) {
|
|||
file.write((uint8_t *)&_prefs->bridge_baud, sizeof(_prefs->bridge_baud)); // 131
|
||||
file.write((uint8_t *)&_prefs->bridge_channel, sizeof(_prefs->bridge_channel)); // 135
|
||||
file.write((uint8_t *)&_prefs->bridge_secret, sizeof(_prefs->bridge_secret)); // 136
|
||||
file.write(pad, 4); // 152
|
||||
file.write((uint8_t *)&_prefs->powersaving_enabled, sizeof(_prefs->powersaving_enabled)); // 152
|
||||
file.write((uint8_t *)&_prefs->gps_enabled, sizeof(_prefs->gps_enabled)); // 156
|
||||
file.write((uint8_t *)&_prefs->gps_interval, sizeof(_prefs->gps_interval)); // 157
|
||||
file.write((uint8_t *)&_prefs->advert_loc_policy, sizeof(_prefs->advert_loc_policy)); // 161
|
||||
|
|
@ -676,6 +676,20 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
|||
strcpy(reply, "Can't find GPS");
|
||||
}
|
||||
#endif
|
||||
} else if (memcmp(command, "powersaving on", 14) == 0) {
|
||||
_prefs->powersaving_enabled = 1;
|
||||
savePrefs();
|
||||
strcpy(reply, "ok"); // TODO: to return Not supported if required
|
||||
} else if (memcmp(command, "powersaving off", 15) == 0) {
|
||||
_prefs->powersaving_enabled = 0;
|
||||
savePrefs();
|
||||
strcpy(reply, "ok");
|
||||
} else if (memcmp(command, "powersaving", 11) == 0) {
|
||||
if (_prefs->powersaving_enabled) {
|
||||
strcpy(reply, "on");
|
||||
} else {
|
||||
strcpy(reply, "off");
|
||||
}
|
||||
} else if (memcmp(command, "log start", 9) == 0) {
|
||||
_callbacks->setLoggingOn(true);
|
||||
strcpy(reply, " logging on");
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ struct NodePrefs { // persisted to file
|
|||
uint8_t advert_loc_policy;
|
||||
uint32_t discovery_mod_timestamp;
|
||||
float adc_multiplier;
|
||||
// Power setting
|
||||
uint8_t powersaving_enabled; // boolean
|
||||
};
|
||||
|
||||
class CommonCLICallbacks {
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
@ -47,6 +49,27 @@ public:
|
|||
return temperatureRead();
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue