Enhance rotary encoder with custom sliders.
Soft watchdog timer (by poelzi)
This commit is contained in:
parent
34a4382920
commit
17be0a2c12
@ -47,7 +47,7 @@
|
|||||||
|
|
||||||
// The last UI state, remove color and saturation option if diplay not active(too many options)
|
// The last UI state, remove color and saturation option if diplay not active(too many options)
|
||||||
#ifdef USERMOD_FOUR_LINE_DISPLAY
|
#ifdef USERMOD_FOUR_LINE_DISPLAY
|
||||||
#define LAST_UI_STATE 8
|
#define LAST_UI_STATE 11
|
||||||
#else
|
#else
|
||||||
#define LAST_UI_STATE 4
|
#define LAST_UI_STATE 4
|
||||||
#endif
|
#endif
|
||||||
@ -366,19 +366,43 @@ public:
|
|||||||
if (buttonWaitTime && currentTime-buttonWaitTime>350 && !buttonPressedBefore) { //same speed as in button.cpp
|
if (buttonWaitTime && currentTime-buttonWaitTime>350 && !buttonPressedBefore) { //same speed as in button.cpp
|
||||||
buttonWaitTime = 0;
|
buttonWaitTime = 0;
|
||||||
char newState = select_state + 1;
|
char newState = select_state + 1;
|
||||||
bool changedState = true;
|
bool changedState = false;
|
||||||
if (newState > LAST_UI_STATE || (newState == 8 && presetHigh==0 && presetLow == 0)) newState = 0;
|
char lineBuffer[64];
|
||||||
|
do {
|
||||||
|
// finde new state
|
||||||
|
switch (newState) {
|
||||||
|
case 0: strcpy_P(lineBuffer, PSTR("Brightness")); changedState = true; break;
|
||||||
|
case 1: if (!extractModeSlider(effectCurrent, 0, lineBuffer, 63)) newState++; else changedState = true; break; // speed
|
||||||
|
case 2: if (!extractModeSlider(effectCurrent, 1, lineBuffer, 63)) newState++; else changedState = true; break; // intensity
|
||||||
|
case 3: strcpy_P(lineBuffer, PSTR("Color Palette")); changedState = true; break;
|
||||||
|
case 4: strcpy_P(lineBuffer, PSTR("Effect")); changedState = true; break;
|
||||||
|
case 5: strcpy_P(lineBuffer, PSTR("Main Color")); changedState = true; break;
|
||||||
|
case 6: strcpy_P(lineBuffer, PSTR("Saturation")); changedState = true; break;
|
||||||
|
case 7:
|
||||||
|
if (!(strip.getSegment(applyToAll ? strip.getFirstSelectedSegId() : strip.getMainSegmentId()).getLightCapabilities() & 0x04)) newState++;
|
||||||
|
else { strcpy_P(lineBuffer, PSTR("CCT")); changedState = true; }
|
||||||
|
break;
|
||||||
|
case 8: if (presetHigh==0 || presetLow == 0) newState++; else { strcpy_P(lineBuffer, PSTR("Preset")); changedState = true; } break;
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
case 11: if (!extractModeSlider(effectCurrent, newState-7, lineBuffer, 63)) newState++; else changedState = true; break; // custom
|
||||||
|
}
|
||||||
|
if (newState > LAST_UI_STATE) newState = 0;
|
||||||
|
} while (!changedState);
|
||||||
if (display != nullptr) {
|
if (display != nullptr) {
|
||||||
switch (newState) {
|
switch (newState) {
|
||||||
case 0: changedState = changeState(PSTR("Brightness"), 1, 0, 1); break; //1 = sun
|
case 0: changedState = changeState(lineBuffer, 1, 0, 1); break; //1 = sun
|
||||||
case 1: changedState = changeState(PSTR("Speed"), 1, 4, 2); break; //2 = skip forward
|
case 1: changedState = changeState(lineBuffer, 1, 4, 2); break; //2 = skip forward
|
||||||
case 2: changedState = changeState(PSTR("Intensity"), 1, 8, 3); break; //3 = fire
|
case 2: changedState = changeState(lineBuffer, 1, 8, 3); break; //3 = fire
|
||||||
case 3: changedState = changeState(PSTR("Color Palette"), 2, 0, 4); break; //4 = custom palette
|
case 3: changedState = changeState(lineBuffer, 2, 0, 4); break; //4 = custom palette
|
||||||
case 4: changedState = changeState(PSTR("Effect"), 3, 0, 5); break; //5 = puzzle piece
|
case 4: changedState = changeState(lineBuffer, 3, 0, 5); break; //5 = puzzle piece
|
||||||
case 5: changedState = changeState(PSTR("Main Color"), 255, 255, 7); break; //7 = brush
|
case 5: changedState = changeState(lineBuffer, 255, 255, 7); break; //7 = brush
|
||||||
case 6: changedState = changeState(PSTR("Saturation"), 255, 255, 8); break; //8 = contrast
|
case 6: changedState = changeState(lineBuffer, 255, 255, 8); break; //8 = contrast
|
||||||
case 7: changedState = changeState(PSTR("CCT"), 255, 255, 10); break; //10 = star
|
case 7: changedState = changeState(lineBuffer, 255, 255, 10); break; //10 = star
|
||||||
case 8: changedState = changeState(PSTR("Preset"), 255, 255, 11); break; //11 = heart
|
case 8: changedState = changeState(lineBuffer, 255, 255, 11); break; //11 = heart
|
||||||
|
case 9: changedState = changeState(lineBuffer, 255, 255, 10); break; //10 = star
|
||||||
|
case 10: changedState = changeState(lineBuffer, 255, 255, 10); break; //10 = star
|
||||||
|
case 11: changedState = changeState(lineBuffer, 255, 255, 10); break; //10 = star
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (changedState) select_state = newState;
|
if (changedState) select_state = newState;
|
||||||
@ -391,29 +415,35 @@ public:
|
|||||||
if (Enc_B == LOW) //changes to LOW so that then encoder registers a change at the very end of a pulse
|
if (Enc_B == LOW) //changes to LOW so that then encoder registers a change at the very end of a pulse
|
||||||
{ // B is high so clockwise
|
{ // B is high so clockwise
|
||||||
switch(select_state) {
|
switch(select_state) {
|
||||||
case 0: changeBrightness(true); break;
|
case 0: changeBrightness(true); break;
|
||||||
case 1: changeEffectSpeed(true); break;
|
case 1: changeEffectSpeed(true); break;
|
||||||
case 2: changeEffectIntensity(true); break;
|
case 2: changeEffectIntensity(true); break;
|
||||||
case 3: changePalette(true); break;
|
case 3: changePalette(true); break;
|
||||||
case 4: changeEffect(true); break;
|
case 4: changeEffect(true); break;
|
||||||
case 5: changeHue(true); break;
|
case 5: changeHue(true); break;
|
||||||
case 6: changeSat(true); break;
|
case 6: changeSat(true); break;
|
||||||
case 7: changeCCT(true); break;
|
case 7: changeCCT(true); break;
|
||||||
case 8: changePreset(true); break;
|
case 8: changePreset(true); break;
|
||||||
|
case 9: changeCustom(1,true); break;
|
||||||
|
case 10: changeCustom(2,true); break;
|
||||||
|
case 11: changeCustom(3,true); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Enc_B == HIGH)
|
else if (Enc_B == HIGH)
|
||||||
{ // B is low so counter-clockwise
|
{ // B is low so counter-clockwise
|
||||||
switch(select_state) {
|
switch(select_state) {
|
||||||
case 0: changeBrightness(false); break;
|
case 0: changeBrightness(false); break;
|
||||||
case 1: changeEffectSpeed(false); break;
|
case 1: changeEffectSpeed(false); break;
|
||||||
case 2: changeEffectIntensity(false); break;
|
case 2: changeEffectIntensity(false); break;
|
||||||
case 3: changePalette(false); break;
|
case 3: changePalette(false); break;
|
||||||
case 4: changeEffect(false); break;
|
case 4: changeEffect(false); break;
|
||||||
case 5: changeHue(false); break;
|
case 5: changeHue(false); break;
|
||||||
case 6: changeSat(false); break;
|
case 6: changeSat(false); break;
|
||||||
case 7: changeCCT(false); break;
|
case 7: changeCCT(false); break;
|
||||||
case 8: changePreset(false); break;
|
case 8: changePreset(false); break;
|
||||||
|
case 9: changeCustom(1,false); break;
|
||||||
|
case 10: changeCustom(2,false); break;
|
||||||
|
case 11: changeCustom(3,false); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -569,6 +599,50 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void changeCustom(uint8_t par, bool increase) {
|
||||||
|
uint8_t val = 0;
|
||||||
|
#ifdef USERMOD_FOUR_LINE_DISPLAY
|
||||||
|
if (display && display->wakeDisplay()) {
|
||||||
|
display->redraw(true);
|
||||||
|
// Throw away wake up input
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
display->updateRedrawTime();
|
||||||
|
#endif
|
||||||
|
stateChanged = true;
|
||||||
|
if (applyToAll) {
|
||||||
|
uint8_t id = strip.getFirstSelectedSegId();
|
||||||
|
switch (par) {
|
||||||
|
case 3: val = strip.getSegment(id).custom3 = max(min((increase ? strip.getSegment(id).custom3+fadeAmount : strip.getSegment(id).custom3-fadeAmount), 255), 0); break;
|
||||||
|
case 2: val = strip.getSegment(id).custom2 = max(min((increase ? strip.getSegment(id).custom2+fadeAmount : strip.getSegment(id).custom2-fadeAmount), 255), 0); break;
|
||||||
|
default: val = strip.getSegment(id).custom1 = max(min((increase ? strip.getSegment(id).custom1+fadeAmount : strip.getSegment(id).custom1-fadeAmount), 255), 0); break;
|
||||||
|
}
|
||||||
|
for (byte i=0; i<strip.getMaxSegments(); i++) {
|
||||||
|
WS2812FX::Segment& seg = strip.getSegment(i);
|
||||||
|
if (!seg.isActive() || i == id) continue;
|
||||||
|
switch (par) {
|
||||||
|
case 3: strip.getSegment(i).custom3 = strip.getSegment(id).custom3; break;
|
||||||
|
case 2: strip.getSegment(i).custom2 = strip.getSegment(id).custom2; break;
|
||||||
|
default: strip.getSegment(i).custom1 = strip.getSegment(id).custom1; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
WS2812FX::Segment& seg = strip.getSegment(strip.getMainSegmentId());
|
||||||
|
switch (par) {
|
||||||
|
case 3: val = seg.custom3 = max(min((increase ? seg.custom3+fadeAmount : seg.custom3-fadeAmount), 255), 0); break;
|
||||||
|
case 2: val = seg.custom2 = max(min((increase ? seg.custom2+fadeAmount : seg.custom2-fadeAmount), 255), 0); break;
|
||||||
|
default: val = seg.custom1 = max(min((increase ? seg.custom1+fadeAmount : seg.custom1-fadeAmount), 255), 0); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lampUdated();
|
||||||
|
#ifdef USERMOD_FOUR_LINE_DISPLAY
|
||||||
|
char lineBuffer[64];
|
||||||
|
sprintf(lineBuffer, "%d", val);
|
||||||
|
display->overlay(lineBuffer, 500, 10); // use star
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void changePalette(bool increase) {
|
void changePalette(bool increase) {
|
||||||
#ifdef USERMOD_FOUR_LINE_DISPLAY
|
#ifdef USERMOD_FOUR_LINE_DISPLAY
|
||||||
if (display && display->wakeDisplay()) {
|
if (display && display->wakeDisplay()) {
|
||||||
|
@ -278,6 +278,7 @@ bool isAsterisksOnly(const char* str, byte maxLen);
|
|||||||
bool requestJSONBufferLock(uint8_t module=255);
|
bool requestJSONBufferLock(uint8_t module=255);
|
||||||
void releaseJSONBufferLock();
|
void releaseJSONBufferLock();
|
||||||
uint8_t extractModeName(uint8_t mode, const char *src, char *dest, uint8_t maxLen);
|
uint8_t extractModeName(uint8_t mode, const char *src, char *dest, uint8_t maxLen);
|
||||||
|
uint8_t extractModeSlider(uint8_t mode, uint8_t slider, char *dest, uint8_t maxLen);
|
||||||
uint16_t crc16(const unsigned char* data_p, size_t length);
|
uint16_t crc16(const unsigned char* data_p, size_t length);
|
||||||
|
|
||||||
//wled_eeprom.cpp
|
//wled_eeprom.cpp
|
||||||
|
@ -234,7 +234,7 @@ void releaseJSONBufferLock()
|
|||||||
// caller must provide large enough buffer for name (incluing SR extensions)!
|
// caller must provide large enough buffer for name (incluing SR extensions)!
|
||||||
uint8_t extractModeName(uint8_t mode, const char *src, char *dest, uint8_t maxLen)
|
uint8_t extractModeName(uint8_t mode, const char *src, char *dest, uint8_t maxLen)
|
||||||
{
|
{
|
||||||
if (src == JSON_mode_names) {
|
if (src == JSON_mode_names || src == nullptr) {
|
||||||
if (mode < MODE_COUNT) {
|
if (mode < MODE_COUNT) {
|
||||||
char lineBuffer[256];
|
char lineBuffer[256];
|
||||||
//strcpy_P(lineBuffer, (const char*)pgm_read_dword(&(WS2812FX::_modeData[mode])));
|
//strcpy_P(lineBuffer, (const char*)pgm_read_dword(&(WS2812FX::_modeData[mode])));
|
||||||
@ -281,6 +281,59 @@ uint8_t extractModeName(uint8_t mode, const char *src, char *dest, uint8_t maxLe
|
|||||||
return strlen(dest);
|
return strlen(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// extracts effect slider data (1st group after @)
|
||||||
|
uint8_t extractModeSlider(uint8_t mode, uint8_t slider, char *dest, uint8_t maxLen)
|
||||||
|
{
|
||||||
|
dest[0] = '\0'; // start by clearing buffer
|
||||||
|
|
||||||
|
if (mode < MODE_COUNT) {
|
||||||
|
String lineBuffer = WS2812FX::_modeData[mode];
|
||||||
|
if (lineBuffer.length() > 0) {
|
||||||
|
int16_t start = lineBuffer.indexOf('@');
|
||||||
|
int16_t stop = lineBuffer.indexOf(';', start);
|
||||||
|
if (start>0 && stop>0) {
|
||||||
|
String names = lineBuffer.substring(start+1, stop);
|
||||||
|
int16_t nameBegin = 0, nameEnd;
|
||||||
|
for (size_t i=0; i<=slider; i++) {
|
||||||
|
const char *tmpstr;
|
||||||
|
dest[0] = '\0'; //clear dest buffer
|
||||||
|
if (i > 0 && nameBegin == 0) break; // there are no more names
|
||||||
|
nameEnd = names.indexOf(',', nameBegin);
|
||||||
|
if (names.charAt(nameBegin) == '!') {
|
||||||
|
switch (i) {
|
||||||
|
case 0: tmpstr = PSTR("FX Speed"); break;
|
||||||
|
case 1: tmpstr = PSTR("FX Intensity"); break;
|
||||||
|
case 2: tmpstr = PSTR("FX Custom 1"); break;
|
||||||
|
case 3: tmpstr = PSTR("FX Custom 2"); break;
|
||||||
|
case 4: tmpstr = PSTR("FX Custom 3"); break;
|
||||||
|
default: tmpstr = PSTR("FX Custom"); break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (nameEnd<0) tmpstr = names.substring(nameBegin).c_str(); // did not find ",", last name?
|
||||||
|
else tmpstr = names.substring(nameBegin, nameEnd).c_str();
|
||||||
|
}
|
||||||
|
strncpy(dest, tmpstr, maxLen); // copy the name into buffer (replacing previous)
|
||||||
|
nameBegin = nameEnd+1; // next name (if "," is not found it will be 0)
|
||||||
|
} // next slider
|
||||||
|
|
||||||
|
// we have slider name (including default value) in the dest buffer
|
||||||
|
for (size_t i=0; i<strlen(dest); i++) if (dest[i]=='=') { dest[i]='\0'; break; } // truncate default value
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// defaults to just speed and intensity since there is no slider data
|
||||||
|
switch (slider) {
|
||||||
|
case 0: strncpy_P(dest, PSTR("FX Speed"), maxLen); break;
|
||||||
|
case 1: strncpy_P(dest, PSTR("FX Intensity"), maxLen); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strlen(dest);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint16_t crc16(const unsigned char* data_p, size_t length) {
|
uint16_t crc16(const unsigned char* data_p, size_t length) {
|
||||||
uint8_t x;
|
uint8_t x;
|
||||||
uint16_t crc = 0xFFFF;
|
uint16_t crc = 0xFFFF;
|
||||||
|
@ -216,6 +216,35 @@ void WLED::loop()
|
|||||||
toki.resetTick();
|
toki.resetTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WLED::enableWatchdog() {
|
||||||
|
#if WLED_WATCHDOG_TIMEOUT > 0
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
esp_err_t watchdog = esp_task_wdt_init(WLED_WATCHDOG_TIMEOUT, true);
|
||||||
|
DEBUG_PRINT(F("Watchdog enabled: "));
|
||||||
|
if (watchdog == ESP_OK) {
|
||||||
|
DEBUG_PRINTLN(F("OK"));
|
||||||
|
} else {
|
||||||
|
DEBUG_PRINTLN(watchdog);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
esp_task_wdt_add(NULL);
|
||||||
|
#else
|
||||||
|
ESP.wdtEnable(WLED_WATCHDOG_TIMEOUT * 1000);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void WLED::disableWatchdog() {
|
||||||
|
#if WLED_WATCHDOG_TIMEOUT > 0
|
||||||
|
DEBUG_PRINTLN(F("Watchdog: disabled"));
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
esp_task_wdt_delete(NULL);
|
||||||
|
#else
|
||||||
|
ESP.wdtDisable();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void WLED::setup()
|
void WLED::setup()
|
||||||
{
|
{
|
||||||
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_DISABLE_BROWNOUT_DET)
|
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_DISABLE_BROWNOUT_DET)
|
||||||
@ -240,6 +269,8 @@ void WLED::setup()
|
|||||||
DEBUG_PRINT(F("heap "));
|
DEBUG_PRINT(F("heap "));
|
||||||
DEBUG_PRINTLN(ESP.getFreeHeap());
|
DEBUG_PRINTLN(ESP.getFreeHeap());
|
||||||
|
|
||||||
|
enableWatchdog();
|
||||||
|
|
||||||
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM)
|
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM)
|
||||||
if (psramFound()) {
|
if (psramFound()) {
|
||||||
// GPIO16/GPIO17 reserved for SPI RAM
|
// GPIO16/GPIO17 reserved for SPI RAM
|
||||||
@ -337,8 +368,13 @@ void WLED::setup()
|
|||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
wifi_set_sleep_type(NONE_SLEEP_T);
|
wifi_set_sleep_type(NONE_SLEEP_T);
|
||||||
#endif
|
#endif
|
||||||
|
WLED::instance().disableWatchdog();
|
||||||
DEBUG_PRINTLN(F("Start ArduinoOTA"));
|
DEBUG_PRINTLN(F("Start ArduinoOTA"));
|
||||||
});
|
});
|
||||||
|
ArduinoOTA.onError([](ota_error_t error) {
|
||||||
|
// reenable watchdog on failed update
|
||||||
|
WLED::instance().enableWatchdog();
|
||||||
|
});
|
||||||
if (strlen(cmDNS) > 0)
|
if (strlen(cmDNS) > 0)
|
||||||
ArduinoOTA.setHostname(cmDNS);
|
ArduinoOTA.setHostname(cmDNS);
|
||||||
}
|
}
|
||||||
|
@ -707,5 +707,7 @@ public:
|
|||||||
void initConnection();
|
void initConnection();
|
||||||
void initInterfaces();
|
void initInterfaces();
|
||||||
void handleStatusLED();
|
void handleStatusLED();
|
||||||
|
void enableWatchdog();
|
||||||
|
void disableWatchdog();
|
||||||
};
|
};
|
||||||
#endif // WLED_H
|
#endif // WLED_H
|
||||||
|
@ -281,6 +281,7 @@ void initServer()
|
|||||||
if (!correctPIN || otaLock) return;
|
if (!correctPIN || otaLock) return;
|
||||||
if(!index){
|
if(!index){
|
||||||
DEBUG_PRINTLN(F("OTA Update Start"));
|
DEBUG_PRINTLN(F("OTA Update Start"));
|
||||||
|
WLED::instance().disableWatchdog();
|
||||||
lastEditTime = millis(); // make sure PIN does not lock during update
|
lastEditTime = millis(); // make sure PIN does not lock during update
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
Update.runAsync(true);
|
Update.runAsync(true);
|
||||||
@ -293,6 +294,7 @@ void initServer()
|
|||||||
DEBUG_PRINTLN(F("Update Success"));
|
DEBUG_PRINTLN(F("Update Success"));
|
||||||
} else {
|
} else {
|
||||||
DEBUG_PRINTLN(F("Update Failed"));
|
DEBUG_PRINTLN(F("Update Failed"));
|
||||||
|
WLED::instance().enableWatchdog();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user