diff --git a/CHANGELOG.md b/CHANGELOG.md
index 641568de5..55e5a8e4d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,26 @@
## WLED changelog
+#### Build 2305280
+- DDP protocol update (#3193)
+- added PCF8574 I2C port expander support for Multi relay usermod
+- MQTT multipacket (fragmented) message fix
+- new ethernet board: @srg74 Ethernet Shield
+- new 2D effects: Soap (#3184) & Octopus & Waving cell (credit @St3P40 https://github.com/80Stepko08)
+- various fixes and enhancements
+
+#### Build 2305090
+- new ethernet board: @Wladi ABC! WLED Eth
+- Battery usermod voltage calculation (#3116)
+- custom palette editor (#3164)
+- improvements in Dancing Shadows and Tartan effects
+- UCS389x support
+- switched to NeoPixelBus 2.7.5 (replaced NeoPixelBrightnessBus with NeoPixelBusLg)
+- SPI bus clock selection (for LEDs) (#3173)
+- DMX mode preset fix (#3134)
+- iOS fix for scroll (#3182)
+- Wordclock "Norddeutsch" fix (#3161)
+- various fixes and enhancements
+
#### Build 2304090
- updated Arduino ESP8266 core to 4.1.0 (newer compiler)
- updated NeoPixelBus to 2.7.3 (with support for UCS890x chipset)
diff --git a/platformio.ini b/platformio.ini
index 5bd8a6995..ae0e4abd4 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -178,14 +178,12 @@ lib_deps =
https://github.com/Aircoookie/ESPAsyncWebServer.git @ ~2.0.7
#For use of the TTGO T-Display ESP32 Module with integrated TFT display uncomment the following line
#TFT_eSPI
- #For use SSD1306 OLED display uncomment following
- #U8g2@~2.28.8
- #U8g2@~2.32.10
- #For Dallas sensor uncomment following 2 lines
- #OneWire@~2.3.5
- #milesburton/DallasTemperature@^3.9.0
+ #For compatible OLED display uncomment following
+ #U8g2 #@ ~2.33.15
+ #For Dallas sensor uncomment following
+ #OneWire @ ~2.3.7
#For BME280 sensor uncomment following
- #BME280@~3.0.0
+ #BME280 @ ~3.0.0
; adafruit/Adafruit BMP280 Library @ 2.1.0
; adafruit/Adafruit CCS811 Library @ 1.0.4
; adafruit/Adafruit Si7021 Library @ 1.4.0
diff --git a/wled00/FX.cpp b/wled00/FX.cpp
index 5d0d30ba7..6428c8a0b 100644
--- a/wled00/FX.cpp
+++ b/wled00/FX.cpp
@@ -2805,7 +2805,7 @@ uint16_t mode_bouncing_balls(void) {
// number of balls based on intensity setting to max of 7 (cycles colors)
// non-chosen color is a random color
uint16_t numBalls = (SEGMENT.intensity * (maxNumBalls - 1)) / 255 + 1; // minimum 1 ball
- const float gravity = -9.81; // standard value of gravity
+ const float gravity = -9.81f; // standard value of gravity
const bool hasCol2 = SEGCOLOR(2);
const unsigned long time = millis();
@@ -4175,11 +4175,9 @@ static const char _data_FX_MODE_DANCING_SHADOWS[] PROGMEM = "Dancing Shadows@!,#
By Stefan Seegel
*/
uint16_t mode_washing_machine(void) {
- float speed = tristate_square8(strip.now >> 7, 90, 15);
- float quot = 32.0f - ((float)SEGMENT.speed / 16.0f);
- speed /= quot;
+ int speed = tristate_square8(strip.now >> 7, 90, 15);
- SEGENV.step += (speed * 128.0f);
+ SEGENV.step += (speed * 2048) / (512 - SEGMENT.speed);
for (int i = 0; i < SEGLEN; i++) {
uint8_t col = sin8(((SEGMENT.intensity / 25 + 1) * 255 * i / SEGLEN) + (SEGENV.step >> 7));
@@ -4593,7 +4591,7 @@ uint16_t mode_2DBlackHole(void) { // By: Stepko https://editor.soulma
}
SEGMENT.fadeToBlackBy(16 + (SEGMENT.speed>>3)); // create fading trails
- float t = (float)(millis())/128; // timebase
+ unsigned long t = millis()/128; // timebase
// outer stars
for (size_t i = 0; i < 8; i++) {
x = beatsin8(SEGMENT.custom1>>3, 0, cols - 1, 0, ((i % 2) ? 128 : 0) + t * i);
diff --git a/wled00/FX.h b/wled00/FX.h
index 745e10f7a..3bb3300c4 100644
--- a/wled00/FX.h
+++ b/wled00/FX.h
@@ -515,7 +515,7 @@ typedef struct Segment {
static uint16_t getUsedSegmentData(void) { return _usedSegmentData; }
static void addUsedSegmentData(int len) { _usedSegmentData += len; }
- void set(uint16_t i1, uint16_t i2, uint8_t grp=1, uint8_t spc=0, uint16_t ofs=UINT16_MAX, uint16_t i1Y=0, uint16_t i2Y=1);
+ void setUp(uint16_t i1, uint16_t i2, uint8_t grp=1, uint8_t spc=0, uint16_t ofs=UINT16_MAX, uint16_t i1Y=0, uint16_t i2Y=1);
bool setColor(uint8_t slot, uint32_t c); //returns true if changed
void setCCT(uint16_t k);
void setOpacity(uint8_t o);
diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp
index d3363cb95..624ce4ec5 100644
--- a/wled00/FX_fcn.cpp
+++ b/wled00/FX_fcn.cpp
@@ -152,12 +152,12 @@ bool Segment::allocateData(size_t len) {
if (data && _dataLen == len) return true; //already allocated
deallocateData();
if (Segment::getUsedSegmentData() + len > MAX_SEGMENT_DATA) return false; //not enough memory
- // if possible use SPI RAM on ESP32
- #if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM)
- if (psramFound())
- data = (byte*) ps_malloc(len);
- else
- #endif
+ // do not use SPI RAM on ESP32 since it is slow
+ //#if defined(ARDUINO_ARCH_ESP32) && defined(BOARD_HAS_PSRAM) && defined(WLED_USE_PSRAM)
+ //if (psramFound())
+ // data = (byte*) ps_malloc(len);
+ //else
+ //#endif
data = (byte*) malloc(len);
if (!data) return false; //allocation failed
Segment::addUsedSegmentData(len);
@@ -379,7 +379,7 @@ void Segment::handleTransition() {
}
}
-void Segment::set(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t ofs, uint16_t i1Y, uint16_t i2Y) {
+void Segment::setUp(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t ofs, uint16_t i1Y, uint16_t i2Y) {
//return if neither bounds nor grouping have changed
bool boundsUnchanged = (start == i1 && stop == i2);
#ifndef WLED_DISABLE_2D
@@ -1427,7 +1427,7 @@ Segment& WS2812FX::getSegment(uint8_t id) {
void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping, uint8_t spacing, uint16_t offset, uint16_t startY, uint16_t stopY) {
if (n >= _segments.size()) return;
- _segments[n].set(i1, i2, grouping, spacing, offset, startY, stopY);
+ _segments[n].setUp(i1, i2, grouping, spacing, offset, startY, stopY);
}
void WS2812FX::restartRuntime() {
diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp
index 316048be9..16daac68d 100644
--- a/wled00/cfg.cpp
+++ b/wled00/cfg.cpp
@@ -438,6 +438,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
getStringFromJson(mqttDeviceTopic, if_mqtt[F("topics")][F("device")], 33); // "wled/test"
getStringFromJson(mqttGroupTopic, if_mqtt[F("topics")][F("group")], 33); // ""
+ CJSON(retainMqttMsg, if_mqtt[F("rtn")]);
#endif
#ifndef WLED_DISABLE_HUESYNC
@@ -885,6 +886,7 @@ void serializeConfig() {
if_mqtt[F("user")] = mqttUser;
if_mqtt[F("pskl")] = strlen(mqttPass);
if_mqtt[F("cid")] = mqttClientID;
+ if_mqtt[F("rtn")] = retainMqttMsg;
JsonObject if_mqtt_topics = if_mqtt.createNestedObject(F("topics"));
if_mqtt_topics[F("device")] = mqttDeviceTopic;
diff --git a/wled00/data/index.htm b/wled00/data/index.htm
index 4df0ad8ee..530b23856 100644
--- a/wled00/data/index.htm
+++ b/wled00/data/index.htm
@@ -72,7 +72,7 @@
Brightness
-
+
diff --git a/wled00/data/index.js b/wled00/data/index.js
index 93ad3f132..3ba3f5254 100644
--- a/wled00/data/index.js
+++ b/wled00/data/index.js
@@ -965,8 +965,8 @@ function genPalPrevCss(id)
function generateListItemHtml(listName, id, name, clickAction, extraHtml = '', effectPar = '')
{
- return `
`+
- `