Minor fixes and optimisations.

Temperature usermod update for pin saving.
This commit is contained in:
Blaž Kristan 2021-02-25 09:54:10 +01:00
parent f24fcfca69
commit f23cee17eb
11 changed files with 994 additions and 921 deletions

View File

@ -4,13 +4,13 @@
#include <DallasTemperature.h> //DS18B20
//Pin defaults for QuinLed Dig-Uno
//Pin defaults for QuinLed Dig-Uno if not overriden
#ifndef TEMPERATURE_PIN
#ifdef ARDUINO_ARCH_ESP32
#define TEMPERATURE_PIN 18
#else //ESP8266 boards
#define TEMPERATURE_PIN 14
#endif
#ifdef ARDUINO_ARCH_ESP32
#define TEMPERATURE_PIN 18
#else //ESP8266 boards
#define TEMPERATURE_PIN 14
#endif
#endif
// the frequency to check temperature, 1 minute
@ -20,19 +20,22 @@
// how many seconds after boot to take first measurement, 20 seconds
#ifndef USERMOD_DALLASTEMPERATURE_FIRST_MEASUREMENT_AT
#define USERMOD_DALLASTEMPERATURE_FIRST_MEASUREMENT_AT 20000
#define USERMOD_DALLASTEMPERATURE_FIRST_MEASUREMENT_AT 20000
#endif
OneWire oneWire(TEMPERATURE_PIN);
DallasTemperature sensor(&oneWire);
class UsermodTemperature : public Usermod {
private:
OneWire *oneWire;
DallasTemperature *sensor;
// The device's unique 64-bit serial code stored in on-board ROM.
// Reading directly from the sensor device address is faster than
// reading from index. When reading by index, DallasTemperature
// must first look up the device address at the specified index.
DeviceAddress sensorDeviceAddress;
// GPIO pin used for sensor (with a default compile-time fallback)
int8_t temperaturePin = TEMPERATURE_PIN;
// measurement unit (true==°C, false==°F)
bool degC = true;
// set last reading as "40 sec before boot", so first reading is taken after 20 sec
unsigned long lastMeasurement = UINT32_MAX - (USERMOD_DALLASTEMPERATURE_MEASUREMENT_INTERVAL - USERMOD_DALLASTEMPERATURE_FIRST_MEASUREMENT_AT);
// last time requestTemperatures was called
@ -51,21 +54,19 @@ class UsermodTemperature : public Usermod {
bool disabled = false;
void requestTemperatures() {
// there is requestTemperaturesByAddress however it
// appears to do more work,
// there is requestTemperaturesByAddress however it
// appears to do more work,
// TODO: measure exection time difference
sensor.requestTemperatures();
sensor->requestTemperatures();
lastTemperaturesRequest = millis();
waitingForConversion = true;
}
void getTemperature() {
if (strip.isUpdating()) return;
#ifdef USERMOD_DALLASTEMPERATURE_CELSIUS
temperature = sensor.getTempC(sensorDeviceAddress);
#else
temperature = sensor.getTempF(sensorDeviceAddress);
#endif
if (degC) temperature = sensor->getTempC(sensorDeviceAddress);
else temperature = sensor->getTempF(sensorDeviceAddress);
lastMeasurement = millis();
waitingForConversion = false;
@ -76,21 +77,29 @@ class UsermodTemperature : public Usermod {
void setup() {
sensor.begin();
// pin retrieved from cfg.json (readFromConfig()) prior to running setup()
if (!pinManager.allocatePin(temperaturePin,false)) {
temperaturePin = -1; // allocation failed
DEBUG_PRINTLN(F("Temperature pin allocation failed."));
} else {
oneWire = new OneWire(temperaturePin);
sensor = new DallasTemperature(oneWire);
if (sensor) sensor->begin();
else
DEBUG_PRINTLN(F("Temperature sensor allocation failed."));
}
// get the unique 64-bit serial code stored in on-board ROM
// if getAddress returns false, the sensor was not found
disabled = !sensor.getAddress(sensorDeviceAddress, 0);
disabled = (temperaturePin==-1) || !sensor->getAddress(sensorDeviceAddress, 0);
if (!disabled) {
DEBUG_PRINTLN(F("Dallas Temperature found"));
// set the resolution for this specific device
sensor.setResolution(sensorDeviceAddress, 9, true);
sensor->setResolution(sensorDeviceAddress, 9, true);
// do not block waiting for reading
sensor.setWaitForConversion(false);
// allocate pin & prevent other use
if (!pinManager.allocatePin(TEMPERATURE_PIN,false))
disabled = true;
sensor->setWaitForConversion(false);
} else {
DEBUG_PRINTLN(F("Dallas Temperature not found"));
}
@ -98,7 +107,7 @@ class UsermodTemperature : public Usermod {
void loop() {
if (disabled || strip.isUpdating()) return;
unsigned long now = millis();
// check to see if we are due for taking a measurement
@ -106,21 +115,19 @@ class UsermodTemperature : public Usermod {
// is complete the the reading is finished
if (now - lastMeasurement < USERMOD_DALLASTEMPERATURE_MEASUREMENT_INTERVAL) return;
// we are due for a measurement, if we are not already waiting
// we are due for a measurement, if we are not already waiting
// for a conversion to complete, then make a new request for temps
if (!waitingForConversion)
{
if (!waitingForConversion) {
requestTemperatures();
return;
}
// we were waiting for a conversion to complete, have we waited log enough?
if (now - lastTemperaturesRequest >= 94 /* 93.75ms per the datasheet */)
{
if (now - lastTemperaturesRequest >= 94 /* 93.75ms per the datasheet */) {
getTemperature();
if (WLED_MQTT_CONNECTED) {
char subuf[38];
char subuf[64];
strcpy(subuf, mqttDeviceTopic);
if (-100 <= temperature) {
// dont publish super low temperature as the graph will get messed up
@ -159,11 +166,77 @@ class UsermodTemperature : public Usermod {
}
temp.add(temperature);
#ifdef USERMOD_DALLASTEMPERATURE_CELSIUS
temp.add(F("°C"));
#else
temp.add(F("°F"));
#endif
if (degC) temp.add(F("°C"));
else temp.add(F("°F"));
}
/**
* 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")] = temperaturePin;
root[F("mode_Temperature")] = degC ? ("C") : ("F");
}
/**
* 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) {
int8_t pin = (int)root[F("pin_Temperature")];
// deallocate pin and release memory
pinManager.deallocatePin(temperaturePin);
delete sensor;
delete oneWire;
// disable usermod
temperaturePin = -1;
disabled = true;
// check if pin is OK
if (pin>=0 && pinManager.allocatePin(pin,false)) {
// allocat memory
oneWire = new OneWire(pin);
sensor = new DallasTemperature(oneWire);
if (sensor) {
temperaturePin = pin;
sensor->begin();
disabled = !sensor->getAddress(sensorDeviceAddress, 0);
} else {
pinManager.deallocatePin(pin);
}
}
}
if (root[F("mode_Temperature")] != nullptr) {
degC = (root[F("mode_Temperature")]==String(PSTR("C")));
}
}
/**
* addToConfig() (called from set.cpp) stores persistent properties to cfg.json
*/
void addToConfig(JsonObject &root) {
// we add JSON object: {"Temperature": {"pin": 0, "degC": true}}
JsonObject top = root.createNestedObject(F("Temperature"));
top[F("pin")] = temperaturePin;
top[F("degC")] = degC;
}
/**
* readFromConfig() is called before setup() to populate properties from values stored in cfg.json
*/
void readFromConfig(JsonObject &root) {
// we look for JSON object: {"Temperature": {"pin": 0, "degC": true}}
JsonObject top = root[F("Temperature")];
if (!top.isNull() && top[F("pin")] != nullptr) {
temperaturePin = (int)top[F("pin")];
degC = top[F("degC")] != nullptr ? top[F("degC")] : true;
} else {
DEBUG_PRINTLN(F("No Temperature sensor config found. (Using defaults.)"));
}
}
uint16_t getId()

View File

@ -603,7 +603,7 @@ class WS2812FX {
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
show(void),
setRgbwPwm(void),
setColorOrder(uint8_t co),
// setColorOrder(uint8_t co),
setPixelSegment(uint8_t n);
bool
@ -629,7 +629,7 @@ class WS2812FX {
getMaxSegments(void),
//getFirstSelectedSegment(void),
getMainSegmentId(void),
getColorOrder(void),
// getColorOrder(void),
gamma8(uint8_t),
gamma8_cal(uint8_t, float),
get_random_wheel_index(uint8_t);

View File

@ -511,14 +511,14 @@ uint32_t WS2812FX::getLastShow(void) {
return _lastShow;
}
//TODO these need to be on a per-strip basis
uint8_t WS2812FX::getColorOrder(void) {
return COL_ORDER_GRB;
}
void WS2812FX::setColorOrder(uint8_t co) {
//bus->SetColorOrder(co);
}
// there is no longer any need for these two
//uint8_t WS2812FX::getColorOrder(void) {
// return COL_ORDER_GRB;
//}
//
//void WS2812FX::setColorOrder(uint8_t co) {
// //bus->SetColorOrder(co);
//}
void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping, uint8_t spacing) {
if (n >= MAX_NUM_SEGMENTS) return;

View File

@ -54,7 +54,7 @@ class Bus {
virtual uint8_t getPins(uint8_t* pinArray) { return 0; }
uint16_t getStart() {
inline uint16_t getStart() {
return _start;
}
@ -76,11 +76,11 @@ class Bus {
return false;
}
uint8_t getType() {
inline uint8_t getType() {
return _type;
}
bool isOk() {
inline bool isOk() {
return _valid;
}
@ -119,11 +119,11 @@ class BusDigital : public Bus {
//Serial.printf("Successfully inited strip %u (len %u) with type %u and pins %u,%u (itype %u)\n",nr, len, type, pins[0],pins[1],_iType);
};
void show() {
inline void show() {
PolyBus::show(_busPtr, _iType);
}
bool canShow() {
inline bool canShow() {
return PolyBus::canShow(_busPtr, _iType);
}
@ -150,11 +150,11 @@ class BusDigital : public Bus {
return PolyBus::getPixelColor(_busPtr, _iType, pix, _colorOrder);
}
uint8_t getColorOrder() {
inline uint8_t getColorOrder() {
return _colorOrder;
}
uint16_t getLength() {
inline uint16_t getLength() {
return _len - _skip;
}
@ -169,11 +169,11 @@ class BusDigital : public Bus {
_colorOrder = colorOrder;
}
bool isRgbw() {
inline bool isRgbw() {
return _rgbw;
}
void reinit() {
inline void reinit() {
PolyBus::begin(_busPtr, _iType, _pins);
}
@ -271,7 +271,7 @@ class BusPwm : public Bus {
}
}
void setBrightness(uint8_t b) {
inline void setBrightness(uint8_t b) {
_bri = b;
}
@ -285,7 +285,7 @@ class BusPwm : public Bus {
return (_type > TYPE_ONOFF && _type <= TYPE_ANALOG_5CH && _type != TYPE_ANALOG_3CH);
}
void cleanup() {
inline void cleanup() {
deallocatePins();
}
@ -326,8 +326,6 @@ class BusManager {
} else {
busses[numBusses] = new BusPwm(bc);
}
// numBusses++;
// return numBusses -1;
return numBusses++;
}
@ -385,7 +383,7 @@ class BusManager {
return busses[busNr];
}
uint8_t getNumBusses() {
inline uint8_t getNumBusses() {
return numBusses;
}

View File

@ -90,9 +90,9 @@ void deserializeConfig() {
// 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;
ledCount = 0;
CJSON(ledCount, hw_led[F("total")]);
if (ledCount > MAX_LEDS) ledCount = MAX_LEDS;
uint16_t lC = 0;
CJSON(strip.ablMilliampsMax, hw_led[F("maxpwr")]);
CJSON(strip.milliampsPerLed, hw_led[F("ledma")]);
@ -109,20 +109,16 @@ void deserializeConfig() {
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 || length+ledCount > MAX_LEDS) continue; // zero length or we reached max. number of LEDs, just stop
// maybe we should have
// start = ledCount; // length of previous strips
if (length==0 || length+lC > MAX_LEDS) continue; // zero length or we reached max. number of LEDs, just stop
uint16_t start = elm[F("start")] | 0;
if (start >= ledCount+length) continue; // something is very wrong :)
if (start >= lC+length) continue; // something is very wrong :)
//limit length of strip if it would exceed total configured LEDs
//if (start + length > ledCount) length = ledCount - start;
uint8_t colorOrder = (int)elm[F("order")];
@ -134,10 +130,11 @@ void deserializeConfig() {
if ((bool)elm[F("rgbw")]) SET_BIT(ledType,7); else UNSET_BIT(ledType,7); // hack bit 7 to indicate RGBW (as an override if necessary)
useRGBW |= (bool)elm[F("rgbw")];
s++;
ledCount += length;
lC += length;
BusConfig bc = BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst);
busses.add(bc);
}
if (lC > ledCount) ledCount = lC; // fix incorrect total length (honour analog setup)
strip.finalizeInit();
JsonObject hw_btn_ins_0 = hw[F("btn")][F("ins")][0];
@ -458,7 +455,7 @@ void serializeConfig() {
if (!bus || bus->getLength()==0) break;
JsonObject ins = hw_led_ins.createNestedObject();
ins[F("en")] = true;
ins[F("start")] = bus->getStart(); // really needed?
ins[F("start")] = bus->getStart();
ins[F("len")] = bus->getLength();
JsonArray ins_pin = ins.createNestedArray("pin");
uint8_t pins[5];

View File

@ -117,10 +117,10 @@
LK.value="";
}
}
d.getElementById("ls"+n).readOnly = !(type >= 32 && type < 48); // not analog
d.getElementById("LC").readOnly = !(type >= 32 && type < 48); // not analog
d.getElementById("ls"+n).readOnly = !(type > 31 && type < 48); // not analog
d.getElementById("LC").readOnly = !(type > 31 && type < 48); // not analog
if (change) {
d.getElementById("ew"+n).checked = (type == 30 || type == 31 || type == 44 || type == 45); // TYPE_xxxx values from const.h
d.getElementById("ew"+n).checked = (type == 30 || type == 31 || type == 44 || type == 45); // RGBW checkbox, TYPE_xxxx values from const.h
}
isRGBW |= d.getElementById("ew"+n).checked;
d.getElementById("dig"+n).style.display = (type > 31 && type < 48) ? "none":"inline";
@ -138,7 +138,12 @@
var sLC = 0, maxLC = 0;
for (i=0; i<LCs.length; i++) {
var nm = LCs[i].name.substring(0,2);
if (nm=="LC" && LCs[i].name !== "LC") {var c=parseInt(LCs[i].value,10);d.getElementById("ls"+n).value=sLC;if(c){sLC+=c;if(c>maxLC)maxLC=c;}continue;}
if (nm=="LC" && LCs[i].name !== "LC") {
var c=parseInt(LCs[i].value,10);
if(d.getElementById("ls"+n).readOnly) d.getElementById("ls"+n).value=sLC;
if(c){sLC+=c;if(c>maxLC)maxLC=c;}
continue;
}
if (nm=="L0" || nm=="L1") {
var lc=d.getElementsByName("LC"+LCs[i].name.substring(2))[0];
p3u|=(LCs[i].value==3);
@ -207,45 +212,47 @@
var f = d.getElementById("mLC");
if (n==1) {
var cn = `<div class="iST">
${i>0?'<hr style="width:260px">':''}
${i+1}:
<select name="LT${i}" onchange="UI(true)">
<option value="22">WS281x</option>
<option value="30">SK6812 RGBW</option>
<option value="31">TM1814</option>
<option value="24">400kHz</option>
<option value="50">WS2801</option>
<option value="51">APA102</option>
<option value="52">LPD8806</option>
<option value="53">P9813</option>
<option value="41">PWM White</option>
<option value="42">PWM WWCW</option>
<option value="43">PWM RGB</option>
<option value="44">PWM RGBW</option>
<option value="45">PWM RGBWC</option>
</select>&nbsp;
Color Order:
<select name="CO${i}">
<option value="0">GRB</option>
<option value="1">RGB</option>
<option value="2">BRG</option>
<option value="3">RBG</option>
<option value="4">BGR</option>
<option value="5">GBR</option>
</select><!--br-->
RGBW: <input id="ew${i}" type="checkbox" name="EW${i}"><br>
<span id="p0d${i}">Pin:</span> <input type="number" name="L0${i}" min="0" max="40" required style="width:35px" onchange="UI()"/>
<span id="p1d${i}">Clock:</span> <input type="number" name="L1${i}" min="0" max="40" style="width:35px" onchange="UI()"/>
<span id="p2d${i}"></span><input type="number" name="L2${i}" min="0" max="40" style="width:35px" onchange="UI()"/>
<span id="p3d${i}"></span><input type="number" name="L3${i}" min="0" max="40" style="width:35px" onchange="UI()"/>
<span id="p4d${i}"></span><input type="number" name="L4${i}" min="0" max="40" style="width:35px" onchange="UI()"/>
<br>
<span id="psd${i}">Start:</span> <input type="number" name="LS${i}" id="ls${i}" min="0" max="8191" value="0" required />&nbsp;
<div id="dig${i}" style="display:inline">
Count: <input type="number" name="LC${i}" min="0" max="2048" value="1" required oninput="UI()" /><br>
Reverse: <input type="checkbox" name="CV${i}"></div><br>
</div>`;
// npm run build has trouble minimizing spaces inside string
var cn =
`<div class="iST">
${i>0?'<hr style="width:260px">':''}
${i+1}:
<select name="LT${i}" onchange="UI(true)">
<option value="22">WS281x</option>
<option value="30">SK6812 RGBW</option>
<option value="31">TM1814</option>
<option value="24">400kHz</option>
<option value="50">WS2801</option>
<option value="51">APA102</option>
<option value="52">LPD8806</option>
<option value="53">P9813</option>
<option value="41">PWM White</option>
<option value="42">PWM WWCW</option>
<option value="43">PWM RGB</option>
<option value="44">PWM RGBW</option>
<option value="45">PWM RGBWC</option>
</select>&nbsp;
Color Order:
<select name="CO${i}">
<option value="0">GRB</option>
<option value="1">RGB</option>
<option value="2">BRG</option>
<option value="3">RBG</option>
<option value="4">BGR</option>
<option value="5">GBR</option>
</select><!--br-->
RGBW: <input id="ew${i}" type="checkbox" name="EW${i}"><br>
<span id="p0d${i}">Pin:</span> <input type="number" name="L0${i}" min="0" max="40" required style="width:35px" onchange="UI()"/>
<span id="p1d${i}">Clock:</span> <input type="number" name="L1${i}" min="0" max="40" style="width:35px" onchange="UI()"/>
<span id="p2d${i}"></span><input type="number" name="L2${i}" min="0" max="40" style="width:35px" onchange="UI()"/>
<span id="p3d${i}"></span><input type="number" name="L3${i}" min="0" max="40" style="width:35px" onchange="UI()"/>
<span id="p4d${i}"></span><input type="number" name="L4${i}" min="0" max="40" style="width:35px" onchange="UI()"/>
<br>
<span id="psd${i}">Start:</span> <input type="number" name="LS${i}" id="ls${i}" min="0" max="8191" value="0" required />&nbsp;
<div id="dig${i}" style="display:inline">
Count: <input type="number" name="LC${i}" min="0" max="2048" value="1" required oninput="UI()" /><br>
Reverse: <input type="checkbox" name="CV${i}"></div><br>
</div>`;
f.insertAdjacentHTML("beforeend", cn);
}
if (n==-1) {

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -87,7 +87,6 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
skipFirstLed = request->hasArg(F("SL"));
useRGBW = false;
ledCount = 0;
uint8_t colorOrder, type;
uint16_t length, start;
@ -113,14 +112,13 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
if (request->hasArg(ew)) SET_BIT(type,7); else UNSET_BIT(type,7); // hack bit 7 to indicate RGBW (as a LED type override if necessary)
useRGBW |= request->hasArg(ew);
colorOrder = request->arg(co).toInt();
start = (request->hasArg(ls)) ? request->arg(ls).toInt() : t;
if (request->hasArg(lc) && request->arg(lc).toInt() > 0) {
length = request->arg(lc).toInt();
t += length = request->arg(lc).toInt();
} else {
break; // no parameter
}
colorOrder = request->arg(co).toInt();
start = (request->hasArg(ls)) ? request->arg(ls).toInt() : 0;
// ledCount += length;
// actual finalization is done in loop()
if (busConfigs[s] != nullptr) delete busConfigs[s];

View File

@ -238,7 +238,7 @@ void loadSettingsFromEEPROM()
if (lastEEPROMversion > 9)
{
strip.setColorOrder(EEPROM.read(383));
//strip.setColorOrder(EEPROM.read(383));
irEnabled = EEPROM.read(385);
strip.ablMilliampsMax = EEPROM.read(387) + ((EEPROM.read(388) << 8) & 0xFF00);
} else if (lastEEPROMversion > 1) //ABL is off by default when updating from version older than 0.8.2

View File

@ -187,7 +187,8 @@ void getSettingsJS(byte subPage, char* dest)
if (subPage <1 || subPage >7) return;
if (subPage == 1) {
if (subPage == 1)
{
sappends('s',SET_F("CS"),clientSSID);
byte l = strlen(clientPass);
@ -253,52 +254,51 @@ void getSettingsJS(byte subPage, char* dest)
}
}
if (subPage == 2) {
char nS[3];
if (subPage == 2)
{
// add usermod pins as d.um_p array
DynamicJsonDocument doc(JSON_BUFFER_SIZE/2);
JsonObject mods = doc.createNestedObject(F("um"));
usermods.addToConfig(mods);
oappend(SET_F("d.um_p=["));
if (!mods.isNull()) {
uint8_t i=0;
oappend(SET_F("d.um_p=["));
for (JsonPair kv : mods) {
if (strncmp_P(kv.key().c_str(),PSTR("pin_"),4) == 0) {
if (i++) oappend(SET_F(","));
oappend(itoa((int)kv.value(),nS,10));
oappendi((int)kv.value());
} else if (!kv.value().isNull()) {
// element is an JsonObject
JsonObject obj = kv.value();
if (obj[F("pin")] != nullptr) {
if (i++) oappend(SET_F(","));
oappend(itoa((int)obj[F("pin")],nS,10));
oappendi((int)obj[F("pin")]);
}
}
}
#ifdef ESP8266
#ifdef WLED_DEBUG
if (i==0)
oappend(SET_F("1"));
else
oappend(SET_F(",1"));
#endif
oappend(SET_F(",6,7,8,9,10,11];")); // flash memory pins
#else
oappend(SET_F("];"));
if (i) oappend(SET_F(","));
oappend(SET_F("6,7,8,9,10,11")); // flash memory pins
#ifdef WLED_DEBUG
oappend(SET_F("1"));
#endif
#endif
}
oappend(SET_F("];"));
// set limit for number of busses
#if defined(WLED_MAX_BUSSES) && WLED_MAX_BUSSES>1
oappend(SET_F("addLEDs("));
oappendi(WLED_MAX_BUSSES);
oappend(SET_F(");"));
#endif
// set limit for LED count
oappend(SET_F("d.LCmax="));
oappendi(MAX_LEDS);
oappend(";");
#ifdef ESP8266
// set limit for DMA LED count
oappend(SET_F("d.LDmax="));
oappendi(MAX_LEDS_DMA);
oappend(";");
@ -320,7 +320,7 @@ void getSettingsJS(byte subPage, char* dest)
uint8_t nPins = bus->getPins(pins);
for (uint8_t i = 0; i < nPins; i++) {
lp[1] = 48+i;
if (pinManager.isPinOk(pins[i])) sappend('v', lp, pins[i]);
if (pinManager.isPinOk(pins[i])) sappend('v',lp,pins[i]);
}
sappend('v',lc,bus->getLength());
sappend('v',lt,bus->getType());