Improvements to deepsleep UM (#4456)

- add touch pin option
- add wake-up on timer macro
- fix powerup behaviour: now works as intended i.e. if no sleep delay set, it enters deepsleep on powerup but only then
- apply macro after wake up even if the window is missed
- respect date-range setting of macro
- removed non-existing pin from touch list
- removed non existing voltageCheck setting
- fixed incorrect threshold setting
- code cleanup
- fix pullup/pulldown for deep-sleep GPIOs

pin init is now working correctly, tested on all platforms

* remove unused statement

---------

Co-authored-by: Damian Schneider <daedae@gmx.ch>
This commit is contained in:
elanworld
2026-01-10 18:28:07 +08:00
committed by GitHub
parent e2de1af6f4
commit fe3a158264
4 changed files with 171 additions and 50 deletions

View File

@@ -1,6 +1,8 @@
#include "wled.h" #include "wled.h"
#include "driver/rtc_io.h" #include "driver/rtc_io.h"
#ifndef CONFIG_IDF_TARGET_ESP32C3
#include "soc/touch_sensor_periph.h"
#endif
#ifdef ESP8266 #ifdef ESP8266
#error The "Deep Sleep" usermod does not support ESP8266 #error The "Deep Sleep" usermod does not support ESP8266
#endif #endif
@@ -21,27 +23,34 @@
#define DEEPSLEEP_DELAY 1 #define DEEPSLEEP_DELAY 1
#endif #endif
RTC_DATA_ATTR bool powerup = true; // variable in RTC data persists on a reboot #ifndef DEEPSLEEP_WAKEUP_TOUCH_PIN
#define DEEPSLEEP_WAKEUP_TOUCH_PIN 1
#endif
RTC_DATA_ATTR bool powerup = true; // this is first boot after power cycle. note: variable in RTC data persists on a reboot
RTC_DATA_ATTR uint8_t wakeupPreset = 0; // preset to apply after deep sleep wakeup (0 = none), set to timer macro preset
class DeepSleepUsermod : public Usermod { class DeepSleepUsermod : public Usermod {
private: private:
bool enabled = false; // do not enable by default
bool enabled = true;
bool initDone = false; bool initDone = false;
uint8_t wakeupPin = DEEPSLEEP_WAKEUPPIN; uint8_t wakeupPin = DEEPSLEEP_WAKEUPPIN;
uint8_t wakeWhenHigh = DEEPSLEEP_WAKEWHENHIGH; // wake up when pin goes high if 1, triggers on low if 0 uint8_t wakeWhenHigh = DEEPSLEEP_WAKEWHENHIGH; // wake up when pin goes high if 1, triggers on low if 0
bool noPull = true; // use pullup/pulldown resistor bool noPull = true; // use pullup/pulldown resistor
bool enableTouchWakeup = false;
uint8_t touchPin = DEEPSLEEP_WAKEUP_TOUCH_PIN;
int wakeupAfter = DEEPSLEEP_WAKEUPINTERVAL; // in seconds, <=0: button only int wakeupAfter = DEEPSLEEP_WAKEUPINTERVAL; // in seconds, <=0: button only
bool presetWake = true; // wakeup timer for preset
int sleepDelay = DEEPSLEEP_DELAY; // in seconds, 0 = immediate int sleepDelay = DEEPSLEEP_DELAY; // in seconds, 0 = immediate
int delaycounter = 5; // delay deep sleep at bootup until preset settings are applied int delaycounter = 10; // delay deep sleep at bootup until preset settings are applied, force wake up if offmode persists after bootup
uint32_t lastLoopTime = 0; uint32_t lastLoopTime = 0;
// string that are used multiple time (this will save some flash memory) // string that are used multiple time (this will save some flash memory)
static const char _name[]; static const char _name[];
static const char _enabled[]; static const char _enabled[];
bool pin_is_valid(uint8_t wakePin) { bool pin_is_valid(uint8_t wakePin) {
#ifdef CONFIG_IDF_TARGET_ESP32 //ESP32: GPIOs 0,2,4, 12-15, 25-39 can be used for wake-up #ifdef CONFIG_IDF_TARGET_ESP32 //ESP32: GPIOs 0,2,4, 12-15, 25-39 can be used for wake-up. note: input-only GPIOs 34-39 do not have internal pull resistors
if (wakePin == 0 || wakePin == 2 || wakePin == 4 || (wakePin >= 12 && wakePin <= 15) || (wakePin >= 25 && wakePin <= 27) || (wakePin >= 32 && wakePin <= 39)) { if (wakePin == 0 || wakePin == 2 || wakePin == 4 || (wakePin >= 12 && wakePin <= 15) || (wakePin >= 25 && wakePin <= 27) || (wakePin >= 32 && wakePin <= 39)) {
return true; return true;
} }
@@ -60,8 +69,56 @@ class DeepSleepUsermod : public Usermod {
return false; return false;
} }
public: // functions to calculate time difference between now and next scheduled timer event
int calculateTimeDifference(int hour1, int minute1, int hour2, int minute2) {
int totalMinutes1 = hour1 * 60 + minute1;
int totalMinutes2 = hour2 * 60 + minute2;
if (totalMinutes2 < totalMinutes1) {
totalMinutes2 += 24 * 60;
}
return totalMinutes2 - totalMinutes1;
}
int findNextTimerInterval() {
if (localTime < 1672502400) { // time invalid before NTP sync 2023-1-1
DEBUG_PRINTLN("Skipping timer check: local time not yet synchronized.");
return -1;
}
int currentHour = hour(localTime);
int currentMinute = minute(localTime);
int currentWeekday = weekdayMondayFirst(); // 1=Monday ... 7=Sunday
int minDifference = INT_MAX;
for (uint8_t i = 0; i < 8; i++) {
// check if timer is enabled and date is in range, also wakes up if no macro is used
if ((timerWeekday[i] & 0x01) && isTodayInDateRange(((timerMonth[i] >> 4) & 0x0F), timerDay[i], timerMonth[i] & 0x0F, timerDayEnd[i])) {
// if timer is enabled (bit0 of timerWeekday) and date is in range, check all weekdays it is set for
for (int dayOffset = 0; dayOffset < 7; dayOffset++) {
int checkWeekday = ((currentWeekday + dayOffset) % 7); // 1-7, check all weekdays starting from today
if (checkWeekday == 0) {
checkWeekday = 7; // sunday is 7 not 0
}
int targetHour = timerHours[i];
int targetMinute = timerMinutes[i];
if ((timerWeekday[i] >> (checkWeekday)) & 0x01) {
if (dayOffset == 0 && (targetHour < currentHour || (targetHour == currentHour && targetMinute <= currentMinute)))
continue; // skip if time has already passed today
int timeDifference = calculateTimeDifference(currentHour, currentMinute, targetHour + (dayOffset * 24), targetMinute);
if (timeDifference < minDifference) {
minDifference = timeDifference;
wakeupPreset = timerMacro[i];
}
}
}
}
}
return minDifference;
}
public:
inline void enable(bool enable) { enabled = enable; } // Enable/Disable the usermod inline void enable(bool enable) { enabled = enable; } // Enable/Disable the usermod
inline bool isEnabled() { return enabled; } //Get usermod enabled/disabled state inline bool isEnabled() { return enabled; } //Get usermod enabled/disabled state
@@ -69,26 +126,39 @@ class DeepSleepUsermod : public Usermod {
void setup() { void setup() {
//TODO: if the de-init of RTC pins is required to do it could be done here //TODO: if the de-init of RTC pins is required to do it could be done here
//rtc_gpio_deinit(wakeupPin); //rtc_gpio_deinit(wakeupPin);
#ifdef WLED_DEBUG
DEBUG_PRINTF("sleep wakeup cause: %d\n", esp_sleep_get_wakeup_cause());
#endif
if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_TIMER) {
wakeupPreset = 0; // not a timed wakeup, don't apply preset
}
initDone = true; initDone = true;
} }
void loop() { void loop() {
if (!enabled || !offMode) { // disabled or LEDs are on if (!enabled) return;
if (!offMode) { // LEDs are on
lastLoopTime = 0; // reset timer lastLoopTime = 0; // reset timer
if (delaycounter) delaycounter--; // decrease delay counter if LEDs are on (they are always turned on after a wake-up, see below)
else if (wakeupPreset) applyPreset(wakeupPreset); // apply preset if set, this ensures macro is applied even if we missed the wake-up time
return; return;
} }
if (sleepDelay > 0) { if (sleepDelay > 0) {
if(lastLoopTime == 0) lastLoopTime = millis(); // initialize powerup = false; // disable powerup sleep if delay is set
if (lastLoopTime == 0) lastLoopTime = millis(); // initialize
if (millis() - lastLoopTime < sleepDelay * 1000) { if (millis() - lastLoopTime < sleepDelay * 1000) {
return; // wait until delay is over return; // wait until delay is over
} }
} else if (powerup && delaycounter) {
delaycounter--; // on first boot without sleepDelay set, do not force-turn on
delay(1000); // just in case: give user a short ~10s window to turn LEDs on in UI
return;
} }
if (powerup == false && delaycounter) { // delay sleep in case a preset is being loaded and turnOnAtBoot is disabled (handleIO() does enable offMode temporarily in this case)
if(powerup == false && delaycounter) { // delay sleep in case a preset is being loaded and turnOnAtBoot is disabled (handleIO() does enable offMode temporarily in this case)
delaycounter--; delaycounter--;
if(delaycounter == 2 && offMode) { // force turn on, no matter the settings (device is bricked if user set sleepDelay=0, no bootup preset and turnOnAtBoot=false) if (delaycounter == 1 && offMode) { // force turn on, no matter the settings (device is bricked if user set sleepDelay=0, no bootup preset and turnOnAtBoot=false)
if (briS == 0) bri = 10; // turn on at low brightness if (briS == 0) bri = 10; // turn on and set low brightness to avoid automatic turn off
else bri = briS; else bri = briS;
strip.setBrightness(bri); // needed to make handleIO() not turn off LEDs (really? does not help in bootup preset) strip.setBrightness(bri); // needed to make handleIO() not turn off LEDs (really? does not help in bootup preset)
offMode = false; offMode = false;
@@ -99,57 +169,82 @@ class DeepSleepUsermod : public Usermod {
} }
return; return;
} }
DEBUG_PRINTLN(F("DeepSleep UM: entering deep sleep...")); DEBUG_PRINTLN(F("DeepSleep UM: entering deep sleep..."));
powerup = false; // turn leds on in all subsequent bootups (overrides Turn LEDs on after power up/reset' at reboot) powerup = false; // turn leds on in all subsequent bootups (overrides Turn LEDs on after power up/reset' at reboot)
if(!pin_is_valid(wakeupPin)) return; if (!pin_is_valid(wakeupPin)) return;
esp_err_t halerror = ESP_OK; esp_err_t halerror = ESP_OK;
pinMode(wakeupPin, INPUT); // make sure GPIO is input with pullup/pulldown disabled pinMode(wakeupPin, INPUT); // make sure GPIO is input with pullup/pulldown disabled
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); //disable all wake-up sources (just in case) esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); //disable all wake-up sources (just in case)
if(wakeupAfter) uint32_t wakeupAfterSec = 0;
esp_sleep_enable_timer_wakeup((uint64_t)wakeupAfter * (uint64_t)1e6); //sleep for x seconds if (presetWake) {
int nextInterval = findNextTimerInterval();
if (nextInterval > 1 && nextInterval < INT_MAX)
wakeupAfterSec = (nextInterval - 1) * 60; // wakeup before next preset
}
if (wakeupAfter > 0) { // user-defined interval
if (wakeupAfterSec == 0 || (uint32_t)wakeupAfter < wakeupAfterSec) {
wakeupAfterSec = wakeupAfter;
}
}
if (wakeupAfterSec > 0) {
esp_sleep_enable_timer_wakeup(wakeupAfterSec * (uint64_t)1e6);
DEBUG_PRINTF("wakeup after %d seconds\n", wakeupAfterSec);
}
#if defined(CONFIG_IDF_TARGET_ESP32C3) // ESP32 C3 #if defined(CONFIG_IDF_TARGET_ESP32C3) // ESP32 C3
if(noPull) gpio_hold_dis((gpio_num_t)wakeupPin); // disable hold and configure pin
gpio_sleep_set_pull_mode((gpio_num_t)wakeupPin, GPIO_FLOATING); if (wakeWhenHigh)
else { // enable pullup/pulldown resistor halerror = esp_deep_sleep_enable_gpio_wakeup(1<<wakeupPin, ESP_GPIO_WAKEUP_GPIO_HIGH);
if(wakeWhenHigh)
gpio_sleep_set_pull_mode((gpio_num_t)wakeupPin, GPIO_PULLDOWN_ONLY);
else else
gpio_sleep_set_pull_mode((gpio_num_t)wakeupPin, GPIO_PULLUP_ONLY); halerror = esp_deep_sleep_enable_gpio_wakeup(1<<wakeupPin, ESP_GPIO_WAKEUP_GPIO_LOW);
} // note: on C3 calling esp_deep_sleep_enable_gpio_wakeup() automatically configures pin as RTC IO and enables pullup/pulldown unless we call gpio_hold_en() which overrides that
if(wakeWhenHigh) gpio_pullup_dis((gpio_num_t)wakeupPin);
halerror = esp_deep_sleep_enable_gpio_wakeup(1<<wakeupPin, ESP_GPIO_WAKEUP_GPIO_HIGH); gpio_pulldown_dis((gpio_num_t)wakeupPin);
else if (!noPull) {
halerror = esp_deep_sleep_enable_gpio_wakeup(1<<wakeupPin, ESP_GPIO_WAKEUP_GPIO_LOW); if (wakeWhenHigh) {
gpio_pulldown_en((gpio_num_t)wakeupPin);
} else {
gpio_pullup_en((gpio_num_t)wakeupPin);
}
}
gpio_hold_en((gpio_num_t)wakeupPin); // if hole_en is used, pullups are disabled for some reason, lets make use of that
#else // ESP32, S2, S3 #else // ESP32, S2, S3
gpio_pulldown_dis((gpio_num_t)wakeupPin); // disable internal pull resistors for GPIO use rtc_gpio_hold_dis((gpio_num_t)wakeupPin); // disable hold and configure pin
gpio_pullup_dis((gpio_num_t)wakeupPin); rtc_gpio_init((gpio_num_t)wakeupPin); // initialize GPIO for RTC domain use
if(noPull) { rtc_gpio_set_direction((gpio_num_t)wakeupPin, RTC_GPIO_MODE_INPUT_ONLY);
rtc_gpio_pullup_dis((gpio_num_t)wakeupPin); rtc_gpio_pullup_dis((gpio_num_t)wakeupPin);
rtc_gpio_pulldown_dis((gpio_num_t)wakeupPin); rtc_gpio_pulldown_dis((gpio_num_t)wakeupPin);
} if (!noPull) {
else { // enable pullup/pulldown resistor for RTC use if (wakeWhenHigh) {
if(wakeWhenHigh) rtc_gpio_pulldown_en((gpio_num_t)wakeupPin);
rtc_gpio_pulldown_en((gpio_num_t)wakeupPin); } else {
rtc_gpio_pullup_en((gpio_num_t)wakeupPin);
}
}
if (wakeWhenHigh)
halerror = esp_sleep_enable_ext1_wakeup(1ULL << wakeupPin, ESP_EXT1_WAKEUP_ANY_HIGH); // only RTC pins can be used
else else
rtc_gpio_pullup_en((gpio_num_t)wakeupPin); halerror = esp_sleep_enable_ext1_wakeup(1ULL << wakeupPin, ESP_EXT1_WAKEUP_ALL_LOW);
}
if(wakeWhenHigh)
halerror = esp_sleep_enable_ext0_wakeup((gpio_num_t)wakeupPin, HIGH); // only RTC pins can be used
else
halerror = esp_sleep_enable_ext0_wakeup((gpio_num_t)wakeupPin, LOW);
#endif
delay(1); // wait for pin to be ready if (enableTouchWakeup) {
if(halerror == ESP_OK) esp_deep_sleep_start(); // go into deep sleep #ifdef SOC_TOUCH_VERSION_2 // S2 and S3 use much higher thresholds
touchSleepWakeUpEnable(touchPin, touchThreshold << 4); // ESP32 S2 & S3: lower threshold = more sensitive
#else
touchSleepWakeUpEnable(touchPin, touchThreshold); // ESP32: higher threshold = more sensitive
#endif
}
delay(1); // just in case: wait for pins to be ready
rtc_gpio_hold_en((gpio_num_t)wakeupPin); // hold the configured GPIO state during deep sleep
#endif
WiFi.mode(WIFI_OFF); // Completely shut down the Wi-Fi module
if (halerror == ESP_OK) esp_deep_sleep_start(); // go into deep sleep
else DEBUG_PRINTLN(F("sleep failed")); else DEBUG_PRINTLN(F("sleep failed"));
} }
//void connected() {} //unused, this is called every time the WiFi is (re)connected //void connected() {} //unused, this is called every time the WiFi is (re)connected
void addToConfig(JsonObject& root) override void addToConfig(JsonObject& root) override
{ {
JsonObject top = root.createNestedObject(FPSTR(_name)); JsonObject top = root.createNestedObject(FPSTR(_name));
top[FPSTR(_enabled)] = enabled; top[FPSTR(_enabled)] = enabled;
@@ -157,6 +252,11 @@ void addToConfig(JsonObject& root) override
top["gpio"] = wakeupPin; top["gpio"] = wakeupPin;
top["wakeWhen"] = wakeWhenHigh; top["wakeWhen"] = wakeWhenHigh;
top["pull"] = noPull; top["pull"] = noPull;
#ifndef CONFIG_IDF_TARGET_ESP32C3
top["enableTouchWakeup"] = enableTouchWakeup;
top["touchPin"] = touchPin;
#endif
top["presetWake"] = presetWake;
top["wakeAfter"] = wakeupAfter; top["wakeAfter"] = wakeupAfter;
top["delaySleep"] = sleepDelay; top["delaySleep"] = sleepDelay;
} }
@@ -176,6 +276,11 @@ void addToConfig(JsonObject& root) override
} }
configComplete &= getJsonValue(top["wakeWhen"], wakeWhenHigh, DEEPSLEEP_WAKEWHENHIGH); // default to wake on low configComplete &= getJsonValue(top["wakeWhen"], wakeWhenHigh, DEEPSLEEP_WAKEWHENHIGH); // default to wake on low
configComplete &= getJsonValue(top["pull"], noPull, DEEPSLEEP_DISABLEPULL); // default to no pullup/pulldown configComplete &= getJsonValue(top["pull"], noPull, DEEPSLEEP_DISABLEPULL); // default to no pullup/pulldown
#ifndef CONFIG_IDF_TARGET_ESP32C3
configComplete &= getJsonValue(top["enableTouchWakeup"], enableTouchWakeup);
configComplete &= getJsonValue(top["touchPin"], touchPin, DEEPSLEEP_WAKEUP_TOUCH_PIN);
#endif
configComplete &= getJsonValue(top["presetWake"], presetWake);
configComplete &= getJsonValue(top["wakeAfter"], wakeupAfter, DEEPSLEEP_WAKEUPINTERVAL); configComplete &= getJsonValue(top["wakeAfter"], wakeupAfter, DEEPSLEEP_WAKEUPINTERVAL);
configComplete &= getJsonValue(top["delaySleep"], sleepDelay, DEEPSLEEP_DELAY); configComplete &= getJsonValue(top["delaySleep"], sleepDelay, DEEPSLEEP_DELAY);
@@ -200,6 +305,19 @@ void addToConfig(JsonObject& root) override
oappend(SET_F(");")); oappend(SET_F(");"));
} }
} }
#ifndef CONFIG_IDF_TARGET_ESP32C3
// dropdown for touch wakeupPin
oappend(SET_F("dd=addDropdown('DeepSleep','touchPin');"));
for (int touchchannel = 0; touchchannel < SOC_TOUCH_SENSOR_NUM; touchchannel++) {
if (touch_sensor_channel_io_map[touchchannel] >= 0) {
oappend(SET_F("addOption(dd,'"));
oappend(String(touch_sensor_channel_io_map[touchchannel]).c_str());
oappend(SET_F("',"));
oappend(String(touch_sensor_channel_io_map[touchchannel]).c_str());
oappend(SET_F(");"));
}
}
#endif
oappend(SET_F("dd=addDropdown('DeepSleep','wakeWhen');")); oappend(SET_F("dd=addDropdown('DeepSleep','wakeWhen');"));
oappend(SET_F("addOption(dd,'Low',0);")); oappend(SET_F("addOption(dd,'Low',0);"));
@@ -207,6 +325,7 @@ void addToConfig(JsonObject& root) override
oappend(SET_F("addInfo('DeepSleep:pull',1,'','-up/down disable: ');")); // first string is suffix, second string is prefix oappend(SET_F("addInfo('DeepSleep:pull',1,'','-up/down disable: ');")); // first string is suffix, second string is prefix
oappend(SET_F("addInfo('DeepSleep:wakeAfter',1,'seconds <i>(0 = never)<i>');")); oappend(SET_F("addInfo('DeepSleep:wakeAfter',1,'seconds <i>(0 = never)<i>');"));
oappend(SET_F("addInfo('DeepSleep:presetWake',1,'<i>(wake up before next preset timer)<i>');"));
oappend(SET_F("addInfo('DeepSleep:delaySleep',1,'seconds <i>(0 = sleep at powerup)<i>');")); // first string is suffix, second string is prefix oappend(SET_F("addInfo('DeepSleep:delaySleep',1,'seconds <i>(0 = sleep at powerup)<i>');")); // first string is suffix, second string is prefix
} }
@@ -217,7 +336,6 @@ void addToConfig(JsonObject& root) override
uint16_t getId() { uint16_t getId() {
return USERMOD_ID_DEEP_SLEEP; return USERMOD_ID_DEEP_SLEEP;
} }
}; };
// add more strings here to reduce flash memory usage // add more strings here to reduce flash memory usage

View File

@@ -1,7 +1,7 @@
# Deep Sleep usermod # Deep Sleep usermod
This usermod unleashes the low power capabilities of th ESP: when you power off your LEDs (using the UI power button or a macro) the ESP will be put into deep sleep mode, reducing power consumption to a minimum. This usermod unleashes the low power capabilities of th ESP: when you power off your LEDs (using the UI power button or a macro) the ESP will be put into deep sleep mode, reducing power consumption to a minimum.
During deep sleep the ESP is shut down completely: no WiFi, no CPU, no outputs. The only way to wake it up is to use an external signal or a button. Once it wakes from deep sleep it reboots so ***make sure to use a boot-up preset.*** During deep sleep the ESP is shut down completely: no WiFi, no CPU, no outputs. The only way to wake it up is by using an external signal, a button, or an automation timer set to the nearest preset time. Once it wakes from deep sleep it reboots so ***make sure to use a boot-up preset.***
# A word of warning # A word of warning
@@ -28,7 +28,7 @@ For lowest power consumption, remove the Power LED and make sure your board does
The GPIOs that can be used to wake the ESP from deep sleep are limited. Only pins connected to the internal RTC unit can be used: The GPIOs that can be used to wake the ESP from deep sleep are limited. Only pins connected to the internal RTC unit can be used:
- ESP32: GPIO 0, 2, 4, 12-15, 25-39 - ESP32: GPIO 0, 2, 4, 12-15, 25-39 note: input-only GPIOs 34-39 do not have internal pull up/down resistors, external resistors are required
- ESP32 S3: GPIO 0-21 - ESP32 S3: GPIO 0-21
- ESP32 S2: GPIO 0-21 - ESP32 S2: GPIO 0-21
- ESP32 C3: GPIO 0-5 - ESP32 C3: GPIO 0-5
@@ -61,6 +61,7 @@ To override the default settings, place the `#define` in wled.h or add `-D DEEPS
* `DEEPSLEEP_DISABLEPULL` - if defined, internal pullup/pulldown is disabled in deep sleep (default is ebnabled) * `DEEPSLEEP_DISABLEPULL` - if defined, internal pullup/pulldown is disabled in deep sleep (default is ebnabled)
* `DEEPSLEEP_WAKEUPINTERVAL` - number of seconds after which a wake-up happens automatically, sooner if button is pressed. 0 = never. accuracy is about 2% * `DEEPSLEEP_WAKEUPINTERVAL` - number of seconds after which a wake-up happens automatically, sooner if button is pressed. 0 = never. accuracy is about 2%
* `DEEPSLEEP_DELAY` - delay between power-off and sleep * `DEEPSLEEP_DELAY` - delay between power-off and sleep
* `DEEPSLEEP_WAKEUP_TOUCH_PIN` - specify GPIO pin used for touch-based wakeup
example for env build flags: example for env build flags:
`-D USERMOD_DEEP_SLEEP` `-D USERMOD_DEEP_SLEEP`

View File

@@ -200,6 +200,7 @@ void getTimeString(char* out);
bool checkCountdown(); bool checkCountdown();
void setCountdown(); void setCountdown();
byte weekdayMondayFirst(); byte weekdayMondayFirst();
bool isTodayInDateRange(byte monthStart, byte dayStart, byte monthEnd, byte dayEnd);
void checkTimers(); void checkTimers();
void calculateSunriseAndSunset(); void calculateSunriseAndSunset();
void setTimeFromAPI(uint32_t timein); void setTimeFromAPI(uint32_t timein);

View File

@@ -69,7 +69,8 @@ enum struct PinOwner : uint8_t {
UM_LDR_DUSK_DAWN = USERMOD_ID_LDR_DUSK_DAWN, // 0x2B // Usermod "usermod_LDR_Dusk_Dawn_v2.h" UM_LDR_DUSK_DAWN = USERMOD_ID_LDR_DUSK_DAWN, // 0x2B // Usermod "usermod_LDR_Dusk_Dawn_v2.h"
UM_MAX17048 = USERMOD_ID_MAX17048, // 0x2F // Usermod "usermod_max17048.h" UM_MAX17048 = USERMOD_ID_MAX17048, // 0x2F // Usermod "usermod_max17048.h"
UM_BME68X = USERMOD_ID_BME68X, // 0x31 // Usermod "usermod_bme68x.h -- Uses "standard" HW_I2C pins UM_BME68X = USERMOD_ID_BME68X, // 0x31 // Usermod "usermod_bme68x.h -- Uses "standard" HW_I2C pins
UM_PIXELS_DICE_TRAY = USERMOD_ID_PIXELS_DICE_TRAY // 0x35 // Usermod "pixels_dice_tray.h" -- Needs compile time specified 6 pins for display including SPI. UM_PIXELS_DICE_TRAY = USERMOD_ID_PIXELS_DICE_TRAY, // 0x35 // Usermod "pixels_dice_tray.h" -- Needs compile time specified 6 pins for display including SPI.
UM_DEEP_SLEEP = USERMOD_ID_DEEP_SLEEP // 0x37 // Usermod "usermod_deep_sleep.h" -- Needs pins to control pmos, nmos, other devices
}; };
static_assert(0u == static_cast<uint8_t>(PinOwner::None), "PinOwner::None must be zero, so default array initialization works as expected"); static_assert(0u == static_cast<uint8_t>(PinOwner::None), "PinOwner::None must be zero, so default array initialization works as expected");