Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -1115,3 +1115,8 @@ void MyMesh::loop() {
uptime_millis += now - last_millis;
last_millis = now;
}

// To check if there is pending work
bool MyMesh::hasPendingWork() const {
return _mgr->getOutboundCount(0xFFFFFFFF) > 0;
}
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 check if there is pending work
bool hasPendingWork() const;
};
18 changes: 18 additions & 0 deletions examples/simple_repeater/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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()) { // 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
}
}
}
1 change: 1 addition & 0 deletions src/MeshCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,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
20 changes: 18 additions & 2 deletions src/helpers/CommonCLI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -93,6 +93,8 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
_prefs->bridge_baud = constrain(_prefs->bridge_baud, 9600, 115200);
_prefs->bridge_channel = constrain(_prefs->bridge_channel, 0, 14);

_prefs->powersaving_enabled = constrain(_prefs->powersaving_enabled, 0, 1);

_prefs->gps_enabled = constrain(_prefs->gps_enabled, 0, 1);
_prefs->advert_loc_policy = constrain(_prefs->advert_loc_policy, 0, 2);

Expand Down Expand Up @@ -145,7 +147,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
Expand Down Expand Up @@ -676,6 +678,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");
Expand Down
2 changes: 2 additions & 0 deletions src/helpers/CommonCLI.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ struct NodePrefs { // persisted to file
uint32_t bridge_baud; // 9600, 19200, 38400, 57600, 115200 (default 115200)
uint8_t bridge_channel; // 1-14 (ESP-NOW only)
char bridge_secret[16]; // for XOR encryption of bridge packets (ESP-NOW only)
// Power setting
uint8_t powersaving_enabled; // boolean
// Gps settings
uint8_t gps_enabled;
uint32_t gps_interval; // in seconds
Expand Down
23 changes: 23 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 @@ -47,6 +49,27 @@ class ESP32Board : public mesh::MainBoard {
return temperatureRead();
}

void enterLightSleep(uint32_t secs) {
#if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(P_LORA_DIO_1) // 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
18 changes: 8 additions & 10 deletions src/helpers/esp32/TBeamBoard.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,7 @@

#if defined(TBEAM_SUPREME_SX1262) || defined(TBEAM_SX1262) || defined(TBEAM_SX1276)

#include <Wire.h>
#include <Arduino.h>
#include "XPowersLib.h"
#include "helpers/ESP32Board.h"
#include <driver/rtc_io.h>
//#include <RadioLib.h>
//#include <helpers/RadioLibWrappers.h>
//#include <helpers/CustomSX1262Wrapper.h>
//#include <helpers/CustomSX1276Wrapper.h>

// Define pin mappings BEFORE including ESP32Board.h so sleep() can use P_LORA_DIO_1
#ifdef TBEAM_SUPREME_SX1262
// LoRa radio module pins for TBeam S3 Supreme SX1262
#define P_LORA_DIO_0 -1 //NC
Expand Down Expand Up @@ -90,6 +81,13 @@
// SX1276
// };

// Include headers AFTER pin definitions so ESP32Board::sleep() can use P_LORA_DIO_1
#include <Wire.h>
#include <Arduino.h>
#include "XPowersLib.h"
#include "helpers/ESP32Board.h"
#include <driver/rtc_io.h>

class TBeamBoard : public ESP32Board {
XPowersLibInterface *PMU = NULL;
//PhysicalLayer * pl;
Expand Down