diff --git a/platformio.ini b/platformio.ini index 97a2d49e..c01d4f15 100644 --- a/platformio.ini +++ b/platformio.ini @@ -446,7 +446,7 @@ lib_deps = ${esp32c3.lib_deps} ; https://github.com/blazoncek/arduinoFFT.git [env:esp32s3dev_8MB] -;; ESP32-S3-DevKitC-1 development board, with 8MB FLASH, no PSRAM +;; ESP32-S3-DevKitC-1 development board, with 8MB FLASH, no PSRAM (flash_mode: qio) board = esp32-s3-devkitc-1 ;platform = espressif32@5.1.1 ;platform_packages = platformio/framework-arduinoespressif32@3.20004.220825 @@ -466,6 +466,26 @@ board_build.f_flash = 80000000L board_build.flash_mode = qio monitor_filters = esp32_exception_decoder +[env:esp32s3dev_8MB_PSRAM] +;; ESP32-TinyS3 development board, with 8MB FLASH and 8MB PSRAM (memory_type: qio_opi, qio_qspi, or opi_opi) +;board = um_tinys3 ; -> needs workaround from https://github.com/Aircoookie/WLED/pull/2905#issuecomment-1328049860 +;board = esp32s3box ; -> error: 'esp32_adc2gpio' was not declared in this scope +board = esp32-s3-devkitc-1 ; -> compiles, but does not support PSRAM +platform = espressif32 @ ~5.2.0 +platform_packages = +upload_speed = 921600 +build_unflags = ${common.build_unflags} +build_flags = ${common.build_flags} ${esp32s3.build_flags} + -D CONFIG_LITTLEFS_FOR_IDF_3_2 -D WLED_WATCHDOG_TIMEOUT=0 -D ARDUINO_USB_MODE=1 -D ARDUINO_USB_MSC_ON_BOOT=0 + ; -D ARDUINO_USB_CDC_ON_BOOT=0 + ; -D WLED_RELEASE_NAME=ESP32-S3_PSRAM + -D WLED_USE_PSRAM -DBOARD_HAS_PSRAM ; tells WLED that PSRAM shall be used +lib_deps = ${esp32s3.lib_deps} +board_build.partitions = tools/WLED_ESP32_8MB.csv +board_build.f_flash = 80000000L +board_build.flash_mode = qio +monitor_filters = esp32_exception_decoder + [env:esp8285_4CH_MagicHome] board = esp8285 platform = ${common.platform_wled_default} diff --git a/usermods/BME280_v2/usermod_bme280.h b/usermods/BME280_v2/usermod_bme280.h index 6b42fc80..c27adfc8 100644 --- a/usermods/BME280_v2/usermod_bme280.h +++ b/usermods/BME280_v2/usermod_bme280.h @@ -16,14 +16,15 @@ private: // NOTE: Do not implement any compile-time variables, anything the user needs to configure // should be configurable from the Usermod menu using the methods below // key settings set via usermod menu - unsigned long TemperatureDecimals = 0; // Number of decimal places in published temperaure values - unsigned long HumidityDecimals = 0; // Number of decimal places in published humidity values - unsigned long PressureDecimals = 0; // Number of decimal places in published pressure values - unsigned long TemperatureInterval = 5; // Interval to measure temperature (and humidity, dew point if available) in seconds - unsigned long PressureInterval = 300; // Interval to measure pressure in seconds + uint8_t TemperatureDecimals = 0; // Number of decimal places in published temperaure values + uint8_t HumidityDecimals = 0; // Number of decimal places in published humidity values + uint8_t PressureDecimals = 0; // Number of decimal places in published pressure values + uint16_t TemperatureInterval = 5; // Interval to measure temperature (and humidity, dew point if available) in seconds + uint16_t PressureInterval = 300; // Interval to measure pressure in seconds bool PublishAlways = false; // Publish values even when they have not changed bool UseCelsius = true; // Use Celsius for Reporting bool HomeAssistantDiscovery = false; // Publish Home Assistant Device Information + bool enabled = true; // set the default pins based on the architecture, these get overridden by Usermod menu settings #ifdef ESP8266 @@ -70,15 +71,10 @@ private: // MQTT topic strings for publishing Home Assistant discovery topics bool mqttInitialized = false; - String mqttTemperatureTopic = ""; - String mqttHumidityTopic = ""; - String mqttPressureTopic = ""; - String mqttHeatIndexTopic = ""; - String mqttDewPointTopic = ""; - // Store packet IDs of MQTT publications - uint16_t mqttTemperaturePub = 0; - uint16_t mqttPressurePub = 0; + // strings to reduce flash memory usage (used more than twice) + static const char _name[]; + static const char _enabled[]; // Read the BME280/BMP280 Sensor (which one runs depends on whether Celsius or Farenheit being set in Usermod Menu) void UpdateBME280Data(int SensorType) @@ -95,7 +91,7 @@ private: sensorTemperature = _temperature; sensorHumidity = _humidity; sensorPressure = _pressure; - tempScale = "°C"; + tempScale = F("°C"); if (sensorType == 1) { sensorHeatIndex = EnvironmentCalculations::HeatIndex(_temperature, _humidity, envTempUnit); @@ -111,7 +107,7 @@ private: sensorTemperature = _temperature; sensorHumidity = _humidity; sensorPressure = _pressure; - tempScale = "°F"; + tempScale = F("°F"); if (sensorType == 1) { sensorHeatIndex = EnvironmentCalculations::HeatIndex(_temperature, _humidity, envTempUnit); @@ -123,18 +119,23 @@ private: // Procedure to define all MQTT discovery Topics void _mqttInitialize() { - mqttTemperatureTopic = String(mqttDeviceTopic) + F("/temperature"); - mqttPressureTopic = String(mqttDeviceTopic) + F("/pressure"); - mqttHumidityTopic = String(mqttDeviceTopic) + F("/humidity"); - mqttHeatIndexTopic = String(mqttDeviceTopic) + F("/heat_index"); - mqttDewPointTopic = String(mqttDeviceTopic) + F("/dew_point"); + char mqttTemperatureTopic[128]; + char mqttHumidityTopic[128]; + char mqttPressureTopic[128]; + char mqttHeatIndexTopic[128]; + char mqttDewPointTopic[128]; + snprintf_P(mqttTemperatureTopic, 127, PSTR("%s/temperature"), mqttDeviceTopic); + snprintf_P(mqttPressureTopic, 127, PSTR("%s/pressure"), mqttDeviceTopic); + snprintf_P(mqttHumidityTopic, 127, PSTR("%s/humidity"), mqttDeviceTopic); + snprintf_P(mqttHeatIndexTopic, 127, PSTR("%s/heat_index"), mqttDeviceTopic); + snprintf_P(mqttDewPointTopic, 127, PSTR("%s/dew_point"), mqttDeviceTopic); if (HomeAssistantDiscovery) { - _createMqttSensor(F("Temperature"), mqttTemperatureTopic, F("temperature"), tempScale); - _createMqttSensor(F("Pressure"), mqttPressureTopic, F("pressure"), F("hPa")); - _createMqttSensor(F("Humidity"), mqttHumidityTopic, F("humidity"), F("%")); - _createMqttSensor(F("HeatIndex"), mqttHeatIndexTopic, F("temperature"), tempScale); - _createMqttSensor(F("DewPoint"), mqttDewPointTopic, F("temperature"), tempScale); + _createMqttSensor(F("Temperature"), mqttTemperatureTopic, "temperature", tempScale); + _createMqttSensor(F("Pressure"), mqttPressureTopic, "pressure", F("hPa")); + _createMqttSensor(F("Humidity"), mqttHumidityTopic, "humidity", F("%")); + _createMqttSensor(F("HeatIndex"), mqttHeatIndexTopic, "temperature", tempScale); + _createMqttSensor(F("DewPoint"), mqttDewPointTopic, "temperature", tempScale); } } @@ -169,6 +170,15 @@ private: mqtt->publish(t.c_str(), 0, true, temp.c_str()); } + void publishMqtt(const char *topic, const char* state) { + //Check if MQTT Connected, otherwise it will crash the 8266 + if (WLED_MQTT_CONNECTED){ + char subuf[128]; + snprintf_P(subuf, 127, PSTR("%s/%s"), mqttDeviceTopic, topic); + mqtt->publish(subuf, 0, false, state); + } + } + public: void setup() { @@ -183,7 +193,7 @@ public: if (!bme.begin()) { sensorType = 0; - DEBUG_PRINTLN(F("Could not find BME280I2C sensor!")); + DEBUG_PRINTLN(F("Could not find BME280 I2C sensor!")); } else { @@ -207,14 +217,16 @@ public: void loop() { + if (!enabled || strip.isUpdating()) return; + // BME280 sensor MQTT publishing - // Check if sensor present and MQTT Connected, otherwise it will crash the MCU - if (sensorType != 0 && WLED_MQTT_CONNECTED) + // Check if sensor present and Connected, otherwise it will crash the MCU + if (sensorType != 0) { // Timer to fetch new temperature, humidity and pressure data at intervals timer = millis(); - if (timer - lastTemperatureMeasure >= TemperatureInterval * 1000 || mqttTemperaturePub == 0) + if (timer - lastTemperatureMeasure >= TemperatureInterval * 1000) { lastTemperatureMeasure = timer; @@ -223,18 +235,11 @@ public: float temperature = roundf(sensorTemperature * powf(10, TemperatureDecimals)) / powf(10, TemperatureDecimals); float humidity, heatIndex, dewPoint; - if (WLED_MQTT_CONNECTED && !mqttInitialized) - { - _mqttInitialize(); - mqttInitialized = true; - } - // If temperature has changed since last measure, create string populated with device topic // from the UI and values read from sensor, then publish to broker if (temperature != lastTemperature || PublishAlways) { - String topic = String(mqttDeviceTopic) + "/temperature"; - mqttTemperaturePub = mqtt->publish(topic.c_str(), 0, false, String(temperature, TemperatureDecimals).c_str()); + publishMqtt("temperature", String(temperature, TemperatureDecimals).c_str()); } lastTemperature = temperature; // Update last sensor temperature for next loop @@ -247,20 +252,17 @@ public: if (humidity != lastHumidity || PublishAlways) { - String topic = String(mqttDeviceTopic) + F("/humidity"); - mqtt->publish(topic.c_str(), 0, false, String(humidity, HumidityDecimals).c_str()); + publishMqtt("humidity", String(humidity, HumidityDecimals).c_str()); } if (heatIndex != lastHeatIndex || PublishAlways) { - String topic = String(mqttDeviceTopic) + F("/heat_index"); - mqtt->publish(topic.c_str(), 0, false, String(heatIndex, TemperatureDecimals).c_str()); + publishMqtt("heat_index", String(heatIndex, TemperatureDecimals).c_str()); } if (dewPoint != lastDewPoint || PublishAlways) { - String topic = String(mqttDeviceTopic) + F("/dew_point"); - mqtt->publish(topic.c_str(), 0, false, String(dewPoint, TemperatureDecimals).c_str()); + publishMqtt("dew_point", String(dewPoint, TemperatureDecimals).c_str()); } lastHumidity = humidity; @@ -269,7 +271,7 @@ public: } } - if (timer - lastPressureMeasure >= PressureInterval * 1000 || mqttPressurePub == 0) + if (timer - lastPressureMeasure >= PressureInterval * 1000) { lastPressureMeasure = timer; @@ -277,15 +279,23 @@ public: if (pressure != lastPressure || PublishAlways) { - String topic = String(mqttDeviceTopic) + F("/pressure"); - mqttPressurePub = mqtt->publish(topic.c_str(), 0, true, String(pressure, PressureDecimals).c_str()); + publishMqtt("pressure", String(pressure, PressureDecimals).c_str()); } lastPressure = pressure; } } } - + + void onMqttConnect(bool sessionPresent) + { + if (WLED_MQTT_CONNECTED && !mqttInitialized) + { + _mqttInitialize(); + mqttInitialized = true; + } + } + /* * API calls te enable data exchange between WLED modules */ @@ -294,9 +304,9 @@ public: return (float)roundf(sensorTemperature * powf(10, TemperatureDecimals)) / powf(10, TemperatureDecimals); } else { return (float)roundf(sensorTemperature * powf(10, TemperatureDecimals)) / powf(10, TemperatureDecimals) * 1.8f + 32; - } - + } } + inline float getTemperatureF() { if (UseCelsius) { return ((float)roundf(sensorTemperature * powf(10, TemperatureDecimals)) / powf(10, TemperatureDecimals) -32) * 0.56f; @@ -304,12 +314,15 @@ public: return (float)roundf(sensorTemperature * powf(10, TemperatureDecimals)) / powf(10, TemperatureDecimals); } } + inline float getHumidity() { return (float)roundf(sensorHumidity * powf(10, HumidityDecimals)); } + inline float getPressure() { return (float)roundf(sensorPressure * powf(10, PressureDecimals)); } + inline float getDewPointC() { if (UseCelsius) { return (float)roundf(sensorDewPoint * powf(10, TemperatureDecimals)) / powf(10, TemperatureDecimals); @@ -317,6 +330,7 @@ public: return (float)roundf(sensorDewPoint * powf(10, TemperatureDecimals)) / powf(10, TemperatureDecimals) * 1.8f + 32; } } + inline float getDewPointF() { if (UseCelsius) { return ((float)roundf(sensorDewPoint * powf(10, TemperatureDecimals)) / powf(10, TemperatureDecimals) -32) * 0.56f; @@ -324,13 +338,16 @@ public: return (float)roundf(sensorDewPoint * powf(10, TemperatureDecimals)) / powf(10, TemperatureDecimals); } } + inline float getHeatIndexC() { if (UseCelsius) { return (float)roundf(sensorHeatIndex * powf(10, TemperatureDecimals)) / powf(10, TemperatureDecimals); } else { return (float)roundf(sensorHeatIndex * powf(10, TemperatureDecimals)) / powf(10, TemperatureDecimals) * 1.8f + 32; } - }inline float getHeatIndexF() { + } + + inline float getHeatIndexF() { if (UseCelsius) { return ((float)roundf(sensorHeatIndex * powf(10, TemperatureDecimals)) / powf(10, TemperatureDecimals) -32) * 0.56f; } else { @@ -384,7 +401,8 @@ public: // Save Usermod Config Settings void addToConfig(JsonObject& root) { - JsonObject top = root.createNestedObject(F("BME280/BMP280")); + JsonObject top = root.createNestedObject(FPSTR(_name)); + top[FPSTR(_enabled)] = enabled; top[F("TemperatureDecimals")] = TemperatureDecimals; top[F("HumidityDecimals")] = HumidityDecimals; top[F("PressureDecimals")] = PressureDecimals; @@ -405,17 +423,17 @@ public: // default settings values could be set here (or below using the 3-argument getJsonValue()) instead of in the class definition or constructor // setting them inside readFromConfig() is slightly more robust, handling the rare but plausible use case of single value being missing after boot (e.g. if the cfg.json was manually edited and a value was removed) - int8_t newPin[2]; for (byte i=0; i<2; i++) newPin[i] = ioPin[i]; // prepare to note changed pins - JsonObject top = root[F("BME280/BMP280")]; + JsonObject top = root[FPSTR(_name)]; if (top.isNull()) { - DEBUG_PRINT(F("BME280/BMP280")); + DEBUG_PRINT(F(_name)); DEBUG_PRINTLN(F(": No config found. (Using defaults.)")); return false; } bool configComplete = !top.isNull(); + configComplete &= getJsonValue(top[FPSTR(_enabled)], enabled); // A 3-argument getJsonValue() assigns the 3rd argument as a default value if the Json value is missing configComplete &= getJsonValue(top[F("TemperatureDecimals")], TemperatureDecimals, 1); configComplete &= getJsonValue(top[F("HumidityDecimals")], HumidityDecimals, 0); @@ -427,7 +445,7 @@ public: configComplete &= getJsonValue(top[F("HomeAssistantDiscovery")], HomeAssistantDiscovery, false); for (byte i=0; i<2; i++) configComplete &= getJsonValue(top[F("pin")][i], newPin[i], ioPin[i]); - DEBUG_PRINT(FPSTR(F("BME280/BMP280"))); + DEBUG_PRINT(FPSTR(_name)); if (!initDone) { // first run: reading from cfg.json for (byte i=0; i<2; i++) ioPin[i] = newPin[i]; @@ -454,4 +472,7 @@ public: uint16_t getId() { return USERMOD_ID_BME280; } -}; \ No newline at end of file +}; + +const char UsermodBME280::_name[] PROGMEM = "BME280/BMP280"; +const char UsermodBME280::_enabled[] PROGMEM = "enabled"; diff --git a/usermods/audioreactive/audio_reactive.h b/usermods/audioreactive/audio_reactive.h index 78f63602..17a0a35d 100644 --- a/usermods/audioreactive/audio_reactive.h +++ b/usermods/audioreactive/audio_reactive.h @@ -1916,10 +1916,10 @@ class AudioReactive : public Usermod { #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3) oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',3,'I2S Master CLK','only use -1, 0, 1 or 3');")); #else - oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',3,'I2S Master CLK','');")); + oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',3,'', 'I2S Master CLK');")); #endif - oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',4,'I2C SDA',' ');")); - oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',5,'I2C SCL',' ');")); + oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',4,'', 'I2C SDA');")); + oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',5,'', 'I2C SCL');")); } diff --git a/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h b/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h index 79fef942..cd279410 100644 --- a/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h +++ b/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h @@ -1036,11 +1036,11 @@ class FourLineDisplayUsermod : public Usermod { oappend(SET_F("addOption(dd,'SSD1305 128x64',5);")); oappend(SET_F("addOption(dd,'SSD1306 SPI',6);")); oappend(SET_F("addOption(dd,'SSD1306 SPI 128x64',7);")); - oappend(SET_F("addInfo('4LineDisplay:pin[]',0,'I2C/SPI CLK','-1 use global');")); - oappend(SET_F("addInfo('4LineDisplay:pin[]',1,'I2C/SPI DTA','-1 use global');")); - oappend(SET_F("addInfo('4LineDisplay:pin[]',2,'SPI CS',' ');")); - oappend(SET_F("addInfo('4LineDisplay:pin[]',3,'SPI DC',' ');")); - oappend(SET_F("addInfo('4LineDisplay:pin[]',4,'SPI RST',' ');")); + oappend(SET_F("addInfo('4LineDisplay:pin[]',0,'-1 use global','I2C/SPI CLK');")); + oappend(SET_F("addInfo('4LineDisplay:pin[]',1,'-1 use global','I2C/SPI DTA');")); + oappend(SET_F("addInfo('4LineDisplay:pin[]',2,'','SPI CS');")); + oappend(SET_F("addInfo('4LineDisplay:pin[]',3,'','SPI DC');")); + oappend(SET_F("addInfo('4LineDisplay:pin[]',4,'','SPI RST');")); } /* diff --git a/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h b/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h index 13dd0dea..a6dc0762 100644 --- a/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h +++ b/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h @@ -191,7 +191,7 @@ private: re_sortModes(modes_qstrings, modes_alpha_indexes, strip.getModeCount(), MODE_SORT_SKIP_COUNT); palettes_qstrings = re_findModeStrings(JSON_palette_names, strip.getPaletteCount()); - palettes_alpha_indexes = re_initIndexArray(strip.getPaletteCount()); + palettes_alpha_indexes = re_initIndexArray(strip.getPaletteCount()); // only use internal palettes // How many palette names start with '*' and should not be sorted? // (Also skipping the first one, 'Default'). diff --git a/wled00/FX.h b/wled00/FX.h index 9d2a6e01..93daa7d6 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -777,7 +777,7 @@ class WS2812FX { // 96 bytes inline uint8_t getSegmentsNum(void) { return _segments.size(); } // returns currently present segments inline uint8_t getCurrSegmentId(void) { return _segment_index; } inline uint8_t getMainSegmentId(void) { return _mainSegment; } - inline uint8_t getPaletteCount() { return 13 + GRADIENT_PALETTE_COUNT; } + inline uint8_t getPaletteCount() { return 13 + GRADIENT_PALETTE_COUNT; } // will only return built-in palette count inline uint8_t getTargetFps() { return _targetFps; } inline uint8_t getModeCount() { return _modeCount; } diff --git a/wled00/FX_2Dfcn.cpp b/wled00/FX_2Dfcn.cpp index 55493e3e..bca05903 100644 --- a/wled00/FX_2Dfcn.cpp +++ b/wled00/FX_2Dfcn.cpp @@ -122,10 +122,11 @@ void IRAM_ATTR_YN WS2812FX::setPixelColorXY(int x, int y, uint32_t col) //WLEDMM #ifndef WLED_DISABLE_2D if (!isMatrix) return; // not a matrix set-up uint16_t index = y * matrixWidth + x; + if (index >= customMappingSize) return; // customMappingSize is always W * H of matrix in 2D setup #else uint16_t index = x; -#endif if (index >= _length) return; +#endif if (index < customMappingSize) index = customMappingTable[index]; busses.setPixelColor(index, col); } @@ -134,10 +135,11 @@ void IRAM_ATTR_YN WS2812FX::setPixelColorXY(int x, int y, uint32_t col) //WLEDMM uint32_t WS2812FX::getPixelColorXY(uint16_t x, uint16_t y) { #ifndef WLED_DISABLE_2D uint16_t index = (y * matrixWidth + x); + if (index >= customMappingSize) return 0; // customMappingSize is always W * H of matrix in 2D setup #else uint16_t index = x; -#endif if (index >= _length) return 0; +#endif if (index < customMappingSize) index = customMappingTable[index]; return busses.getPixelColor(index); } diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 4d13224d..b9164885 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -425,12 +425,7 @@ void Segment::setMode(uint8_t fx, bool loadDefaults) { sOpt = extractModeDefaults(fx, "mi"); if (sOpt >= 0) mirror = (bool)sOpt; // NOTE: setting this option is a risky business sOpt = extractModeDefaults(fx, "rY"); if (sOpt >= 0) reverse_y = (bool)sOpt; sOpt = extractModeDefaults(fx, "mY"); if (sOpt >= 0) mirror_y = (bool)sOpt; // NOTE: setting this option is a risky business - sOpt = extractModeDefaults(fx, "pal"); - if (sOpt >= 0 && (size_t)sOpt < strip.getPaletteCount() + strip.customPalettes.size()) { - if (sOpt != palette) { - palette = sOpt; - } - } + sOpt = extractModeDefaults(fx, "pal"); if (sOpt >= 0) setPalette(sOpt); } stateChanged = true; // send UDP/WS broadcast } @@ -438,13 +433,13 @@ void Segment::setMode(uint8_t fx, bool loadDefaults) { } void Segment::setPalette(uint8_t pal) { - if (pal < strip.getPaletteCount()) { - if (pal != palette) { - if (strip.paletteFade) startTransition(strip.getTransition()); - palette = pal; - } + if (pal < 245 && pal > GRADIENT_PALETTE_COUNT+13) pal = 0; // built in palettes + if (pal > 245 && (strip.customPalettes.size() == 0 || 255U-pal > strip.customPalettes.size()-1)) pal = 0; // custom palettes + if (pal != palette) { + if (strip.paletteFade) startTransition(strip.getTransition()); + palette = pal; + stateChanged = true; // send UDP/WS broadcast } - stateChanged = true; // send UDP/WS broadcast } // 2D matrix diff --git a/wled00/data/index.js b/wled00/data/index.js index c4566648..3615b8d8 100644 --- a/wled00/data/index.js +++ b/wled00/data/index.js @@ -1560,8 +1560,8 @@ function requestJson(command=null) if (json.info) { let i = json.info; // append custom palettes (when loading for the 1st time) - if (!command && isEmpty(lastinfo) && i.leds && i.leds.cpal) { - for (let j = 0; j()) strlcpy(quickLoad, sObj[F("ql")].as(), 3); // only 2 chars for QL + if (sObj[F("ql")].is()) strlcpy(quickLoad, sObj[F("ql")].as(), 9); // client limits QL to 2 chars, buffer for 8 bytes to allow unicode sObj.remove("v"); sObj.remove("time"); sObj.remove(F("error")); diff --git a/wled00/udp.cpp b/wled00/udp.cpp index cc0cb22b..2d1388f8 100644 --- a/wled00/udp.cpp +++ b/wled00/udp.cpp @@ -411,10 +411,10 @@ void handleNotifications() for (size_t i = 0; i < strip.getSegmentsNum(); i++) { Segment& seg = strip.getSegment(i); if (!seg.isActive() || !seg.isSelected()) continue; - if (udpIn[8] < strip.getModeCount()) strip.setMode(i, udpIn[8]); + seg.setMode(udpIn[8]); seg.speed = udpIn[9]; if (version > 2) seg.intensity = udpIn[16]; - if (version > 4 && udpIn[19] < strip.getPaletteCount()) seg.palette = udpIn[19]; + if (version > 4) seg.setPalette(udpIn[19]); } stateChanged = true; } diff --git a/wled00/wled.h b/wled00/wled.h index 8ca29ef4..76b108f7 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2211242 +#define VERSION 2211250 //uncomment this if you have a "my_config.h" file you'd like to use //#define WLED_USE_MY_CONFIG