From bb8d5ac13ffd74119e96643e5595d37ba9d6673f Mon Sep 17 00:00:00 2001 From: Blaz Kristan Date: Sun, 17 Jan 2021 00:20:31 +0100 Subject: [PATCH 1/9] Dynamic allocation for bus manager. --- wled00/FX.h | 38 ++----- wled00/FX_fcn.cpp | 0 wled00/button.cpp | 53 +++++----- wled00/cfg.cpp | 162 +++++++++++++++++------------ wled00/data/settings_leds.htm | 188 +++++++++++++++++++++++++++++----- wled00/html_settings.h | 80 +++++++++------ wled00/ir.cpp | 2 +- wled00/set.cpp | 129 ++++++++++++++++++++--- wled00/wled.cpp | 61 +++++------ wled00/wled.h | 46 +++++++-- wled00/xml.cpp | 69 +++++++++++-- 11 files changed, 585 insertions(+), 243 deletions(-) mode change 100644 => 100755 wled00/FX.h mode change 100644 => 100755 wled00/FX_fcn.cpp mode change 100644 => 100755 wled00/data/settings_leds.htm mode change 100644 => 100755 wled00/wled.cpp mode change 100644 => 100755 wled00/xml.cpp diff --git a/wled00/FX.h b/wled00/FX.h old mode 100644 new mode 100755 index cdab2336..2a3c1869 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -27,36 +27,6 @@ #ifndef WS2812FX_h #define WS2812FX_h -//TEMPORARY DEFINES FOR TESTING - MAKE THESE RUNTIME CONFIGURABLE TOO! -#ifndef LEDPIN -#define LEDPIN 2 -#endif - -#ifndef BTNPIN -#define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended) -#endif - -#ifndef TOUCHPIN -//#define TOUCHPIN T0 //touch pin. Behaves the same as button. ESP32 only. -#endif - -#ifndef IRPIN -#define IRPIN 4 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0 -#endif - -#ifndef RLYPIN -#define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,... -#endif - -#ifndef AUXPIN -#define AUXPIN -1 //debug auxiliary output pin (-1 to disable) -#endif - -#ifndef RLYMDE -#define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on -#endif -//END OF TEMP DEFINES - #ifdef ESP32_MULTISTRIP #include "../usermods/esp32_multistrip/NpbWrapper.h" #else @@ -659,6 +629,8 @@ class WS2812FX { paletteFade = 0, paletteBlend = 0, milliampsPerLed = 55, +// getStripType(uint8_t strip=0), +// setStripType(uint8_t type, uint8_t strip=0), getBrightness(void), getMode(void), getSpeed(void), @@ -673,11 +645,17 @@ class WS2812FX { get_random_wheel_index(uint8_t); int8_t +// setStripPin(uint8_t strip, int8_t pin), +// getStripPin(uint8_t strip=0), +// setStripPinClk(uint8_t strip, int8_t pin), +// getStripPinClk(uint8_t strip=0), tristate_square8(uint8_t x, uint8_t pulsewidth, uint8_t attdec); uint16_t ablMilliampsMax, currentMilliamps, +// setStripLen(uint8_t strip, uint16_t len), +// getStripLen(uint8_t strip=0), triwave16(uint16_t); uint32_t diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp old mode 100644 new mode 100755 diff --git a/wled00/button.cpp b/wled00/button.cpp index 7adbf68b..d774137e 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -17,9 +17,7 @@ void shortPressAction() bool isButtonPressed() { - #if defined(BTNPIN) && BTNPIN > -1 - if (digitalRead(BTNPIN) == LOW) return true; - #endif + if (btnPin>=0 && digitalRead(btnPin) == LOW) return true; #ifdef TOUCHPIN if (touchRead(TOUCHPIN) <= TOUCH_THRESHOLD) return true; #endif @@ -29,8 +27,7 @@ bool isButtonPressed() void handleButton() { -#if (defined(BTNPIN) && BTNPIN > -1) || defined(TOUCHPIN) - if (!buttonEnabled) return; + if (btnPin<0 || !buttonEnabled) return; if (isButtonPressed()) //pressed { @@ -75,7 +72,6 @@ void handleButton() buttonWaitTime = 0; shortPressAction(); } -#endif } void handleIO() @@ -88,37 +84,43 @@ void handleIO() lastOnTime = millis(); if (offMode) { - #if RLYPIN >= 0 - digitalWrite(RLYPIN, RLYMDE); - #endif + if (rlyPin>=0) { + pinMode(rlyPin, OUTPUT); + digitalWrite(rlyPin, rlyMde); + } offMode = false; } } else if (millis() - lastOnTime > 600) { - if (!offMode) { - #if LEDPIN == LED_BUILTIN - pinMode(LED_BUILTIN, OUTPUT); - digitalWrite(LED_BUILTIN, HIGH); + if (!offMode) { + #ifdef ESP8266 + for (uint8_t s=0; s= 0 - digitalWrite(RLYPIN, !RLYMDE); - #endif - } + if (rlyPin>=0) { + pinMode(rlyPin, OUTPUT); + digitalWrite(rlyPin, !rlyMde); + } + } offMode = true; } - #if AUXPIN >= 0 //output - if (auxActive || auxActiveBefore) + if (auxPin>=1 && (auxActive || auxActiveBefore)) { if (!auxActiveBefore) { auxActiveBefore = true; switch (auxTriggeredState) { - case 0: pinMode(AUXPIN, INPUT); break; - case 1: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, HIGH); break; - case 2: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, LOW); break; + case 0: pinMode(auxPin, INPUT); break; + case 1: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, HIGH); break; + case 2: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, LOW); break; } auxStartTime = millis(); } @@ -128,11 +130,10 @@ void handleIO() auxActiveBefore = false; switch (auxDefaultState) { - case 0: pinMode(AUXPIN, INPUT); break; - case 1: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, HIGH); break; - case 2: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, LOW); break; + case 0: pinMode(auxPin, INPUT); break; + case 1: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, HIGH); break; + case 2: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, LOW); break; } } } - #endif } diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 43d2615e..940dde7b 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -89,31 +89,59 @@ void deserializeConfig() { JsonObject hw = doc[F("hw")]; + // initialize LED pins and lengths prior to other HW JsonObject hw_led = hw[F("led")]; - CJSON(ledCount, hw_led[F("total")]); - if (ledCount > MAX_LEDS) ledCount = MAX_LEDS; +// CJSON(ledCount, hw_led[F("total")]); + ledCount = 0; CJSON(strip.ablMilliampsMax, hw_led[F("maxpwr")]); CJSON(strip.milliampsPerLed, hw_led[F("ledma")]); CJSON(strip.reverseMode, hw_led[F("rev")]); CJSON(strip.rgbwMode, hw_led[F("rgbwm")]); - JsonObject hw_led_ins_0 = hw_led[F("ins")][0]; - //bool hw_led_ins_0_en = hw_led_ins_0[F("en")]; // true - //int hw_led_ins_0_start = hw_led_ins_0[F("start")]; // 0 - //int hw_led_ins_0_len = hw_led_ins_0[F("len")]; // 1200 - - //int hw_led_ins_0_pin_0 = hw_led_ins_0[F("pin")][0]; // 2 - - strip.setColorOrder(hw_led_ins_0[F("order")]); - //bool hw_led_ins_0_rev = hw_led_ins_0[F("rev")]; // false - skipFirstLed = hw_led_ins_0[F("skip")]; // 0 - useRGBW = (hw_led_ins_0[F("type")] == TYPE_SK6812_RGBW); + JsonVariant strVar = hw_led["ins"]; + if (strVar.is()) { + // some safety measures here? + } else { + JsonArray elms = strVar.as(); + uint8_t s=0; + for ( JsonObject elm : elms ) { + if (s>=WLED_MAX_BUSSES) break; + int8_t pins[2] = {-1,-1}; + pins[0] = elm[F("pin")][0]; + if (pins[0] >= 0 && pinManager.allocatePin(pins[0])) { + if (elm[F("pin")].size()==2) { + pins[1] = elm[F("pin")][1]; + if (pins[1] >= 0) + if (!pinManager.allocatePin(pins[1])) { + pinManager.deallocatePin(pins[0]); + break; // pin not ok + } + } + } else { + break; // pin not ok + } + uint16_t length = elm[F("len")]); + if (length==0) break; + uint8_t colorOrder = (int)elm[F("order")]; + uint8_t skipFirstLed = elm[F("skip")]; // 0 + uint8_t ledType = elm[F("type")]; + uint8_t useRGBW = ((ledType == TYPE_SK6812_RGBW) || ledType == TYPE_TM1814); + ledCount += length; + busses->add(ledType? TYPE_SK6812_RGBW : TYPE_WS2812_RGB, pins, 0, ledCount, colorOrder); + } + } + if (ledCount > MAX_LEDS) ledCount = MAX_LEDS; JsonObject hw_btn_ins_0 = hw[F("btn")][F("ins")][0]; - buttonEnabled = hw_btn_ins_0[F("en")] | buttonEnabled; - - //int hw_btn_ins_0_pin_0 = hw_btn_ins_0[F("pin")][0]; // 0 + CJSON(buttonEnabled, hw_btn_ins_0[F("type")]); + int hw_btn_pin = hw_btn_ins_0[F("pin")][0]; + if (pinManager.allocatePin(hw_btn_pin,false)) { + btnPin = hw_btn_pin; + pinMode(btnPin, INPUT_PULLUP); + } else { + btnPin = -1; + } JsonArray hw_btn_ins_0_macros = hw_btn_ins_0[F("macros")]; CJSON(macroButton, hw_btn_ins_0_macros[0]); @@ -122,11 +150,24 @@ void deserializeConfig() { //int hw_btn_ins_0_type = hw_btn_ins_0[F("type")]; // 0 - //int hw_ir_pin = hw[F("ir")][F("pin")]; // 4 - CJSON(irEnabled, hw[F("ir")][F("type")]); // 0 + #ifndef WLED_DISABLE_INFRARED + int hw_ir_pin = hw[F("ir")][F("pin")]; // 4 + if (pinManager.allocatePin(hw_ir_pin,false)) { + irPin = hw_ir_pin; + } else { + irPin = -1; + } + #endif + CJSON(irEnabled, hw[F("ir")][F("type")]); - //int hw_relay_pin = hw[F("relay")][F("pin")]; // 12 - //bool hw_relay_rev = hw[F("relay")][F("rev")]; // false + int hw_relay_pin = hw[F("relay")][F("pin")]; + if (pinManager.allocatePin(hw_relay_pin,true)) { + rlyPin = hw_relay_pin; + pinMode(rlyPin, OUTPUT); + } else { + rlyPin = -1; + } + CJSON(rlyMde, hw[F("relay")][F("rev")]); //int hw_status_pin = hw[F("status")][F("pin")]; // -1 @@ -404,70 +445,57 @@ void serializeConfig() { JsonArray hw_led_ins = hw_led.createNestedArray("ins"); - JsonObject hw_led_ins_0 = hw_led_ins.createNestedObject(); - hw_led_ins_0[F("en")] = true; - hw_led_ins_0[F("start")] = 0; - hw_led_ins_0[F("len")] = ledCount; - JsonArray hw_led_ins_0_pin = hw_led_ins_0.createNestedArray("pin"); - hw_led_ins_0_pin.add(LEDPIN); - #ifdef DATAPIN - hw_led_ins_0_pin.add(DATAPIN); - #endif - hw_led_ins_0[F("order")] = strip.getColorOrder(); - hw_led_ins_0[F("rev")] = false; - hw_led_ins_0[F("skip")] = skipFirstLed ? 1 : 0; - - //this is very crude and temporary - byte ledType = TYPE_WS2812_RGB; - if (useRGBW) ledType = TYPE_SK6812_RGBW; - #ifdef USE_WS2801 - ledType = TYPE_WS2801; - #endif - #ifdef USE_APA102 - ledType = TYPE_APA102; - #endif - #ifdef USE_LPD8806 - ledType = TYPE_LPD8806; - #endif - #ifdef USE_P9813 - ledType = TYPE_P9813; - #endif - #ifdef USE_TM1814 - ledType = TYPE_TM1814; - #endif - - hw_led_ins_0[F("type")] = ledType; + uint16_t start = 0; + for (uint8_t s=0; sgetNumBusses(); s++) { + Bus *bus = busses->getBus(s); + if (!bus || bus->getLength()==0) break; + JsonObject hw_led_ins_0 = hw_led_ins.createNestedObject(); + hw_led_ins_0[F("en")] = true; + hw_led_ins_0[F("start")] = start; + start += bus->getLength(); + hw_led_ins_0[F("len")] = bus->getLength(); + JsonArray hw_led_ins_0_pin = hw_led_ins_0.createNestedArray("pin"); + hw_led_ins_0_pin.add(bus->getBusPins(s)[0]); + if (bus->getBusPins(s)[1]>=0) hw_led_ins_0_pin.add(bus->getBusPins(s)[1]); + hw_led_ins_0[F("order")] = bus->getColorOrder(); + hw_led_ins_0[F("rev")] = false; + hw_led_ins_0[F("skip")] = skipFirstLed ? 1 : 0; + hw_led_ins_0[F("type")] = bus->getType(); + } JsonObject hw_btn = hw.createNestedObject("btn"); JsonArray hw_btn_ins = hw_btn.createNestedArray("ins"); - #if defined(BTNPIN) && BTNPIN > -1 + // button BTNPIN JsonObject hw_btn_ins_0 = hw_btn_ins.createNestedObject(); hw_btn_ins_0[F("type")] = (buttonEnabled) ? BTN_TYPE_PUSH : BTN_TYPE_NONE; JsonArray hw_btn_ins_0_pin = hw_btn_ins_0.createNestedArray("pin"); - hw_btn_ins_0_pin.add(BTNPIN); + hw_btn_ins_0_pin.add(btnPin); JsonArray hw_btn_ins_0_macros = hw_btn_ins_0.createNestedArray("macros"); hw_btn_ins_0_macros.add(macroButton); hw_btn_ins_0_macros.add(macroLongPress); hw_btn_ins_0_macros.add(macroDoublePress); + + #ifndef WLED_DISABLE_INFRARED + if (irPin>=0) { + JsonObject hw_ir = hw.createNestedObject("ir"); + hw_ir[F("pin")] = irPin; + hw_ir[F("type")] = irEnabled; // the byte 'irEnabled' does contain the IR-Remote Type ( 0=disabled ) + } #endif - #if defined(IRPIN) && IRPIN > -1 - JsonObject hw_ir = hw.createNestedObject("ir"); - hw_ir[F("pin")] = IRPIN; - hw_ir[F("type")] = irEnabled; // the byte 'irEnabled' does contain the IR-Remote Type ( 0=disabled ) - #endif - - #if defined(RLYPIN) && RLYPIN > -1 JsonObject hw_relay = hw.createNestedObject("relay"); - hw_relay[F("pin")] = RLYPIN; - hw_relay[F("rev")] = (RLYMDE) ? false : true; - JsonObject hw_status = hw.createNestedObject("status"); - hw_status[F("pin")] = -1; - #endif + hw_relay[F("pin")] = rlyPin; + hw_relay[F("rev")] = rlyMde; + + //JsonObject hw_status = hw.createNestedObject("status"); + //hw_status[F("pin")] = -1; + + JsonObject hw_aux = hw.createNestedObject("aux"); + hw_aux[F("pin")] = auxPin; JsonObject light = doc.createNestedObject("light"); light[F("scale-bri")] = briMultiplier; diff --git a/wled00/data/settings_leds.htm b/wled00/data/settings_leds.htm old mode 100644 new mode 100755 index 6a0dee0a..2b2625f0 --- a/wled00/data/settings_leds.htm +++ b/wled00/data/settings_leds.htm @@ -52,13 +52,53 @@ myC[i].style.display = (d.getElementById('rgbw').checked) ? 'inline':'none'; } - d.getElementById('ledwarning').style.display = (d.Sf.LC.value > 1000) ? 'inline':'none'; d.getElementById('ampwarning').style.display = (d.Sf.MA.value > 7200) ? 'inline':'none'; - if (d.Sf.LA.value == 255) laprev = 12; - else if (d.Sf.LA.value > 0) laprev = d.Sf.LA.value; - - var val = Math.ceil((100 + d.Sf.LC.value * laprev)/500)/2; + if (d.Sf.LA.value == 255) laprev = 12; + else if (d.Sf.LA.value > 0) laprev = d.Sf.LA.value; + + var s = d.getElementsByTagName("select"); + for (i=0; i49 && s[i].value!=54) // TYPE_xxxx values from const.h + { + o[n].style = "display:inline;"; + LK.required = true; + } else { + o[n].style = "display:none;"; + LK.required = false; + LK.value=""; + } + } + } + + var LCs = d.getElementsByTagName("input"); + var sLC = 0; + for (i=0; ie==parseInt(LCs[i].value,10))) {alert("Usermod pin clash!");LCs[i].value="";LCs[i].focus();continue;} + for (j=0; j 1000) ? 'inline':'none'; + + //var val = Math.ceil((100 + d.Sf.LC.value * laprev)/500)/2; + var val = Math.ceil((100 + sLC * laprev)/500)/2; val = (val > 5) ? Math.ceil(val) : val; var s = ""; var is12V = (d.Sf.LAsel.value == 30); @@ -79,11 +119,91 @@ s2 += "A is enough)
"; d.getElementById('psu').innerHTML = s; d.getElementById('psu2').innerHTML = isWS2815 ? "" : s2; - } + } + function addLEDs(n) + { + if (n>1) {d.maxST=n; d.getElementById("+").style="display:inline;"; return;} + + var o = d.getElementsByName("iST"); + var i = o.length; + + if ((n==1 && i>=d.maxST) || (n==-1 && i<=1)) return; + + var f = d.getElementById("mLC"); + if (n==1) { + var s, t = d.createElement("div"); + t.setAttribute("name","iST"); + + t.appendChild(d.createTextNode((i+1)+": ")); + + s = d.createElement("select"); + s.setAttribute("name","LTsel"+i); + s.onchange = function(){UI()} + o = d.createElement("option"); o.text = "WS281x"; o.value = "22"; s.add(o); + o = d.createElement("option"); o.text = "SK6812"; o.value = "30"; s.add(o); + o = d.createElement("option"); o.text = "WS2801"; o.value = "50"; s.add(o); + o = d.createElement("option"); o.text = "APA102"; o.value = "51"; s.add(o); + o = d.createElement("option"); o.text = "LPD8806"; o.value = "52"; s.add(o); + o = d.createElement("option"); o.text = "P9813"; o.value = "53"; s.add(o); + o = d.createElement("option"); o.text = "TM1814"; o.value = "54"; s.add(o); + t.appendChild(s); + + t.appendChild(d.createTextNode(" CO: ")); + s = d.createElement("select"); + s.setAttribute("name","CO"+i); + o = d.createElement("option"); o.text = "GRB"; o.value = "0"; s.add(o); + o = d.createElement("option"); o.text = "RGB"; o.value = "1"; s.add(o); + o = d.createElement("option"); o.text = "BRG"; o.value = "2"; s.add(o); + o = d.createElement("option"); o.text = "RBG"; o.value = "3"; s.add(o); + o = d.createElement("option"); o.text = "BGR"; o.value = "4"; s.add(o); + o = d.createElement("option"); o.text = "GBR"; o.value = "5"; s.add(o); + t.appendChild(s); + + t.appendChild(d.createTextNode(" RGBW: ")); + s = d.createElement("input"); + s.type = "checkbox"; + s.setAttribute("name","EW"+i); + t.appendChild(s); + + t.appendChild(d.createElement("br")); + + t.appendChild(d.createTextNode("pin:")); + var e = d.createElement("input"); + e.type = "number"; e.value = ""; e.name = "LP"+i; e.min=0; e.max=40; e.required=true; e.onchange=function(){UI()}; + t.appendChild(e); + + var b = d.createElement("div"); + b.setAttribute("name","iLK"); + b.appendChild(d.createTextNode(" clk:")); + e = d.createElement("input"); + e.type = "number"; e.value = ""; e.name = "LK"+i; e.min=0; e.max=40; e.onchange=function(){UI()}; + if (d.getElementsByName("LTsel")[0].value>49) e.required = true; + b.appendChild(e); + t.appendChild(b); + + t.appendChild(d.createTextNode(" count:")); + e = d.createElement("input"); + e.type = "number"; e.value = "0"; e.name = "LC"+i; e.min=0; e.max=1000; e.required=true; e.oninput = function(){UI()}; + t.appendChild(e); + + t.appendChild(d.createElement("br")); + f.appendChild(t); + } + if (n==-1) { + o[--i].remove();--i; + } + + var p = d.getElementById("+"); + var m = d.getElementById("-"); + if (i0) {m.style="display:inline";} else {m.style="display:none";} + + UI(); + } function GetV() { - //values injected by server while sending HTML - } + //values injected by server while sending HTML + }