Preset loading tuning.

Multi-relay toggle support.
Fire2012 tuning.
2D functions tuning.
Global SPI comments & tuning.
Bugfix in 4LD usermod.
On & bri support fix.
This commit is contained in:
Blaz Kristan 2022-09-09 17:16:52 +02:00
parent 94243ac605
commit e4fbf70568
11 changed files with 85 additions and 55 deletions

View File

@ -80,7 +80,7 @@ class MultiRelay : public Usermod {
void handleOffTimer() { void handleOffTimer() {
unsigned long now = millis(); unsigned long now = millis();
bool activeRelays = false; bool activeRelays = false;
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) { for (int i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
if (_relay[i].active && _switchTimerStart > 0 && now - _switchTimerStart > (_relay[i].delay*1000)) { if (_relay[i].active && _switchTimerStart > 0 && now - _switchTimerStart > (_relay[i].delay*1000)) {
if (!_relay[i].external) toggleRelay(i); if (!_relay[i].external) toggleRelay(i);
_relay[i].active = false; _relay[i].active = false;
@ -182,7 +182,7 @@ class MultiRelay : public Usermod {
*/ */
MultiRelay() { MultiRelay() {
const int8_t defPins[] = {MULTI_RELAY_PINS}; const int8_t defPins[] = {MULTI_RELAY_PINS};
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) { for (int i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
_relay[i].pin = i<sizeof(defPins) ? defPins[i] : -1; _relay[i].pin = i<sizeof(defPins) ? defPins[i] : -1;
_relay[i].delay = 0; _relay[i].delay = 0;
_relay[i].mode = false; _relay[i].mode = false;
@ -226,7 +226,7 @@ class MultiRelay : public Usermod {
uint8_t getActiveRelayCount() { uint8_t getActiveRelayCount() {
uint8_t count = 0; uint8_t count = 0;
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) if (_relay[i].pin>=0) count++; for (int i=0; i<MULTI_RELAY_MAX_RELAYS; i++) if (_relay[i].pin>=0) count++;
return count; return count;
} }
@ -268,7 +268,7 @@ class MultiRelay : public Usermod {
strcat_P(subuf, PSTR("/relay/#")); strcat_P(subuf, PSTR("/relay/#"));
mqtt->subscribe(subuf, 0); mqtt->subscribe(subuf, 0);
if (HAautodiscovery) publishHomeAssistantAutodiscovery(); if (HAautodiscovery) publishHomeAssistantAutodiscovery();
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) { for (int i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
if (_relay[i].pin<0) continue; if (_relay[i].pin<0) continue;
publishMqtt(i); //publish current state publishMqtt(i); //publish current state
} }
@ -276,7 +276,7 @@ class MultiRelay : public Usermod {
} }
void publishHomeAssistantAutodiscovery() { void publishHomeAssistantAutodiscovery() {
for (uint8_t i = 0; i < MULTI_RELAY_MAX_RELAYS; i++) { for (int i = 0; i < MULTI_RELAY_MAX_RELAYS; i++) {
char uid[24], json_str[1024], buf[128]; char uid[24], json_str[1024], buf[128];
size_t payload_size; size_t payload_size;
sprintf_P(uid, PSTR("%s_sw%d"), escapedMac.c_str(), i); sprintf_P(uid, PSTR("%s_sw%d"), escapedMac.c_str(), i);
@ -320,7 +320,7 @@ class MultiRelay : public Usermod {
*/ */
void setup() { void setup() {
// pins retrieved from cfg.json (readFromConfig()) prior to running setup() // pins retrieved from cfg.json (readFromConfig()) prior to running setup()
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) { for (int i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
if (_relay[i].pin<0) continue; if (_relay[i].pin<0) continue;
if (!pinManager.allocatePin(_relay[i].pin,true, PinOwner::UM_MultiRelay)) { if (!pinManager.allocatePin(_relay[i].pin,true, PinOwner::UM_MultiRelay)) {
_relay[i].pin = -1; // allocation failed _relay[i].pin = -1; // allocation failed
@ -357,7 +357,7 @@ class MultiRelay : public Usermod {
if (_oldMode != offMode) { if (_oldMode != offMode) {
_oldMode = offMode; _oldMode = offMode;
_switchTimerStart = millis(); _switchTimerStart = millis();
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) { for (int i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
if (_relay[i].pin>=0 && !_relay[i].external) _relay[i].active = true; if (_relay[i].pin>=0 && !_relay[i].external) _relay[i].active = true;
} }
} }
@ -382,7 +382,7 @@ class MultiRelay : public Usermod {
} }
bool handled = false; bool handled = false;
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) { for (int i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
if (_relay[i].button == b && _relay[i].external) { if (_relay[i].button == b && _relay[i].external) {
handled = true; handled = true;
} }
@ -402,8 +402,8 @@ class MultiRelay : public Usermod {
if (buttonLongPressed[b] == buttonPressedBefore[b]) return handled; if (buttonLongPressed[b] == buttonPressedBefore[b]) return handled;
if (now - buttonPressedTime[b] > WLED_DEBOUNCE_THRESHOLD) { //fire edge event only after 50ms without change (debounce) if (now - buttonPressedTime[b] > WLED_DEBOUNCE_THRESHOLD) { //fire edge event only after 50ms without change (debounce)
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) { for (int i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
if (_relay[i].pin>=0 && _relay[i].button == b) { if (_relay[i].button == b) {
switchRelay(i, buttonPressedBefore[b]); switchRelay(i, buttonPressedBefore[b]);
buttonLongPressed[b] = buttonPressedBefore[b]; //save the last "long term" switch state buttonLongPressed[b] = buttonPressedBefore[b]; //save the last "long term" switch state
} }
@ -450,8 +450,8 @@ class MultiRelay : public Usermod {
if (buttonWaitTime[b] && now - buttonWaitTime[b] > 350 && !buttonPressedBefore[b]) { if (buttonWaitTime[b] && now - buttonWaitTime[b] > 350 && !buttonPressedBefore[b]) {
buttonWaitTime[b] = 0; buttonWaitTime[b] = 0;
//shortPressAction(b); //not exposed //shortPressAction(b); //not exposed
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) { for (int i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
if (_relay[i].pin>=0 && _relay[i].button == b) { if (_relay[i].button == b) {
toggleRelay(i); toggleRelay(i);
} }
} }
@ -473,7 +473,7 @@ class MultiRelay : public Usermod {
infoArr.add(F(" relays")); infoArr.add(F(" relays"));
String uiDomString; String uiDomString;
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) { for (int i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
if (_relay[i].pin<0 || !_relay[i].external) continue; if (_relay[i].pin<0 || !_relay[i].external) continue;
uiDomString = F("Relay "); uiDomString += i; uiDomString = F("Relay "); uiDomString += i;
JsonArray infoArr = user.createNestedArray(uiDomString); // timer value JsonArray infoArr = user.createNestedArray(uiDomString); // timer value
@ -507,7 +507,7 @@ class MultiRelay : public Usermod {
} }
#if MULTI_RELAY_MAX_RELAYS > 1 #if MULTI_RELAY_MAX_RELAYS > 1
JsonArray rel_arr = multiRelay.createNestedArray(F("relays")); JsonArray rel_arr = multiRelay.createNestedArray(F("relays"));
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) { for (int i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
if (_relay[i].pin < 0) continue; if (_relay[i].pin < 0) continue;
JsonObject relay = rel_arr.createNestedObject(); JsonObject relay = rel_arr.createNestedObject();
relay[FPSTR(_relay_str)] = i; relay[FPSTR(_relay_str)] = i;
@ -527,14 +527,24 @@ class MultiRelay : public Usermod {
if (!initDone || !enabled) return; // prevent crash on boot applyPreset() if (!initDone || !enabled) return; // prevent crash on boot applyPreset()
JsonObject usermod = root[FPSTR(_name)]; JsonObject usermod = root[FPSTR(_name)];
if (!usermod.isNull()) { if (!usermod.isNull()) {
if (usermod["on"].is<bool>() && usermod[FPSTR(_relay_str)].is<int>() && usermod[FPSTR(_relay_str)].as<int>()>=0) { if (usermod[FPSTR(_relay_str)].is<int>() && usermod[FPSTR(_relay_str)].as<int>()>=0) {
switchRelay(usermod[FPSTR(_relay_str)].as<int>(), usermod["on"].as<bool>()); int rly = usermod[FPSTR(_relay_str)].as<int>();
if (usermod["on"].is<bool>()) {
switchRelay(rly, usermod["on"].as<bool>());
} else if (usermod["on"].is<const char*>() && usermod["on"].as<const char*>()[0] == 't') {
toggleRelay(rly);
}
} }
} else if (root[FPSTR(_name)].is<JsonArray>()) { } else if (root[FPSTR(_name)].is<JsonArray>()) {
JsonArray relays = root[FPSTR(_name)].as<JsonArray>(); JsonArray relays = root[FPSTR(_name)].as<JsonArray>();
for (JsonVariant r : relays) { for (JsonVariant r : relays) {
if (r["on"].is<bool>() && r[FPSTR(_relay_str)].is<int>() && r[FPSTR(_relay_str)].as<int>()>=0) { if (r[FPSTR(_relay_str)].is<int>() && r[FPSTR(_relay_str)].as<int>()>=0) {
switchRelay(r[FPSTR(_relay_str)].as<int>(), r["on"].as<bool>()); int rly = r[FPSTR(_relay_str)].as<int>();
if (r["on"].is<bool>()) {
switchRelay(rly, r["on"].as<bool>());
} else if (r["on"].is<const char*>() && r["on"].as<const char*>()[0] == 't') {
toggleRelay(rly);
}
} }
} }
} }
@ -548,7 +558,7 @@ class MultiRelay : public Usermod {
top[FPSTR(_enabled)] = enabled; top[FPSTR(_enabled)] = enabled;
top[FPSTR(_broadcast)] = periodicBroadcastSec; top[FPSTR(_broadcast)] = periodicBroadcastSec;
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) { for (int i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
String parName = FPSTR(_relay_str); parName += '-'; parName += i; String parName = FPSTR(_relay_str); parName += '-'; parName += i;
JsonObject relay = top.createNestedObject(parName); JsonObject relay = top.createNestedObject(parName);
relay["pin"] = _relay[i].pin; relay["pin"] = _relay[i].pin;
@ -582,7 +592,7 @@ class MultiRelay : public Usermod {
periodicBroadcastSec = min(900,max(0,(int)periodicBroadcastSec)); periodicBroadcastSec = min(900,max(0,(int)periodicBroadcastSec));
HAautodiscovery = top[FPSTR(_HAautodiscovery)] | HAautodiscovery; HAautodiscovery = top[FPSTR(_HAautodiscovery)] | HAautodiscovery;
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) { for (int i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
String parName = FPSTR(_relay_str); parName += '-'; parName += i; String parName = FPSTR(_relay_str); parName += '-'; parName += i;
oldPin[i] = _relay[i].pin; oldPin[i] = _relay[i].pin;
_relay[i].pin = top[parName]["pin"] | _relay[i].pin; _relay[i].pin = top[parName]["pin"] | _relay[i].pin;
@ -606,12 +616,12 @@ class MultiRelay : public Usermod {
DEBUG_PRINTLN(F(" config loaded.")); DEBUG_PRINTLN(F(" config loaded."));
} else { } else {
// deallocate all pins 1st // deallocate all pins 1st
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) for (int i=0; i<MULTI_RELAY_MAX_RELAYS; i++)
if (oldPin[i]>=0) { if (oldPin[i]>=0) {
pinManager.deallocatePin(oldPin[i], PinOwner::UM_MultiRelay); pinManager.deallocatePin(oldPin[i], PinOwner::UM_MultiRelay);
} }
// allocate new pins // allocate new pins
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) { for (int i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
if (_relay[i].pin>=0 && pinManager.allocatePin(_relay[i].pin, true, PinOwner::UM_MultiRelay)) { if (_relay[i].pin>=0 && pinManager.allocatePin(_relay[i].pin, true, PinOwner::UM_MultiRelay)) {
if (!_relay[i].external) { if (!_relay[i].external) {
_relay[i].state = !offMode; _relay[i].state = !offMode;

View File

@ -402,10 +402,12 @@ class FourLineDisplayUsermod : public Usermod {
else u8x8 = (U8X8 *) new U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA else u8x8 = (U8X8 *) new U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
break; break;
case SSD1306_SPI: case SSD1306_SPI:
// u8x8 uses global SPI variable that is attached to VSPI bus on ESP32
if (!isHW) u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_4W_SW_SPI(ioPin[0], ioPin[1], ioPin[2], ioPin[3], ioPin[4]); if (!isHW) u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_4W_SW_SPI(ioPin[0], ioPin[1], ioPin[2], ioPin[3], ioPin[4]);
else u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_4W_HW_SPI(ioPin[2], ioPin[3], ioPin[4]); // Pins are cs, dc, reset else u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_4W_HW_SPI(ioPin[2], ioPin[3], ioPin[4]); // Pins are cs, dc, reset
break; break;
case SSD1306_SPI64: case SSD1306_SPI64:
// u8x8 uses global SPI variable that is attached to VSPI bus on ESP32
if (!isHW) u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_SW_SPI(ioPin[0], ioPin[1], ioPin[2], ioPin[3], ioPin[4]); if (!isHW) u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_SW_SPI(ioPin[0], ioPin[1], ioPin[2], ioPin[3], ioPin[4]);
else u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_HW_SPI(ioPin[2], ioPin[3], ioPin[4]); // Pins are cs, dc, reset else u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_HW_SPI(ioPin[2], ioPin[3], ioPin[4]); // Pins are cs, dc, reset
break; break;
@ -1052,10 +1054,25 @@ class FourLineDisplayUsermod : public Usermod {
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings! * I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
*/ */
void addToConfig(JsonObject& root) { void addToConfig(JsonObject& root) {
// determine if we are using global HW pins (data & clock)
int8_t hw_dta, hw_clk;
if ((type == SSD1306_SPI || type == SSD1306_SPI64)) {
hw_clk = spi_sclk<0 ? HW_PIN_CLOCKSPI : spi_sclk;
hw_dta = spi_mosi<0 ? HW_PIN_DATASPI : spi_mosi;
} else {
hw_clk = i2c_scl<0 ? HW_PIN_SCL : i2c_scl;
hw_dta = i2c_sda<0 ? HW_PIN_SDA : i2c_sda;
}
JsonObject top = root.createNestedObject(FPSTR(_name)); JsonObject top = root.createNestedObject(FPSTR(_name));
top[FPSTR(_enabled)] = enabled; top[FPSTR(_enabled)] = enabled;
JsonArray io_pin = top.createNestedArray("pin"); JsonArray io_pin = top.createNestedArray("pin");
for (byte i=0; i<5; i++) io_pin.add(ioPin[i]); for (int i=0; i<5; i++) {
if (i==0 && ioPin[i]==hw_clk) io_pin.add(-1); // do not store global HW pin
else if (i==1 && ioPin[i]==hw_dta) io_pin.add(-1); // do not store global HW pin
else io_pin.add(ioPin[i]);
}
top["type"] = type; top["type"] = type;
top[FPSTR(_flip)] = (bool) flip; top[FPSTR(_flip)] = (bool) flip;
top[FPSTR(_contrast)] = contrast; top[FPSTR(_contrast)] = contrast;

View File

@ -1982,11 +1982,11 @@ uint16_t mode_fire_2012()
uint8_t cool = random8((((20 + SEGMENT.speed/3) * 16) / SEGLEN)+2); uint8_t cool = random8((((20 + SEGMENT.speed/3) * 16) / SEGLEN)+2);
uint8_t minTemp = 0; uint8_t minTemp = 0;
if (i<ignition) { if (i<ignition) {
cool /= (ignition-i); // ignition area cools slower cool /= (ignition-i)/3 + 1; // ignition area cools slower
minTemp = 4*(ignition-i) + 8; // and should not become black minTemp = (ignition-i)/4 + 16; // and should not become black
} }
uint8_t temp = qsub8(heat[i], cool); uint8_t temp = qsub8(heat[i], cool);
heat[i] = i<ignition && temp<minTemp ? minTemp : temp; // prevent ignition area from becoming black heat[i] = temp<minTemp ? minTemp : temp;
} }
// Step 2. Heat from each cell drifts 'up' and diffuses a little // Step 2. Heat from each cell drifts 'up' and diffuses a little

View File

@ -388,7 +388,7 @@ typedef struct Segment {
uint8_t _briT; // temporary brightness uint8_t _briT; // temporary brightness
uint8_t _cctT; // temporary CCT uint8_t _cctT; // temporary CCT
CRGBPalette16 _palT; // temporary palette CRGBPalette16 _palT; // temporary palette
uint8_t _prevPaletteBlends; // number of previous palette blends (there are max 128 belnds possible) uint8_t _prevPaletteBlends; // number of previous palette blends (there are max 255 belnds possible)
uint8_t _modeP; // previous mode/effect uint8_t _modeP; // previous mode/effect
//uint16_t _aux0, _aux1; // previous mode/effect runtime data //uint16_t _aux0, _aux1; // previous mode/effect runtime data
//uint32_t _step, _call; // previous mode/effect runtime data //uint32_t _step, _call; // previous mode/effect runtime data

View File

@ -437,8 +437,7 @@ void Segment::nscale8(uint8_t scale) {
const uint16_t cols = virtualWidth(); const uint16_t cols = virtualWidth();
const uint16_t rows = virtualHeight(); const uint16_t rows = virtualHeight();
for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) { for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) {
if (leds) leds[XY(x,y)].nscale8(scale); setPixelColorXY(x, y, CRGB(getPixelColorXY(x, y)).nscale8(scale));
else setPixelColorXY(x, y, CRGB(getPixelColorXY(x, y)).nscale8(scale));
} }
} }
@ -451,7 +450,7 @@ void Segment::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint3
const int16_t dy = abs(y1-y0), sy = y0<y1 ? 1 : -1; const int16_t dy = abs(y1-y0), sy = y0<y1 ? 1 : -1;
int16_t err = (dx>dy ? dx : -dy)/2, e2; int16_t err = (dx>dy ? dx : -dy)/2, e2;
for (;;) { for (;;) {
setPixelColorXY(x0,y0,c); addPixelColorXY(x0,y0,c);
if (x0==x1 && y0==y1) break; if (x0==x1 && y0==y1) break;
e2 = err; e2 = err;
if (e2 >-dx) { err -= dy; x0 += sx; } if (e2 >-dx) { err -= dy; x0 += sx; }
@ -466,7 +465,7 @@ void Segment::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint3
#include "src/font/console_font_7x9.h" #include "src/font/console_font_7x9.h"
// draws a raster font character on canvas // draws a raster font character on canvas
// only supports 5x8=40, 5x12=60, 6x8=48 and 7x9=63 fonts ATM // only supports: 4x6=24, 5x8=40, 5x12=60, 6x8=48 and 7x9=63 fonts ATM
void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color) { void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color) {
if (chr < 32 || chr > 126) return; // only ASCII 32-126 supported if (chr < 32 || chr > 126) return; // only ASCII 32-126 supported
chr -= 32; // align with font table entries chr -= 32; // align with font table entries
@ -491,7 +490,7 @@ void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w,
for (int j = 0; j<w; j++) { // character width for (int j = 0; j<w; j++) { // character width
int16_t x0 = x + (w-1) - j; int16_t x0 = x + (w-1) - j;
if ((x0 >= 0 || x0 < cols) && ((bits>>(j+(8-w))) & 0x01)) { // bit set & drawing on-screen if ((x0 >= 0 || x0 < cols) && ((bits>>(j+(8-w))) & 0x01)) { // bit set & drawing on-screen
setPixelColorXY(x0, y0, color); addPixelColorXY(x0, y0, color);
} }
} }
} }

View File

@ -829,10 +829,9 @@ class PolyBus {
#ifdef ESP8266 #ifdef ESP8266
if (pins[0] == P_8266_HS_MOSI && pins[1] == P_8266_HS_CLK) isHSPI = true; if (pins[0] == P_8266_HS_MOSI && pins[1] == P_8266_HS_CLK) isHSPI = true;
#else #else
// temporary hack to limit use of hardware SPI to a single SPI peripheral: only allow ESP32 hardware serial on segment 0 // temporary hack to limit use of hardware SPI to a single SPI peripheral (HSPI): only allow ESP32 hardware serial on segment 0
// SPI global variable is normally linked to VSPI on ESP32 (or FSPI C3, S3)
if (!num) isHSPI = true; if (!num) isHSPI = true;
//if (num==0 && pins[0] == P_32_VS_MOSI && pins[1] == P_32_VS_CLK) isHSPI = true; // no nultiplexing, up to 80MHz clock
//if (num==1 && pins[0] == P_32_HS_MOSI && pins[1] == P_32_HS_CLK) isHSPI = true;
#endif #endif
uint8_t t = I_NONE; uint8_t t = I_NONE;
switch (busType) { switch (busType) {

View File

@ -286,7 +286,11 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
CJSON(spi_miso, hw_if_spi[2]); CJSON(spi_miso, hw_if_spi[2]);
PinManagerPinType spi[3] = { { spi_mosi, true }, { spi_miso, true }, { spi_sclk, true } }; PinManagerPinType spi[3] = { { spi_mosi, true }, { spi_miso, true }, { spi_sclk, true } };
if (spi_mosi >= 0 && spi_sclk >= 0 && pinManager.allocateMultiplePins(spi, 3, PinOwner::HW_SPI)) { if (spi_mosi >= 0 && spi_sclk >= 0 && pinManager.allocateMultiplePins(spi, 3, PinOwner::HW_SPI)) {
// do not initialise bus here #ifdef ESP32
SPI.begin(spi_sclk, spi_miso, spi_mosi); // SPI global uses VSPI on ESP32 and FSPI on C3, S3
#else
SPI.begin();
#endif
} else { } else {
spi_mosi = -1; spi_mosi = -1;
spi_miso = -1; spi_miso = -1;

View File

@ -287,22 +287,13 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
bool stateResponse = root[F("v")] | false; bool stateResponse = root[F("v")] | false;
bool onBefore = bri; bool onBefore = bri;
uint8_t tmpBri = bri; getVal(root["bri"], &bri);
getVal(root["bri"], &tmpBri);
if (root["on"].isNull()) { bool on = root["on"] | (bri > 0);
if ((onBefore && tmpBri==0) || (!onBefore && tmpBri>0)) toggleOnOff(); if (!on != !bri) toggleOnOff();
bri = tmpBri;
} else { if (root["on"].is<const char*>() && root["on"].as<const char*>()[0] == 't') {
bool on = root["on"] | onBefore; if (onBefore || !bri) toggleOnOff(); // do not toggle off again if just turned on by bri (makes e.g. "{"on":"t","bri":32}" work)
if (on != onBefore || (root["on"].is<const char*>() && root["on"].as<const char*>()[0] == 't')) {
toggleOnOff();
// a hack is needed after toggleOnOf()
if (!root["bri"].isNull()) {
if (bri==0) briLast = tmpBri;
else bri = tmpBri;
}
}
} }
if (bri && !onBefore) { // unfreeze all segments when turning on if (bri && !onBefore) { // unfreeze all segments when turning on
@ -433,9 +424,12 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
if (root["win"].isNull()) presetCycCurr = currentPreset; if (root["win"].isNull()) presetCycCurr = currentPreset;
stateChanged = false; // cancel state change update (preset was set directly by applying values stored in UI JSON array) stateChanged = false; // cancel state change update (preset was set directly by applying values stored in UI JSON array)
} else if (root["win"].isNull() && getVal(root["ps"], &ps, 0, 0) && ps > 0 && ps < 251 && ps != currentPreset) { } else if (root["win"].isNull() && getVal(root["ps"], &ps, 0, 0) && ps > 0 && ps < 251 && ps != currentPreset) {
// b) preset ID only (use embedded cycling limits if they exist in getVal()) // b) preset ID only or preset that does not change state (use embedded cycling limits if they exist in getVal())
presetCycCurr = ps; presetCycCurr = ps;
applyPreset(ps, callMode); // async load root.remove(F("v")); // may be added in UI call
root.remove(F("time")); // may be added in UI call
root.remove("ps");
if (root.size() == 0) applyPreset(ps, callMode); // async load (only preset ID was specified)
return stateResponse; return stateResponse;
} }
} }

View File

@ -63,6 +63,7 @@ void toggleOnOff()
briLast = bri; briLast = bri;
bri = 0; bri = 0;
} }
stateChanged = true;
} }

View File

@ -515,7 +515,13 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
spi_mosi = hw_mosi_pin; spi_mosi = hw_mosi_pin;
spi_miso = hw_miso_pin; spi_miso = hw_miso_pin;
spi_sclk = hw_sclk_pin; spi_sclk = hw_sclk_pin;
// no bus initialisation // no bus re-initialisation as usermods do not get any notification
//SPI.end();
#ifdef ESP32
//SPI.begin(spi_sclk, spi_miso, spi_mosi);
#else
//SPI.begin();
#endif
} else { } else {
//SPI.end(); //SPI.end();
DEBUG_PRINTLN(F("Could not allocate SPI pins.")); DEBUG_PRINTLN(F("Could not allocate SPI pins."));

View File

@ -8,7 +8,7 @@
*/ */
// version code in format yymmddb (b = daily build) // version code in format yymmddb (b = daily build)
#define VERSION 2209061 #define VERSION 2209091
//uncomment this if you have a "my_config.h" file you'd like to use //uncomment this if you have a "my_config.h" file you'd like to use
//#define WLED_USE_MY_CONFIG //#define WLED_USE_MY_CONFIG