Preset loading tuning.
Multi-relay toggle support. Fire2012 tuning. 2D functions tuning. Global SPI comments & tuning. Bugfix in 4LD usermod.
This commit is contained in:
parent
4480abc646
commit
c9fd69ceb7
@ -80,7 +80,7 @@ class MultiRelay : public Usermod {
|
||||
void handleOffTimer() {
|
||||
unsigned long now = millis();
|
||||
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].external) toggleRelay(i);
|
||||
_relay[i].active = false;
|
||||
@ -182,7 +182,7 @@ class MultiRelay : public Usermod {
|
||||
*/
|
||||
MultiRelay() {
|
||||
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].delay = 0;
|
||||
_relay[i].mode = false;
|
||||
@ -226,7 +226,7 @@ class MultiRelay : public Usermod {
|
||||
|
||||
uint8_t getActiveRelayCount() {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -268,7 +268,7 @@ class MultiRelay : public Usermod {
|
||||
strcat_P(subuf, PSTR("/relay/#"));
|
||||
mqtt->subscribe(subuf, 0);
|
||||
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;
|
||||
publishMqtt(i); //publish current state
|
||||
}
|
||||
@ -276,7 +276,7 @@ class MultiRelay : public Usermod {
|
||||
}
|
||||
|
||||
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];
|
||||
size_t payload_size;
|
||||
sprintf_P(uid, PSTR("%s_sw%d"), escapedMac.c_str(), i);
|
||||
@ -320,7 +320,7 @@ class MultiRelay : public Usermod {
|
||||
*/
|
||||
void 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 (!pinManager.allocatePin(_relay[i].pin,true, PinOwner::UM_MultiRelay)) {
|
||||
_relay[i].pin = -1; // allocation failed
|
||||
@ -357,7 +357,7 @@ class MultiRelay : public Usermod {
|
||||
if (_oldMode != offMode) {
|
||||
_oldMode = offMode;
|
||||
_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;
|
||||
}
|
||||
}
|
||||
@ -382,7 +382,7 @@ class MultiRelay : public Usermod {
|
||||
}
|
||||
|
||||
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) {
|
||||
handled = true;
|
||||
}
|
||||
@ -402,8 +402,8 @@ class MultiRelay : public Usermod {
|
||||
if (buttonLongPressed[b] == buttonPressedBefore[b]) return handled;
|
||||
|
||||
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++) {
|
||||
if (_relay[i].pin>=0 && _relay[i].button == b) {
|
||||
for (int i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
|
||||
if (_relay[i].button == b) {
|
||||
switchRelay(i, buttonPressedBefore[b]);
|
||||
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]) {
|
||||
buttonWaitTime[b] = 0;
|
||||
//shortPressAction(b); //not exposed
|
||||
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
|
||||
if (_relay[i].pin>=0 && _relay[i].button == b) {
|
||||
for (int i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
|
||||
if (_relay[i].button == b) {
|
||||
toggleRelay(i);
|
||||
}
|
||||
}
|
||||
@ -473,7 +473,7 @@ class MultiRelay : public Usermod {
|
||||
infoArr.add(F(" relays"));
|
||||
|
||||
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;
|
||||
uiDomString = F("Relay "); uiDomString += i;
|
||||
JsonArray infoArr = user.createNestedArray(uiDomString); // timer value
|
||||
@ -507,7 +507,7 @@ class MultiRelay : public Usermod {
|
||||
}
|
||||
#if MULTI_RELAY_MAX_RELAYS > 1
|
||||
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;
|
||||
JsonObject relay = rel_arr.createNestedObject();
|
||||
relay[FPSTR(_relay_str)] = i;
|
||||
@ -527,14 +527,24 @@ class MultiRelay : public Usermod {
|
||||
if (!initDone || !enabled) return; // prevent crash on boot applyPreset()
|
||||
JsonObject usermod = root[FPSTR(_name)];
|
||||
if (!usermod.isNull()) {
|
||||
if (usermod["on"].is<bool>() && usermod[FPSTR(_relay_str)].is<int>() && usermod[FPSTR(_relay_str)].as<int>()>=0) {
|
||||
switchRelay(usermod[FPSTR(_relay_str)].as<int>(), usermod["on"].as<bool>());
|
||||
if (usermod[FPSTR(_relay_str)].is<int>() && usermod[FPSTR(_relay_str)].as<int>()>=0) {
|
||||
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>()) {
|
||||
JsonArray relays = root[FPSTR(_name)].as<JsonArray>();
|
||||
for (JsonVariant r : relays) {
|
||||
if (r["on"].is<bool>() && r[FPSTR(_relay_str)].is<int>() && r[FPSTR(_relay_str)].as<int>()>=0) {
|
||||
switchRelay(r[FPSTR(_relay_str)].as<int>(), r["on"].as<bool>());
|
||||
if (r[FPSTR(_relay_str)].is<int>() && r[FPSTR(_relay_str)].as<int>()>=0) {
|
||||
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(_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;
|
||||
JsonObject relay = top.createNestedObject(parName);
|
||||
relay["pin"] = _relay[i].pin;
|
||||
@ -582,7 +592,7 @@ class MultiRelay : public Usermod {
|
||||
periodicBroadcastSec = min(900,max(0,(int)periodicBroadcastSec));
|
||||
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;
|
||||
oldPin[i] = _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."));
|
||||
} else {
|
||||
// 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) {
|
||||
pinManager.deallocatePin(oldPin[i], PinOwner::UM_MultiRelay);
|
||||
}
|
||||
// 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].external) {
|
||||
_relay[i].state = !offMode;
|
||||
|
@ -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
|
||||
break;
|
||||
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]);
|
||||
else u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_4W_HW_SPI(ioPin[2], ioPin[3], ioPin[4]); // Pins are cs, dc, reset
|
||||
break;
|
||||
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]);
|
||||
else u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_HW_SPI(ioPin[2], ioPin[3], ioPin[4]); // Pins are cs, dc, reset
|
||||
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!
|
||||
*/
|
||||
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));
|
||||
top[FPSTR(_enabled)] = enabled;
|
||||
|
||||
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[FPSTR(_flip)] = (bool) flip;
|
||||
top[FPSTR(_contrast)] = contrast;
|
||||
|
@ -1982,11 +1982,11 @@ uint16_t mode_fire_2012()
|
||||
uint8_t cool = random8((((20 + SEGMENT.speed/3) * 16) / SEGLEN)+2);
|
||||
uint8_t minTemp = 0;
|
||||
if (i<ignition) {
|
||||
cool /= (ignition-i); // ignition area cools slower
|
||||
minTemp = 4*(ignition-i) + 8; // and should not become black
|
||||
cool /= (ignition-i)/3 + 1; // ignition area cools slower
|
||||
minTemp = (ignition-i)/4 + 16; // and should not become black
|
||||
}
|
||||
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
|
||||
|
@ -388,7 +388,7 @@ typedef struct Segment {
|
||||
uint8_t _briT; // temporary brightness
|
||||
uint8_t _cctT; // temporary CCT
|
||||
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
|
||||
//uint16_t _aux0, _aux1; // previous mode/effect runtime data
|
||||
//uint32_t _step, _call; // previous mode/effect runtime data
|
||||
|
@ -437,8 +437,7 @@ void Segment::nscale8(uint8_t scale) {
|
||||
const uint16_t cols = virtualWidth();
|
||||
const uint16_t rows = virtualHeight();
|
||||
for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) {
|
||||
if (leds) leds[XY(x,y)].nscale8(scale);
|
||||
else setPixelColorXY(x, y, CRGB(getPixelColorXY(x, y)).nscale8(scale));
|
||||
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;
|
||||
int16_t err = (dx>dy ? dx : -dy)/2, e2;
|
||||
for (;;) {
|
||||
setPixelColorXY(x0,y0,c);
|
||||
addPixelColorXY(x0,y0,c);
|
||||
if (x0==x1 && y0==y1) break;
|
||||
e2 = err;
|
||||
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"
|
||||
|
||||
// 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) {
|
||||
if (chr < 32 || chr > 126) return; // only ASCII 32-126 supported
|
||||
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
|
||||
int16_t x0 = x + (w-1) - j;
|
||||
if ((x0 >= 0 || x0 < cols) && ((bits>>(j+(8-w))) & 0x01)) { // bit set & drawing on-screen
|
||||
setPixelColorXY(x0, y0, color);
|
||||
addPixelColorXY(x0, y0, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -829,10 +829,9 @@ class PolyBus {
|
||||
#ifdef ESP8266
|
||||
if (pins[0] == P_8266_HS_MOSI && pins[1] == P_8266_HS_CLK) isHSPI = true;
|
||||
#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==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
|
||||
uint8_t t = I_NONE;
|
||||
switch (busType) {
|
||||
|
@ -286,7 +286,11 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
CJSON(spi_miso, hw_if_spi[2]);
|
||||
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)) {
|
||||
// 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 {
|
||||
spi_mosi = -1;
|
||||
spi_miso = -1;
|
||||
|
@ -424,9 +424,12 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
if (root["win"].isNull()) presetCycCurr = currentPreset;
|
||||
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) {
|
||||
// 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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -63,6 +63,7 @@ void toggleOnOff()
|
||||
briLast = bri;
|
||||
bri = 0;
|
||||
}
|
||||
stateChanged = true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -515,7 +515,13 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
spi_mosi = hw_mosi_pin;
|
||||
spi_miso = hw_miso_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 {
|
||||
//SPI.end();
|
||||
DEBUG_PRINTLN(F("Could not allocate SPI pins."));
|
||||
|
Loading…
Reference in New Issue
Block a user