diff --git a/usermods/Temperature/usermod_temperature.h b/usermods/Temperature/usermod_temperature.h index 05c6159d..1ce0322e 100644 --- a/usermods/Temperature/usermod_temperature.h +++ b/usermods/Temperature/usermod_temperature.h @@ -97,19 +97,14 @@ class UsermodTemperature : public Usermod { } void loop() { - if (disabled || strip.isUpdating()) { - return; - } + if (disabled || strip.isUpdating()) return; unsigned long now = millis(); // check to see if we are due for taking a measurement // lastMeasurement will not be updated until the conversion // is complete the the reading is finished - if (now - lastMeasurement < USERMOD_DALLASTEMPERATURE_MEASUREMENT_INTERVAL) - { - return; - } + if (now - lastMeasurement < USERMOD_DALLASTEMPERATURE_MEASUREMENT_INTERVAL) return; // we are due for a measurement, if we are not already waiting // for a conversion to complete, then make a new request for temps @@ -142,9 +137,7 @@ class UsermodTemperature : public Usermod { void addToJsonInfo(JsonObject& root) { // dont add temperature to info if we are disabled - if (disabled) { - return; - } + if (disabled) return; JsonObject user = root[F("u")]; if (user.isNull()) user = root.createNestedObject(F("u")); @@ -173,32 +166,6 @@ class UsermodTemperature : public Usermod { #endif } - /** - * addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object). - * Values in the state object may be modified by connected clients - * Add "pin_Temperature" to json state. This can be used to check which GPIO pin usermod uses. - */ - void addToJsonState(JsonObject &root) - { - root[F("pin_Temperature")] = TEMPERATURE_PIN; - } - - /** - * readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object). - * Values in the state object may be modified by connected clients - * Read "pin_Temperature" from json state and and change GPIO pin used. - */ - void readFromJsonState(JsonObject &root) - { - /* - if (root[F("pin_Temperature")] != nullptr) - { - if (pinManager.allocatePin((int)root[F("pin_Temperature")],false)) - temperaturePin = (int)root["PIRenabled"]; - } - */ - } - uint16_t getId() { return USERMOD_ID_TEMPERATURE; diff --git a/wled00/FX.h b/wled00/FX.h index 746f9e13..a55bcc7a 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -29,12 +29,6 @@ #ifndef WS2812FX_h #define WS2812FX_h -#ifdef ESP32_MULTISTRIP - #include "../usermods/esp32_multistrip/NpbWrapper.h" -#else - #include "bus_manager.h" -#endif - #include "const.h" #define FASTLED_INTERNAL //remove annoying pragma messages @@ -586,7 +580,6 @@ class WS2812FX { ablMilliampsMax = 850; currentMilliamps = 0; timebase = 0; - busses = new BusManager(); resetSegments(); } @@ -804,8 +797,6 @@ class WS2812FX { mode_dynamic_smooth(void); private: - BusManager *busses; - uint32_t crgb_to_col(CRGB fastled); CRGB col_to_crgb(uint32_t); CRGBPalette16 currentPalette; diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 26181805..9bdd2b92 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -62,11 +62,11 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst) _lengthRaw += LED_SKIP_AMOUNT; } - uint8_t pins[] = {LEDPIN}; + uint8_t pins[] = {2}; - while (!busses->canAllShow()) yield(); - busses->removeAll(); - busses->add(supportWhite? TYPE_SK6812_RGBW : TYPE_WS2812_RGB, pins, 0, countPixels, COL_ORDER_GRB); + while (!busses.canAllShow()) yield(); + busses.removeAll(); + busses.add(supportWhite? TYPE_SK6812_RGBW : TYPE_WS2812_RGB, pins, 0, countPixels, COL_ORDER_GRB); _segments[0].start = 0; _segments[0].stop = _length; @@ -74,8 +74,8 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst) setBrightness(_brightness); #ifdef ESP8266 - for (uint8_t i = 0; i < busses->getNumBusses(); i++) { - Bus* b = busses->getBus(i); + for (uint8_t i = 0; i < busses.getNumBusses(); i++) { + Bus* b = busses.getBus(i); if ((!IS_DIGITAL(b->getType()) || IS_2PIN(b->getType()))) continue; uint8_t pins[5]; b->getPins(pins); @@ -205,12 +205,12 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) if (indexSet < customMappingSize) indexSet = customMappingTable[indexSet]; #endif if (indexSetRev >= SEGMENT.start && indexSetRev < SEGMENT.stop) { - busses->setPixelColor(indexSet + skip, col); + busses.setPixelColor(indexSet + skip, col); if (IS_MIRROR) { //set the corresponding mirrored pixel if (reverseMode) { - busses->setPixelColor(REV(SEGMENT.start) - indexSet + skip + REV(SEGMENT.stop) + 1, col); + busses.setPixelColor(REV(SEGMENT.start) - indexSet + skip + REV(SEGMENT.stop) + 1, col); } else { - busses->setPixelColor(SEGMENT.stop - indexSet + skip + SEGMENT.start - 1, col); + busses.setPixelColor(SEGMENT.stop - indexSet + skip + SEGMENT.start - 1, col); } } } @@ -221,11 +221,11 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) if (i < customMappingSize) i = customMappingTable[i]; #endif uint32_t col = ((w << 24) | (r << 16) | (g << 8) | (b)); - busses->setPixelColor(i + skip, col); + busses.setPixelColor(i + skip, col); } if (skip && i == 0) { for (uint16_t j = 0; j < skip; j++) { - busses->setPixelColor(j, BLACK); + busses.setPixelColor(j, BLACK); } } } @@ -276,7 +276,7 @@ void WS2812FX::show(void) { for (uint16_t i = 0; i < _length; i++) //sum up the usage of each LED { - RgbwColor c = busses->getPixelColor(i); + RgbwColor c = busses.getPixelColor(i); if(useWackyWS2815PowerModel) { @@ -305,24 +305,24 @@ void WS2812FX::show(void) { uint16_t scaleI = scale * 255; uint8_t scaleB = (scaleI > 255) ? 255 : scaleI; uint8_t newBri = scale8(_brightness, scaleB); - busses->setBrightness(newBri); + busses.setBrightness(newBri); currentMilliamps = (powerSum0 * newBri) / puPerMilliamp; } else { currentMilliamps = powerSum / puPerMilliamp; - busses->setBrightness(_brightness); + busses.setBrightness(_brightness); } currentMilliamps += MA_FOR_ESP; //add power of ESP back to estimate currentMilliamps += _length; //add standby power back to estimate } else { currentMilliamps = 0; - busses->setBrightness(_brightness); + busses.setBrightness(_brightness); } // some buses send asynchronously and this method will return before // all of the data has been sent. // See https://github.com/Makuna/NeoPixelBus/wiki/ESP32-NeoMethods#neoesp32rmt-methods - busses->show(); + busses.show(); _lastShow = millis(); } @@ -331,7 +331,7 @@ void WS2812FX::show(void) { * On some hardware (ESP32), strip updates are done asynchronously. */ bool WS2812FX::isUpdating() { - return !busses->canAllShow(); + return !busses.canAllShow(); } /** @@ -492,7 +492,7 @@ uint32_t WS2812FX::getPixelColor(uint16_t i) if (i >= _lengthRaw) return 0; - return busses->getPixelColor(i); + return busses.getPixelColor(i); } WS2812FX::Segment& WS2812FX::getSegment(uint8_t id) { diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index c92d24ec..20898b8a 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -292,8 +292,11 @@ class BusManager { return numBusses -1; } + //do not call this method from system context (network callback) void removeAll() { //Serial.println("Removing all."); + //prevents crashes due to deleting busses while in use. + while (!canAllShow()) yield(); for (uint8_t i = 0; i < numBusses; i++) delete busses[i]; numBusses = 0; } @@ -346,6 +349,12 @@ class BusManager { return numBusses; } + static bool isRgbw(uint8_t type) { + if (type == TYPE_SK6812_RGBW || type == TYPE_TM1814) return true; + if (type > TYPE_ONOFF && type <= TYPE_ANALOG_5CH && type != TYPE_ANALOG_3CH) return true; + return false; + } + private: uint8_t numBusses = 0; Bus* busses[WLED_MAX_BUSSES]; diff --git a/wled00/button.cpp b/wled00/button.cpp index d774137e..458ff22a 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -94,13 +94,9 @@ void handleIO() { if (!offMode) { #ifdef ESP8266 - for (uint8_t s=0; s=0) { pinMode(rlyPin, OUTPUT); diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 940dde7b..8c184d7a 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -92,8 +92,9 @@ void deserializeConfig() { // initialize LED pins and lengths prior to other HW JsonObject hw_led = hw[F("led")]; -// CJSON(ledCount, hw_led[F("total")]); - ledCount = 0; + CJSON(ledCount, hw_led[F("total")]); + if (ledCount > MAX_LEDS) ledCount = MAX_LEDS; + CJSON(strip.ablMilliampsMax, hw_led[F("maxpwr")]); CJSON(strip.milliampsPerLed, hw_led[F("ledma")]); CJSON(strip.reverseMode, hw_led[F("rev")]); @@ -104,32 +105,40 @@ void deserializeConfig() { // 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 + uint8_t s = 0; + useRGBW = false; + busses.removeAll(); + for (JsonObject elm : elms) { + if (s >= WLED_MAX_BUSSES) break; + uint8_t pins[5] = {255, 255, 255, 255, 255}; + JsonArray pinArr = elm[F("pin")]; + if (pinArr.size() == 0) continue; + pins[0] = pinArr[0]; + uint8_t i = 0; + for (int p : pinArr) { + pins[i] = p; + i++; + if (i>4) break; } - uint16_t length = elm[F("len")]); - if (length==0) break; + + uint16_t length = elm[F("len")]; + if (length==0) continue; 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); + //only use skip from the first strip (this shouldn't have been in ins obj. but remains here for compatibility) + if (s==0) skipFirstLed = elm[F("skip")]; + uint16_t start = elm[F("start")] | 0; + if (start >= ledCount) continue; + //limit length of strip if it would exceed total configured LEDs + if (start + length > ledCount) length = ledCount - start; + uint8_t ledType = elm[F("type")] | TYPE_WS2812_RGB; + bool reversed = elm[F("rev")]; + //RGBW mode is enabled if at least one of the strips is RGBW + useRGBW = (useRGBW || BusManager::isRgbw(ledType)); + busses.add(ledType, pins, start, ledCount, colorOrder, reversed); } + //if no bus inited successfully (empty cfg or invalid), init default + uint8_t defPin[] = {LEDPIN}; + busses.add(TYPE_WS2812_RGB, defPin, 0, ledCount, COL_ORDER_GRB); } if (ledCount > MAX_LEDS) ledCount = MAX_LEDS; @@ -446,21 +455,21 @@ void serializeConfig() { JsonArray hw_led_ins = hw_led.createNestedArray("ins"); uint16_t start = 0; - for (uint8_t s=0; sgetNumBusses(); s++) { - Bus *bus = busses->getBus(s); + for (uint8_t s = 0; s < busses.getNumBusses(); 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 ins = hw_led_ins.createNestedObject(); + ins[F("en")] = true; + ins[F("start")] = bus->getStart(); + ins[F("len")] = bus->getLength(); + JsonArray ins_pin = ins.createNestedArray("pin"); + uint8_t pins[5]; + uint8_t nPins = bus->getPins(pins); + for (uint8_t i = 0; i < nPins; i++) ins_pin.add(pins[i]); + ins[F("order")] = bus->getColorOrder(); + ins[F("rev")] = bus->reversed; + ins[F("skip")] = (skipFirstLed && s == 0) ? 1 : 0; + ins[F("type")] = bus->getType(); } JsonObject hw_btn = hw.createNestedObject("btn"); diff --git a/wled00/const.h b/wled00/const.h index 326d3e85..c62d37e5 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -205,4 +205,9 @@ #define JSON_BUFFER_SIZE 16384 #endif +//this is merely a default now and can be changed at runtime +#ifndef LEDPIN +#define LEDPIN 2 +#endif + #endif diff --git a/wled00/data/settings_leds.htm b/wled00/data/settings_leds.htm index 2b2625f0..a133a296 100644 --- a/wled00/data/settings_leds.htm +++ b/wled00/data/settings_leds.htm @@ -46,10 +46,11 @@ } function UI() { + var isRGBW = false; //TODO check all strips for rgbw (old d.getElementById('rgbw').checked) var myC = d.querySelectorAll('.wc'), l = myC.length; for (i = 0; i < l; i++) { - myC[i].style.display = (d.getElementById('rgbw').checked) ? 'inline':'none'; + myC[i].style.display = (isRGBW) ? 'inline':'none'; } d.getElementById('ampwarning').style.display = (d.Sf.MA.value > 7200) ? 'inline':'none'; @@ -59,8 +60,8 @@ var s = d.getElementsByTagName("select"); for (i=0; i=d.maxST) || (n==-1 && i<=1)) return; + if ((n==1 && i>=d.maxST) || (n==-1 && i==0)) return; var f = d.getElementById("mLC"); if (n==1) { @@ -137,7 +138,7 @@ t.appendChild(d.createTextNode((i+1)+": ")); s = d.createElement("select"); - s.setAttribute("name","LTsel"+i); + s.setAttribute("name","LT"+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); @@ -177,7 +178,7 @@ 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; + //if (d.getElementsByName("LT"+i)[0].value>49) e.required = true; b.appendChild(e); t.appendChild(b); @@ -214,34 +215,12 @@

LED & HW setup

+ Total LED count:
+ LED strips -
+
-
- 1: - - CO: - - RGBW:
- pin: -
clk:
- count: -
+ Loading...

Relay pin: Active high?
Button pin:
diff --git a/wled00/html_settings.h b/wled00/html_settings.h index 14510629..4745ef6b 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -71,26 +71,16 @@ Do not enable if WiFi is working correctly, increases power consumption.
LED Settings