diff --git a/CHANGELOG.md b/CHANGELOG.md
index efbe90a5..e9f86e23 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,20 @@
## WLED changelog
-### Builds after release 0.13.1
+### WLED release 0.13.2
+
+#### Build 2208140
+
+- Version bump to v0.13.2 "Toki"
+- Added option to receive live data on the main segment only (PR #2601)
+- Enable ESP watchdog by default (PR #2657)
+- Fixed race condition when saving bus config
+- Better potentiometer filtering (PR #2693)
+- More suitable DMX libraries (PR #2652)
+- Fixed outgoing serial TPM2 message length (PR #2628)
+- Fixed next universe overflow and Art-Net DMX start address (PR #2607)
+- Fixed relative segment brightness (PR #2665)
+
+### Builds between releases 0.13.1 and 0.13.2
#### Build 2203191
diff --git a/usermods/PWM_fan/usermod_PWM_fan.h b/usermods/PWM_fan/usermod_PWM_fan.h
index ba4e1726..fec2e726 100644
--- a/usermods/PWM_fan/usermod_PWM_fan.h
+++ b/usermods/PWM_fan/usermod_PWM_fan.h
@@ -51,6 +51,7 @@ class PWMFanUsermod : public Usermod {
float targetTemperature = 25.0;
uint8_t minPWMValuePct = 50;
uint8_t numberOfInterrupsInOneSingleRotation = 2; // Number of interrupts ESP32 sees on tacho signal on a single fan rotation. All the fans I've seen trigger two interrups.
+ uint8_t pwmValuePct = 0;
// strings to reduce flash memory usage (used more than twice)
static const char _name[];
@@ -83,6 +84,8 @@ class PWMFanUsermod : public Usermod {
}
void updateTacho(void) {
+ // store milliseconds when tacho was measured the last time
+ msLastTachoMeasurement = millis();
if (tachoPin < 0) return;
// start of tacho measurement
@@ -93,8 +96,6 @@ class PWMFanUsermod : public Usermod {
last_rpm /= tachoUpdateSec;
// reset counter
counter_rpm = 0;
- // store milliseconds when tacho was measured the last time
- msLastTachoMeasurement = millis();
// attach interrupt again
attachInterrupt(digitalPinToInterrupt(tachoPin), rpm_fan, FALLING);
}
@@ -102,6 +103,7 @@ class PWMFanUsermod : public Usermod {
// https://randomnerdtutorials.com/esp32-pwm-arduino-ide/
void initPWMfan(void) {
if (pwmPin < 0 || !pinManager.allocatePin(pwmPin, true, PinOwner::UM_Unspecified)) {
+ enabled = false;
pwmPin = -1;
return;
}
@@ -217,12 +219,41 @@ class PWMFanUsermod : public Usermod {
* Below it is shown how this could be used for e.g. a light sensor
*/
void addToJsonInfo(JsonObject& root) {
- if (tachoPin < 0) return;
JsonObject user = root["u"];
if (user.isNull()) user = root.createNestedObject("u");
- JsonArray data = user.createNestedArray(FPSTR(_name));
- data.add(last_rpm);
- data.add(F("rpm"));
+
+ JsonArray infoArr = user.createNestedArray(FPSTR(_name));
+ String uiDomString = F("");
+ infoArr.add(uiDomString);
+
+ if (enabled) {
+ JsonArray infoArr = user.createNestedArray(F("Manual"));
+ String uiDomString = F("
"); //
+ infoArr.add(uiDomString);
+
+ JsonArray data = user.createNestedArray(F("Speed"));
+ if (tachoPin >= 0) {
+ data.add(last_rpm);
+ data.add(F("rpm"));
+ } else {
+ if (lockFan) data.add(F("locked"));
+ else data.add(F("auto"));
+ }
+ }
}
/*
@@ -237,14 +268,19 @@ class PWMFanUsermod : public Usermod {
* Values in the state object may be modified by connected clients
*/
void readFromJsonState(JsonObject& root) {
- if (!initDone || !enabled) return; // prevent crash on boot applyPreset()
+ if (!initDone) return; // prevent crash on boot applyPreset()
JsonObject usermod = root[FPSTR(_name)];
if (!usermod.isNull()) {
- if (!usermod[FPSTR(_speed)].isNull() && usermod[FPSTR(_speed)].is()) {
- int pwmValuePct = usermod[FPSTR(_speed)].as();
- updateFanSpeed((MAX(0,MIN(100,pwmValuePct)) * 255) / 100);
+ if (usermod[FPSTR(_enabled)].is()) {
+ enabled = usermod[FPSTR(_enabled)].as();
+ if (!enabled) updateFanSpeed(0);
}
- if (!usermod[FPSTR(_lock)].isNull() && usermod[FPSTR(_lock)].is()) {
+ if (enabled && !usermod[FPSTR(_speed)].isNull() && usermod[FPSTR(_speed)].is()) {
+ pwmValuePct = usermod[FPSTR(_speed)].as();
+ updateFanSpeed((constrain(pwmValuePct,0,100) * 255) / 100);
+ if (pwmValuePct) lockFan = true;
+ }
+ if (enabled && !usermod[FPSTR(_lock)].isNull() && usermod[FPSTR(_lock)].is()) {
lockFan = usermod[FPSTR(_lock)].as();
}
}
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 927e9e16..38a055a5 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
@@ -312,19 +312,30 @@ class FourLineDisplayUsermod : public Usermod {
bool isHW, isSPI = (type == SSD1306_SPI || type == SSD1306_SPI64);
PinOwner po = PinOwner::UM_FourLineDisplay;
if (isSPI) {
- PinManagerPinType cspins[2] = { { ioPin[3], true }, { ioPin[4], true } };
- if (!pinManager.allocateMultiplePins(cspins, 2, PinOwner::UM_FourLineDisplay)) { type=NONE; return; }
- isHW = (ioPin[0]==spi_sclk && ioPin[1]==spi_mosi && ioPin[2]==spi_cs);
+ uint8_t hw_sclk = spi_sclk<0 ? HW_PIN_CLOCKSPI : spi_sclk;
+ uint8_t hw_mosi = spi_mosi<0 ? HW_PIN_DATASPI : spi_mosi;
+ if (ioPin[0] < 0 || ioPin[1] < 0) {
+ ioPin[0] = hw_sclk;
+ ioPin[1] = hw_mosi;
+ }
+ isHW = (ioPin[0]==hw_sclk && ioPin[1]==hw_mosi);
+ PinManagerPinType cspins[3] = { { ioPin[2], true }, { ioPin[3], true }, { ioPin[4], true } };
+ if (!pinManager.allocateMultiplePins(cspins, 3, PinOwner::UM_FourLineDisplay)) { type=NONE; return; }
if (isHW) po = PinOwner::HW_SPI; // allow multiple allocations of HW I2C bus pins
- PinManagerPinType pins[3] = { { ioPin[0], true }, { ioPin[1], true }, { ioPin[2], true } };
- if (!pinManager.allocateMultiplePins(pins, 5, po)) {
- pinManager.deallocatePin(ioPin[3], PinOwner::UM_FourLineDisplay);
- pinManager.deallocatePin(ioPin[4], PinOwner::UM_FourLineDisplay);
+ PinManagerPinType pins[2] = { { ioPin[0], true }, { ioPin[1], true } };
+ if (!pinManager.allocateMultiplePins(pins, 2, po)) {
+ pinManager.deallocateMultiplePins(cspins, 3, PinOwner::UM_FourLineDisplay);
type = NONE;
return;
}
} else {
- isHW = (ioPin[0]==i2c_scl && ioPin[1]==i2c_sda);
+ uint8_t hw_scl = i2c_scl<0 ? HW_PIN_SCL : i2c_scl;
+ uint8_t hw_sda = i2c_sda<0 ? HW_PIN_SDA : i2c_sda;
+ if (ioPin[0] < 0 || ioPin[1] < 0) {
+ ioPin[0] = hw_scl;
+ ioPin[1] = hw_sda;
+ }
+ isHW = (ioPin[0]==hw_scl && ioPin[1]==hw_sda);
if (isHW) po = PinOwner::HW_I2C; // allow multiple allocations of HW I2C bus pins
PinManagerPinType pins[2] = { {ioPin[0], true }, { ioPin[1], true } };
if (!pinManager.allocateMultiplePins(pins, 2, po)) { type=NONE; return; }
@@ -1019,8 +1030,8 @@ 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');"));
- oappend(SET_F("addInfo('4LineDisplay:pin[]',1,'I2C/SPI DTA');"));
+ 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');"));
@@ -1071,7 +1082,7 @@ class FourLineDisplayUsermod : public Usermod {
bool readFromConfig(JsonObject& root) {
bool needsRedraw = false;
DisplayType newType = type;
- int8_t newPin[5]; for (byte i=0; i<5; i++) newPin[i] = ioPin[i];
+ int8_t oldPin[5]; for (byte i=0; i<5; i++) oldPin[i] = ioPin[i];
JsonObject top = root[FPSTR(_name)];
if (top.isNull()) {
@@ -1082,7 +1093,7 @@ class FourLineDisplayUsermod : public Usermod {
enabled = top[FPSTR(_enabled)] | enabled;
newType = top["type"] | newType;
- for (byte i=0; i<5; i++) newPin[i] = top["pin"][i] | ioPin[i];
+ for (byte i=0; i<5; i++) ioPin[i] = top["pin"][i] | ioPin[i];
flip = top[FPSTR(_flip)] | flip;
contrast = top[FPSTR(_contrast)] | contrast;
#ifndef ARDUINO_ARCH_ESP32
@@ -1102,26 +1113,31 @@ class FourLineDisplayUsermod : public Usermod {
DEBUG_PRINT(FPSTR(_name));
if (!initDone) {
// first run: reading from cfg.json
- for (byte i=0; i<5; i++) ioPin[i] = newPin[i];
type = newType;
DEBUG_PRINTLN(F(" config loaded."));
} else {
DEBUG_PRINTLN(F(" config (re)loaded."));
// changing parameters from settings page
bool pinsChanged = false;
- for (byte i=0; i<5; i++) if (ioPin[i] != newPin[i]) { pinsChanged = true; break; }
+ for (byte i=0; i<5; i++) if (ioPin[i] != oldPin[i]) { pinsChanged = true; break; }
if (pinsChanged || type!=newType) {
if (type != NONE) delete u8x8;
PinOwner po = PinOwner::UM_FourLineDisplay;
bool isSPI = (type == SSD1306_SPI || type == SSD1306_SPI64);
- if (!isSPI && ioPin[0]==i2c_scl && ioPin[1]==i2c_sda) po = PinOwner::HW_I2C; // allow multiple allocations of HW I2C bus pins
- if (isSPI && ioPin[0]==spi_sclk && ioPin[1]==spi_mosi && ioPin[2]==spi_cs) po = PinOwner::HW_SPI; // allow multiple allocations of HW SPI bus pins
- pinManager.deallocateMultiplePins((const uint8_t *)ioPin, isSPI ? 5 : 2, po);
- for (byte i=0; i<5; i++) ioPin[i] = newPin[i];
- if (ioPin[0]<0 || ioPin[1]<0) { // data & clock must be > -1
- type = NONE;
- return true;
- } else type = newType;
+ if (isSPI) {
+ pinManager.deallocateMultiplePins((const uint8_t *)(&oldPin[2]), 3, po);
+ uint8_t hw_sclk = spi_sclk<0 ? HW_PIN_CLOCKSPI : spi_sclk;
+ uint8_t hw_mosi = spi_mosi<0 ? HW_PIN_DATASPI : spi_mosi;
+ bool isHW = (oldPin[0]==hw_sclk && oldPin[1]==hw_mosi);
+ if (isHW) po = PinOwner::HW_SPI;
+ } else {
+ uint8_t hw_scl = i2c_scl<0 ? HW_PIN_SCL : i2c_scl;
+ uint8_t hw_sda = i2c_sda<0 ? HW_PIN_SDA : i2c_sda;
+ bool isHW = (oldPin[0]==hw_scl && oldPin[1]==hw_sda);
+ if (isHW) po = PinOwner::HW_I2C;
+ }
+ pinManager.deallocateMultiplePins((const uint8_t *)oldPin, 2, po);
+ type = newType;
setup();
needsRedraw |= true;
} else {
diff --git a/wled00/FX.cpp b/wled00/FX.cpp
index aee00737..6c797748 100644
--- a/wled00/FX.cpp
+++ b/wled00/FX.cpp
@@ -75,7 +75,7 @@ int8_t tristate_square8(uint8_t x, uint8_t pulsewidth, uint8_t attdec) {
*/
uint16_t mode_static(void) {
SEGMENT.fill(SEGCOLOR(0));
- return /*(SEGMENT.getOption(SEG_OPTION_TRANSITIONAL)) ? FRAMETIME :*/ 350; //update faster if in transition
+ return 350;
}
static const char _data_FX_MODE_STATIC[] PROGMEM = "Solid";
@@ -2157,7 +2157,7 @@ uint16_t mode_noise16_2()
//fastled_col = ColorFromPalette(SEGPALETTE, index, noise, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED.
//SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue);
- SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0));
+ SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0, noise));
}
return FRAMETIME;
@@ -2182,7 +2182,7 @@ uint16_t mode_noise16_3()
//fastled_col = ColorFromPalette(SEGPALETTE, index, noise, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED.
//SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue);
- SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0));
+ SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0, noise));
}
return FRAMETIME;
@@ -3987,7 +3987,7 @@ uint16_t mode_flow(void)
{
uint8_t colorIndex = (i * 255 / zoneLen) - counter;
uint16_t led = (z & 0x01) ? i : (zoneLen -1) -i;
- if (SEGMENT.getOption(SEG_OPTION_REVERSED)) led = (zoneLen -1) -led;
+ if (SEGMENT.reverse) led = (zoneLen -1) -led;
SEGMENT.setPixelColor(pos + led, SEGMENT.color_from_palette(colorIndex, false, true, 255));
}
}
@@ -4928,7 +4928,7 @@ uint16_t mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https:
SEGENV.aux1 = SEGENV.aux0;
SEGENV.aux0 = crc;
- return (SEGMENT.getOption(SEG_OPTION_TRANSITIONAL)) ? FRAMETIME : FRAMETIME_FIXED * (128-(SEGMENT.speed>>1)); // update only when appropriate time passes (in 42 FPS slots)
+ return FRAMETIME_FIXED * (128-(SEGMENT.speed>>1)); // update only when appropriate time passes (in 42 FPS slots)
} // mode_2Dgameoflife()
static const char _data_FX_MODE_2DGAMEOFLIFE[] PROGMEM = "Game Of Life@!,;!,!;!;2d";
diff --git a/wled00/FX.h b/wled00/FX.h
index b160622d..486c9af4 100644
--- a/wled00/FX.h
+++ b/wled00/FX.h
@@ -344,7 +344,7 @@ typedef enum mapping1D2D {
M12_Block = 3
} mapping1D2D_t;
-// segment, 68 (92 in memory) bytes
+// segment, 72 bytes
typedef struct Segment {
public:
uint16_t start; // start index / start X coordinate 2D (left)
@@ -357,34 +357,38 @@ typedef struct Segment {
union {
uint16_t options; //bit pattern: msb first: [transposed mirrorY reverseY] transitional (tbd) paused needspixelstate mirrored on reverse selected
struct {
- bool selected : 1; // 0 : selected
- bool reverse : 1; // 1 : reversed
- bool on : 1; // 2 : is On
- bool mirror : 1; // 3 : mirrored
- bool pxs : 1; // 4 : indicates that the effect does not use FRAMETIME or needs getPixelColor (?)
- bool freeze : 1; // 5 : paused/frozen
- bool reset : 1; // 6 : indicates that Segment runtime requires reset
- bool transitional: 1; // 7 : transitional (there is transition occuring)
- bool reverse_y : 1; // 8 : reversed Y (2D)
- bool mirror_y : 1; // 9 : mirrored Y (2D)
- bool transpose : 1; // 10 : transposed (2D, swapped X & Y)
- uint8_t map1D2D : 2; // 11-12 : mapping for 1D effect on 2D (0-strip, 1-expand vertically, 2-circular, 3-rectangular)
- uint8_t soundSim : 3; // 13-15 : 0-7 sound simulation types
+ bool selected : 1; // 0 : selected
+ bool reverse : 1; // 1 : reversed
+ bool on : 1; // 2 : is On
+ bool mirror : 1; // 3 : mirrored
+ bool pxs : 1; // 4 : indicates that the effect does not use FRAMETIME or needs getPixelColor (?)
+ bool freeze : 1; // 5 : paused/frozen
+ bool reset : 1; // 6 : indicates that Segment runtime requires reset
+ bool transitional: 1; // 7 : transitional (there is transition occuring)
+ bool reverse_y : 1; // 8 : reversed Y (2D)
+ bool mirror_y : 1; // 9 : mirrored Y (2D)
+ bool transpose : 1; // 10 : transposed (2D, swapped X & Y)
+ uint8_t map1D2D : 3; // 11-13 : mapping for 1D effect on 2D (0-use as strip, 1-expand vertically, 2-circular/arc, 3-rectangular/corner, ...)
+ uint8_t soundSim : 2; // 14-15 : 0-3 sound simulation types
};
};
uint8_t grouping, spacing;
+ //struct {
+ // uint8_t grouping : 4; // maximum 15 pixels in a group
+ // uint8_t spacing : 4; // maximum 15 pixels per gap
+ //};
uint8_t opacity;
uint32_t colors[NUM_COLORS];
- uint8_t cct; //0==1900K, 255==10091K
- uint8_t custom1, custom2; // custom FX parameters/sliders
+ uint8_t cct; //0==1900K, 255==10091K
+ uint8_t custom1, custom2; // custom FX parameters/sliders
struct {
- uint8_t custom3 : 5; // reduced range slider (0-31)
- bool check1 : 1; // checkmark 1
- bool check2 : 1; // checkmark 2
- bool check3 : 1; // checkmark 3
+ uint8_t custom3 : 5; // reduced range slider (0-31)
+ bool check1 : 1; // checkmark 1
+ bool check2 : 1; // checkmark 2
+ bool check3 : 1; // checkmark 3
};
- uint16_t startY; // start Y coodrinate 2D (top)
- uint16_t stopY; // stop Y coordinate 2D (bottom)
+ uint8_t startY; // start Y coodrinate 2D (top); there should be no more than 255 rows
+ uint8_t stopY; // stop Y coordinate 2D (bottom); there should be no more than 255 rows
char *name;
// runtime data
@@ -491,18 +495,18 @@ typedef struct Segment {
Segment& operator= (Segment &&orig) noexcept; // move assignment
#ifdef WLED_DEBUG
- size_t getSize() { return sizeof(Segment) + (data?_dataLen:0) + (name?strlen(name):0) + (_t?sizeof(Transition):0) + (!Segment::_globalLeds && leds?sizeof(CRGB)*length():0); }
+ size_t getSize() const { return sizeof(Segment) + (data?_dataLen:0) + (name?strlen(name):0) + (_t?sizeof(Transition):0) + (!Segment::_globalLeds && leds?sizeof(CRGB)*length():0); }
#endif
- inline bool getOption(uint8_t n) { return ((options >> n) & 0x01); }
- inline bool isSelected(void) { return selected; }
- inline bool isActive(void) { return stop > start; }
- inline bool is2D(void) { return !(startY == 0 && stopY == 1); }
- inline uint16_t width(void) { return stop - start; } // segment width in physical pixels (length if 1D)
- inline uint16_t height(void) { return stopY - startY; } // segment height (if 2D) in physical pixels
- inline uint16_t length(void) { return width() * height(); } // segment length (count) in physical pixels
- inline uint16_t groupLength(void) { return grouping + spacing; }
- inline uint8_t getLightCapabilities(void) { return _capabilities; }
+ inline bool getOption(uint8_t n) const { return ((options >> n) & 0x01); }
+ inline bool isSelected(void) const { return selected; }
+ inline bool isActive(void) const { return stop > start; }
+ inline bool is2D(void) const { return !(startY == 0 && stopY == 1); }
+ inline uint16_t width(void) const { return stop - start; } // segment width in physical pixels (length if 1D)
+ inline uint16_t height(void) const { return stopY - startY; } // segment height (if 2D) in physical pixels
+ inline uint16_t length(void) const { return width() * height(); } // segment length (count) in physical pixels
+ inline uint16_t groupLength(void) const { return grouping + spacing; }
+ inline uint8_t getLightCapabilities(void) const { return _capabilities; }
static uint16_t getUsedSegmentData(void) { return _usedSegmentData; }
static void addUsedSegmentData(int len) { _usedSegmentData += len; }
@@ -511,11 +515,11 @@ typedef struct Segment {
void setCCT(uint16_t k);
void setOpacity(uint8_t o);
void setOption(uint8_t n, bool val);
- uint8_t differs(Segment& b);
+ uint8_t differs(Segment& b) const;
void refreshLightCapabilities(void);
// runtime data functions
- inline uint16_t dataSize(void) { return _dataLen; }
+ inline uint16_t dataSize(void) const { return _dataLen; }
bool allocateData(size_t len);
void deallocateData(void);
void resetIfRequired(void);
@@ -540,7 +544,7 @@ typedef struct Segment {
CRGBPalette16 ¤tPalette(CRGBPalette16 &tgt, uint8_t paletteID);
// 1D strip
- uint16_t virtualLength(void);
+ uint16_t virtualLength(void) const;
void setPixelColor(int n, uint32_t c); // set relative pixel within segment with color
void setPixelColor(int n, byte r, byte g, byte b, byte w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); } // automatically inline
void setPixelColor(int n, CRGB c) { setPixelColor(n, RGBW32(c.r,c.g,c.b,0)); } // automatically inline
@@ -564,8 +568,8 @@ typedef struct Segment {
uint32_t color_wheel(uint8_t pos);
// 2D matrix
- uint16_t virtualWidth(void);
- uint16_t virtualHeight(void);
+ uint16_t virtualWidth(void) const;
+ uint16_t virtualHeight(void) const;
#ifndef WLED_DISABLE_2D
uint16_t XY(uint16_t x, uint16_t y); // support function to get relative index within segment (for leds[])
void setPixelColorXY(int x, int y, uint32_t c); // set relative pixel within segment with color
@@ -627,7 +631,7 @@ typedef struct Segment {
void wu_pixel(uint32_t x, uint32_t y, CRGB c) {}
#endif
} segment;
-//static int i = sizeof(Segment);
+//static int segSize = sizeof(Segment);
// main "strip" class
class WS2812FX { // 96 bytes
diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp
index 8e112f82..dedff0ef 100644
--- a/wled00/FX_fcn.cpp
+++ b/wled00/FX_fcn.cpp
@@ -386,14 +386,14 @@ void Segment::setOption(uint8_t n, bool val) {
}
// 2D matrix
-uint16_t Segment::virtualWidth() {
+uint16_t Segment::virtualWidth() const {
uint16_t groupLen = groupLength();
uint16_t vWidth = ((transpose ? height() : width()) + groupLen - 1) / groupLen;
if (mirror) vWidth = (vWidth + 1) /2; // divide by 2 if mirror, leave at least a single LED
return vWidth;
}
-uint16_t Segment::virtualHeight() {
+uint16_t Segment::virtualHeight() const {
uint16_t groupLen = groupLength();
uint16_t vHeight = ((transpose ? width() : height()) + groupLen - 1) / groupLen;
if (mirror_y) vHeight = (vHeight + 1) /2; // divide by 2 if mirror, leave at least a single LED
@@ -401,7 +401,7 @@ uint16_t Segment::virtualHeight() {
}
// 1D strip
-uint16_t Segment::virtualLength() {
+uint16_t Segment::virtualLength() const {
#ifndef WLED_DISABLE_2D
if (is2D()) {
uint16_t vW = virtualWidth();
@@ -561,7 +561,7 @@ uint32_t Segment::getPixelColor(uint16_t i)
return strip.getPixelColor(i);
}
-uint8_t Segment::differs(Segment& b) {
+uint8_t Segment::differs(Segment& b) const {
uint8_t d = 0;
if (start != b.start) d |= SEG_DIFFERS_BOUNDS;
if (stop != b.stop) d |= SEG_DIFFERS_BOUNDS;
@@ -583,7 +583,7 @@ uint8_t Segment::differs(Segment& b) {
if ((options & 0b1111111100101110) != (b.options & 0b1111111100101110)) d |= SEG_DIFFERS_OPT;
if ((options & 0x01) != (b.options & 0x01)) d |= SEG_DIFFERS_SEL;
- for (uint8_t i = 0; i < NUM_COLORS; i++) if (colors[i] != b.colors[i]) d |= SEG_DIFFERS_COL;
+ for (uint8_t i = 0; i < NUM_COLORS; i++) if (colors[i] != b.colors[i]) d |= SEG_DIFFERS_COL;
return d;
}
@@ -1106,7 +1106,7 @@ void WS2812FX::setBrightness(uint8_t b, bool direct) {
_brightness = b;
if (_brightness == 0) { //unfreeze all segments on power off
for (segment &seg : _segments) {
- seg.setOption(SEG_OPTION_FREEZE, false);
+ seg.freeze = false;
}
}
if (direct) {
@@ -1319,7 +1319,7 @@ void WS2812FX::makeAutoSegments(bool forceReset) {
_segments.clear();
for (size_t i = 0; i < s; i++) {
Segment seg = Segment(segStarts[i], segStops[i]);
- seg.setOption(SEG_OPTION_SELECTED, true);
+ seg.selected = true;
_segments.push_back(seg);
}
_mainSegment = 0;
@@ -1394,7 +1394,7 @@ void WS2812FX::setTransitionMode(bool t)
void WS2812FX::printSize()
{
size_t size = 0;
- for (Segment seg : _segments) size += seg.getSize();
+ for (const Segment seg : _segments) size += seg.getSize();
DEBUG_PRINTF("Segments: %d -> %uB\n", _segments.size(), size);
DEBUG_PRINTF("Modes: %d*%d=%uB\n", sizeof(mode_ptr), _mode.size(), (_mode.capacity()*sizeof(mode_ptr)));
DEBUG_PRINTF("Data: %d*%d=%uB\n", sizeof(const char *), _modeData.size(), (_modeData.capacity()*sizeof(const char *)));
diff --git a/wled00/bus_wrapper.h b/wled00/bus_wrapper.h
index 6a343442..e2783236 100644
--- a/wled00/bus_wrapper.h
+++ b/wled00/bus_wrapper.h
@@ -33,6 +33,11 @@
#define I_8266_U1_TM1_4 14
#define I_8266_DM_TM1_4 15
#define I_8266_BB_TM1_4 16
+//TM1829 (RGB)
+#define I_8266_U0_TM2_3 39
+#define I_8266_U1_TM2_3 40
+#define I_8266_DM_TM2_3 41
+#define I_8266_BB_TM2_3 42
/*** ESP32 Neopixel methods ***/
//RGB
@@ -52,6 +57,11 @@
#define I_32_I0_TM1_4 27
#define I_32_I1_TM1_4 28
//Bit Bang theoratically possible, but very undesirable and not needed (no pin restrictions on RMT and I2S)
+//TM1829 (RGB)
+#define I_32_RN_TM2_3 43
+#define I_32_I0_TM2_3 44
+#define I_32_I1_TM2_3 45
+//Bit Bang theoratically possible, but very undesirable and not needed (no pin restrictions on RMT and I2S)
//APA102
#define I_HS_DOT_3 29 //hardware SPI
@@ -69,6 +79,10 @@
#define I_HS_P98_3 35
#define I_SS_P98_3 36
+//LPD6803
+#define I_HS_LPO_3 37
+#define I_SS_LPO_3 38
+
/*** ESP8266 Neopixel methods ***/
#ifdef ESP8266
@@ -92,6 +106,11 @@
#define B_8266_U1_TM1_4 NeoPixelBrightnessBus
#define B_8266_DM_TM1_4 NeoPixelBrightnessBus
#define B_8266_BB_TM1_4 NeoPixelBrightnessBus
+//TM1829 (RGB)
+#define B_8266_U0_TM2_4 NeoPixelBrightnessBus
+#define B_8266_U1_TM2_4 NeoPixelBrightnessBus
+#define B_8266_DM_TM2_4 NeoPixelBrightnessBus
+#define B_8266_BB_TM2_4 NeoPixelBrightnessBus
#endif
/*** ESP32 Neopixel methods ***/
@@ -129,6 +148,15 @@
#define B_32_I1_TM1_4 NeoPixelBrightnessBus
#endif
//Bit Bang theoratically possible, but very undesirable and not needed (no pin restrictions on RMT and I2S)
+//TM1829 (RGB)
+#define B_32_RN_TM2_3 NeoPixelBrightnessBus
+#ifndef CONFIG_IDF_TARGET_ESP32C3
+#define B_32_I0_TM2_3 NeoPixelBrightnessBus
+#endif
+#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
+#define B_32_I1_TM2_3 NeoPixelBrightnessBus
+#endif
+//Bit Bang theoratically possible, but very undesirable and not needed (no pin restrictions on RMT and I2S)
#endif
@@ -140,6 +168,10 @@
#define B_HS_LPD_3 NeoPixelBrightnessBus
#define B_SS_LPD_3 NeoPixelBrightnessBus
+//LPD6803
+#define B_HS_LPO_3 NeoPixelBrightnessBus
+#define B_SS_LPO_3 NeoPixelBrightnessBus
+
//WS2801
#if defined(WLED_WS2801_SPEED_KHZ) && WLED_WS2801_SPEED_KHZ==40000
#define B_HS_WS1_3 NeoPixelBrightnessBus // fastest bus speed (not existing method?)
@@ -193,8 +225,13 @@ class PolyBus {
case I_8266_U1_TM1_4: beginTM1814(busPtr); break;
case I_8266_DM_TM1_4: beginTM1814(busPtr); break;
case I_8266_BB_TM1_4: beginTM1814(busPtr); break;
+ case I_8266_U0_TM2_3: (static_cast(busPtr))->Begin(); break;
+ case I_8266_U1_TM2_3: (static_cast(busPtr))->Begin(); break;
+ case I_8266_DM_TM2_3: (static_cast(busPtr))->Begin(); break;
+ case I_8266_BB_TM2_3: (static_cast(busPtr))->Begin(); break;
case I_HS_DOT_3: (static_cast(busPtr))->Begin(); break;
case I_HS_LPD_3: (static_cast(busPtr))->Begin(); break;
+ case I_HS_LPO_3: (static_cast(busPtr))->Begin(); break;
case I_HS_WS1_3: (static_cast(busPtr))->Begin(); break;
case I_HS_P98_3: (static_cast(busPtr))->Begin(); break;
#endif
@@ -221,20 +258,25 @@ class PolyBus {
case I_32_I1_400_3: (static_cast(busPtr))->Begin(); break;
#endif
case I_32_RN_TM1_4: beginTM1814(busPtr); break;
+ case I_32_RN_TM2_3: (static_cast(busPtr))->Begin(); break;
#ifndef CONFIG_IDF_TARGET_ESP32C3
case I_32_I0_TM1_4: beginTM1814(busPtr); break;
+ case I_32_I0_TM2_3: (static_cast(busPtr))->Begin(); break;
#endif
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
case I_32_I1_TM1_4: beginTM1814(busPtr); break;
+ case I_32_I1_TM2_3: (static_cast(busPtr))->Begin(); break;
#endif
// ESP32 can (and should, to avoid inadvertantly driving the chip select signal) specify the pins used for SPI, but only in begin()
case I_HS_DOT_3: (static_cast(busPtr))->Begin(pins[1], -1, pins[0], -1); break;
case I_HS_LPD_3: (static_cast(busPtr))->Begin(pins[1], -1, pins[0], -1); break;
+ case I_HS_LPO_3: (static_cast(busPtr))->Begin(pins[1], -1, pins[0], -1); break;
case I_HS_WS1_3: (static_cast(busPtr))->Begin(pins[1], -1, pins[0], -1); break;
case I_HS_P98_3: (static_cast(busPtr))->Begin(pins[1], -1, pins[0], -1); break;
#endif
case I_SS_DOT_3: (static_cast(busPtr))->Begin(); break;
case I_SS_LPD_3: (static_cast(busPtr))->Begin(); break;
+ case I_SS_LPO_3: (static_cast(busPtr))->Begin(); break;
case I_SS_WS1_3: (static_cast(busPtr))->Begin(); break;
case I_SS_P98_3: (static_cast(busPtr))->Begin(); break;
}
@@ -260,6 +302,10 @@ class PolyBus {
case I_8266_U1_TM1_4: busPtr = new B_8266_U1_TM1_4(len, pins[0]); break;
case I_8266_DM_TM1_4: busPtr = new B_8266_DM_TM1_4(len, pins[0]); break;
case I_8266_BB_TM1_4: busPtr = new B_8266_BB_TM1_4(len, pins[0]); break;
+ case I_8266_U0_TM2_3: busPtr = new B_8266_U0_TM2_4(len, pins[0]); break;
+ case I_8266_U1_TM2_3: busPtr = new B_8266_U1_TM2_4(len, pins[0]); break;
+ case I_8266_DM_TM2_3: busPtr = new B_8266_DM_TM2_4(len, pins[0]); break;
+ case I_8266_BB_TM2_3: busPtr = new B_8266_BB_TM2_4(len, pins[0]); break;
#endif
#ifdef ARDUINO_ARCH_ESP32
case I_32_RN_NEO_3: busPtr = new B_32_RN_NEO_3(len, pins[0], (NeoBusChannel)channel); break;
@@ -284,11 +330,14 @@ class PolyBus {
case I_32_I1_400_3: busPtr = new B_32_I1_400_3(len, pins[0]); break;
#endif
case I_32_RN_TM1_4: busPtr = new B_32_RN_TM1_4(len, pins[0], (NeoBusChannel)channel); break;
+ case I_32_RN_TM2_3: busPtr = new B_32_RN_TM2_3(len, pins[0], (NeoBusChannel)channel); break;
#ifndef CONFIG_IDF_TARGET_ESP32C3
case I_32_I0_TM1_4: busPtr = new B_32_I0_TM1_4(len, pins[0]); break;
+ case I_32_I0_TM2_3: busPtr = new B_32_I0_TM2_3(len, pins[0]); break;
#endif
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
case I_32_I1_TM1_4: busPtr = new B_32_I1_TM1_4(len, pins[0]); break;
+ case I_32_I1_TM2_3: busPtr = new B_32_I1_TM2_3(len, pins[0]); break;
#endif
#endif
// for 2-wire: pins[1] is clk, pins[0] is dat. begin expects (len, clk, dat)
@@ -296,6 +345,8 @@ class PolyBus {
case I_SS_DOT_3: busPtr = new B_SS_DOT_3(len, pins[1], pins[0]); break;
case I_HS_LPD_3: busPtr = new B_HS_LPD_3(len, pins[1], pins[0]); break;
case I_SS_LPD_3: busPtr = new B_SS_LPD_3(len, pins[1], pins[0]); break;
+ case I_HS_LPO_3: busPtr = new B_HS_LPO_3(len, pins[1], pins[0]); break;
+ case I_SS_LPO_3: busPtr = new B_SS_LPO_3(len, pins[1], pins[0]); break;
case I_HS_WS1_3: busPtr = new B_HS_WS1_3(len, pins[1], pins[0]); break;
case I_SS_WS1_3: busPtr = new B_SS_WS1_3(len, pins[1], pins[0]); break;
case I_HS_P98_3: busPtr = new B_HS_P98_3(len, pins[1], pins[0]); break;
@@ -324,6 +375,10 @@ class PolyBus {
case I_8266_U1_TM1_4: (static_cast(busPtr))->Show(); break;
case I_8266_DM_TM1_4: (static_cast(busPtr))->Show(); break;
case I_8266_BB_TM1_4: (static_cast(busPtr))->Show(); break;
+ case I_8266_U0_TM2_3: (static_cast(busPtr))->Show(); break;
+ case I_8266_U1_TM2_3: (static_cast(busPtr))->Show(); break;
+ case I_8266_DM_TM2_3: (static_cast(busPtr))->Show(); break;
+ case I_8266_BB_TM2_3: (static_cast(busPtr))->Show(); break;
#endif
#ifdef ARDUINO_ARCH_ESP32
case I_32_RN_NEO_3: (static_cast(busPtr))->Show(); break;
@@ -348,17 +403,22 @@ class PolyBus {
case I_32_I1_400_3: (static_cast(busPtr))->Show(); break;
#endif
case I_32_RN_TM1_4: (static_cast(busPtr))->Show(); break;
+ case I_32_RN_TM2_3: (static_cast(busPtr))->Show(); break;
#ifndef CONFIG_IDF_TARGET_ESP32C3
case I_32_I0_TM1_4: (static_cast(busPtr))->Show(); break;
+ case I_32_I0_TM2_3: (static_cast(busPtr))->Show(); break;
#endif
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
case I_32_I1_TM1_4: (static_cast(busPtr))->Show(); break;
+ case I_32_I1_TM2_3: (static_cast(busPtr))->Show(); break;
#endif
#endif
case I_HS_DOT_3: (static_cast(busPtr))->Show(); break;
case I_SS_DOT_3: (static_cast(busPtr))->Show(); break;
case I_HS_LPD_3: (static_cast(busPtr))->Show(); break;
case I_SS_LPD_3: (static_cast(busPtr))->Show(); break;
+ case I_HS_LPO_3: (static_cast(busPtr))->Show(); break;
+ case I_SS_LPO_3: (static_cast(busPtr))->Show(); break;
case I_HS_WS1_3: (static_cast(busPtr))->Show(); break;
case I_SS_WS1_3: (static_cast(busPtr))->Show(); break;
case I_HS_P98_3: (static_cast(busPtr))->Show(); break;
@@ -385,6 +445,10 @@ class PolyBus {
case I_8266_U1_TM1_4: return (static_cast(busPtr))->CanShow(); break;
case I_8266_DM_TM1_4: return (static_cast(busPtr))->CanShow(); break;
case I_8266_BB_TM1_4: return (static_cast(busPtr))->CanShow(); break;
+ case I_8266_U0_TM2_3: return (static_cast(busPtr))->CanShow(); break;
+ case I_8266_U1_TM2_3: return (static_cast(busPtr))->CanShow(); break;
+ case I_8266_DM_TM2_3: return (static_cast(busPtr))->CanShow(); break;
+ case I_8266_BB_TM2_3: return (static_cast(busPtr))->CanShow(); break;
#endif
#ifdef ARDUINO_ARCH_ESP32
case I_32_RN_NEO_3: return (static_cast(busPtr))->CanShow(); break;
@@ -409,17 +473,22 @@ class PolyBus {
case I_32_I1_400_3: return (static_cast(busPtr))->CanShow(); break;
#endif
case I_32_RN_TM1_4: return (static_cast(busPtr))->CanShow(); break;
+ case I_32_RN_TM2_3: return (static_cast(busPtr))->CanShow(); break;
#ifndef CONFIG_IDF_TARGET_ESP32C3
case I_32_I0_TM1_4: return (static_cast(busPtr))->CanShow(); break;
+ case I_32_I0_TM2_3: return (static_cast(busPtr))->CanShow(); break;
#endif
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
case I_32_I1_TM1_4: return (static_cast(busPtr))->CanShow(); break;
+ case I_32_I1_TM2_3: return (static_cast(busPtr))->CanShow(); break;
#endif
#endif
case I_HS_DOT_3: return (static_cast(busPtr))->CanShow(); break;
case I_SS_DOT_3: return (static_cast(busPtr))->CanShow(); break;
case I_HS_LPD_3: return (static_cast(busPtr))->CanShow(); break;
case I_SS_LPD_3: return (static_cast(busPtr))->CanShow(); break;
+ case I_HS_LPO_3: return (static_cast(busPtr))->CanShow(); break;
+ case I_SS_LPO_3: return (static_cast(busPtr))->CanShow(); break;
case I_HS_WS1_3: return (static_cast(busPtr))->CanShow(); break;
case I_SS_WS1_3: return (static_cast(busPtr))->CanShow(); break;
case I_HS_P98_3: return (static_cast(busPtr))->CanShow(); break;
@@ -470,6 +539,10 @@ class PolyBus {
case I_8266_U1_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break;
case I_8266_DM_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break;
case I_8266_BB_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break;
+ case I_8266_U0_TM2_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
+ case I_8266_U1_TM2_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
+ case I_8266_DM_TM2_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
+ case I_8266_BB_TM2_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
#endif
#ifdef ARDUINO_ARCH_ESP32
case I_32_RN_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
@@ -494,17 +567,22 @@ class PolyBus {
case I_32_I1_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
#endif
case I_32_RN_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break;
+ case I_32_RN_TM2_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
#ifndef CONFIG_IDF_TARGET_ESP32C3
case I_32_I0_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break;
+ case I_32_I0_TM2_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
#endif
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
case I_32_I1_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break;
+ case I_32_I1_TM2_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
#endif
#endif
case I_HS_DOT_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
case I_SS_DOT_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
case I_HS_LPD_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
case I_SS_LPD_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
+ case I_HS_LPO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
+ case I_SS_LPO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
case I_HS_WS1_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
case I_SS_WS1_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
case I_HS_P98_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
@@ -531,6 +609,10 @@ class PolyBus {
case I_8266_U1_TM1_4: (static_cast(busPtr))->SetBrightness(b); break;
case I_8266_DM_TM1_4: (static_cast(busPtr))->SetBrightness(b); break;
case I_8266_BB_TM1_4: (static_cast(busPtr))->SetBrightness(b); break;
+ case I_8266_U0_TM2_3: (static_cast(busPtr))->SetBrightness(b); break;
+ case I_8266_U1_TM2_3: (static_cast(busPtr))->SetBrightness(b); break;
+ case I_8266_DM_TM2_3: (static_cast(busPtr))->SetBrightness(b); break;
+ case I_8266_BB_TM2_3: (static_cast(busPtr))->SetBrightness(b); break;
#endif
#ifdef ARDUINO_ARCH_ESP32
case I_32_RN_NEO_3: (static_cast(busPtr))->SetBrightness(b); break;
@@ -555,17 +637,22 @@ class PolyBus {
case I_32_I1_400_3: (static_cast(busPtr))->SetBrightness(b); break;
#endif
case I_32_RN_TM1_4: (static_cast(busPtr))->SetBrightness(b); break;
+ case I_32_RN_TM2_3: (static_cast(busPtr))->SetBrightness(b); break;
#ifndef CONFIG_IDF_TARGET_ESP32C3
case I_32_I0_TM1_4: (static_cast(busPtr))->SetBrightness(b); break;
+ case I_32_I0_TM2_3: (static_cast(busPtr))->SetBrightness(b); break;
#endif
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
case I_32_I1_TM1_4: (static_cast(busPtr))->SetBrightness(b); break;
+ case I_32_I1_TM2_3: (static_cast(busPtr))->SetBrightness(b); break;
#endif
#endif
case I_HS_DOT_3: (static_cast(busPtr))->SetBrightness(b); break;
case I_SS_DOT_3: (static_cast(busPtr))->SetBrightness(b); break;
case I_HS_LPD_3: (static_cast(busPtr))->SetBrightness(b); break;
case I_SS_LPD_3: (static_cast(busPtr))->SetBrightness(b); break;
+ case I_HS_LPO_3: (static_cast(busPtr))->SetBrightness(b); break;
+ case I_SS_LPO_3: (static_cast(busPtr))->SetBrightness(b); break;
case I_HS_WS1_3: (static_cast(busPtr))->SetBrightness(b); break;
case I_SS_WS1_3: (static_cast(busPtr))->SetBrightness(b); break;
case I_HS_P98_3: (static_cast(busPtr))->SetBrightness(b); break;
@@ -593,6 +680,10 @@ class PolyBus {
case I_8266_U1_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break;
case I_8266_DM_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break;
case I_8266_BB_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break;
+ case I_8266_U0_TM2_3: col = (static_cast(busPtr))->GetPixelColor(pix); break;
+ case I_8266_U1_TM2_3: col = (static_cast(busPtr))->GetPixelColor(pix); break;
+ case I_8266_DM_TM2_3: col = (static_cast(busPtr))->GetPixelColor(pix); break;
+ case I_8266_BB_TM2_3: col = (static_cast(busPtr))->GetPixelColor(pix); break;
#endif
#ifdef ARDUINO_ARCH_ESP32
case I_32_RN_NEO_3: col = (static_cast(busPtr))->GetPixelColor(pix); break;
@@ -617,17 +708,22 @@ class PolyBus {
case I_32_I1_400_3: col = (static_cast(busPtr))->GetPixelColor(pix); break;
#endif
case I_32_RN_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break;
+ case I_32_RN_TM2_3: col = (static_cast(busPtr))->GetPixelColor(pix); break;
#ifndef CONFIG_IDF_TARGET_ESP32C3
case I_32_I0_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break;
+ case I_32_I0_TM2_3: col = (static_cast(busPtr))->GetPixelColor(pix); break;
#endif
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
case I_32_I1_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break;
+ case I_32_I1_TM2_3: col = (static_cast(busPtr))->GetPixelColor(pix); break;
#endif
#endif
case I_HS_DOT_3: col = (static_cast(busPtr))->GetPixelColor(pix); break;
case I_SS_DOT_3: col = (static_cast(busPtr))->GetPixelColor(pix); break;
case I_HS_LPD_3: col = (static_cast(busPtr))->GetPixelColor(pix); break;
case I_SS_LPD_3: col = (static_cast(busPtr))->GetPixelColor(pix); break;
+ case I_HS_LPO_3: col = (static_cast(busPtr))->GetPixelColor(pix); break;
+ case I_SS_LPO_3: col = (static_cast(busPtr))->GetPixelColor(pix); break;
case I_HS_WS1_3: col = (static_cast(busPtr))->GetPixelColor(pix); break;
case I_SS_WS1_3: col = (static_cast(busPtr))->GetPixelColor(pix); break;
case I_HS_P98_3: col = (static_cast(busPtr))->GetPixelColor(pix); break;
@@ -674,6 +770,10 @@ class PolyBus {
case I_8266_U1_TM1_4: delete (static_cast(busPtr)); break;
case I_8266_DM_TM1_4: delete (static_cast(busPtr)); break;
case I_8266_BB_TM1_4: delete (static_cast(busPtr)); break;
+ case I_8266_U0_TM2_3: delete (static_cast(busPtr)); break;
+ case I_8266_U1_TM2_3: delete (static_cast(busPtr)); break;
+ case I_8266_DM_TM2_3: delete (static_cast(busPtr)); break;
+ case I_8266_BB_TM2_3: delete (static_cast(busPtr)); break;
#endif
#ifdef ARDUINO_ARCH_ESP32
case I_32_RN_NEO_3: delete (static_cast(busPtr)); break;
@@ -698,17 +798,22 @@ class PolyBus {
case I_32_I1_400_3: delete (static_cast(busPtr)); break;
#endif
case I_32_RN_TM1_4: delete (static_cast(busPtr)); break;
+ case I_32_RN_TM2_3: delete (static_cast(busPtr)); break;
#ifndef CONFIG_IDF_TARGET_ESP32C3
case I_32_I0_TM1_4: delete (static_cast(busPtr)); break;
+ case I_32_I0_TM2_3: delete (static_cast(busPtr)); break;
#endif
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
case I_32_I1_TM1_4: delete (static_cast(busPtr)); break;
+ case I_32_I1_TM2_3: delete (static_cast(busPtr)); break;
#endif
#endif
case I_HS_DOT_3: delete (static_cast(busPtr)); break;
case I_SS_DOT_3: delete (static_cast(busPtr)); break;
case I_HS_LPD_3: delete (static_cast(busPtr)); break;
case I_SS_LPD_3: delete (static_cast(busPtr)); break;
+ case I_HS_LPO_3: delete (static_cast(busPtr)); break;
+ case I_SS_LPO_3: delete (static_cast(busPtr)); break;
case I_HS_WS1_3: delete (static_cast(busPtr)); break;
case I_SS_WS1_3: delete (static_cast(busPtr)); break;
case I_HS_P98_3: delete (static_cast(busPtr)); break;
@@ -733,6 +838,7 @@ class PolyBus {
switch (busType) {
case TYPE_APA102: t = I_SS_DOT_3; break;
case TYPE_LPD8806: t = I_SS_LPD_3; break;
+ case TYPE_LPD6803: t = I_SS_LPO_3; break;
case TYPE_WS2801: t = I_SS_WS1_3; break;
case TYPE_P9813: t = I_SS_P98_3; break;
default: t=I_NONE;
@@ -753,6 +859,8 @@ class PolyBus {
return I_8266_U0_400_3 + offset;
case TYPE_TM1814:
return I_8266_U0_TM1_4 + offset;
+ case TYPE_TM1829:
+ return I_8266_U0_TM2_3 + offset;
}
#else //ESP32
uint8_t offset = 0; //0 = RMT (num 0-7) 8 = I2S0 9 = I2S1
@@ -773,6 +881,8 @@ class PolyBus {
return I_32_RN_400_3 + offset;
case TYPE_TM1814:
return I_32_RN_TM1_4 + offset;
+ case TYPE_TM1829:
+ return I_32_RN_TM2_3 + offset;
}
#endif
}
diff --git a/wled00/button.cpp b/wled00/button.cpp
index b472f927..81e3c8c3 100644
--- a/wled00/button.cpp
+++ b/wled00/button.cpp
@@ -197,10 +197,10 @@ void handleAnalog(uint8_t b)
// otherwise use "double press" for segment selection
Segment& seg = strip.getSegment(macroDoublePress[b]);
if (aRead == 0) {
- seg.setOption(SEG_OPTION_ON, 0); // off
+ seg.on = false; // off
} else {
seg.setOpacity(aRead);
- seg.setOption(SEG_OPTION_ON, 1);
+ seg.on = true;
}
// this will notify clients of update (websockets,mqtt,etc)
updateInterfaces(CALL_MODE_BUTTON);
diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp
index f5528a43..6ee4a191 100644
--- a/wled00/cfg.cpp
+++ b/wled00/cfg.cpp
@@ -283,18 +283,12 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
JsonArray hw_if_spi = hw[F("if")][F("spi-pin")];
CJSON(spi_mosi, hw_if_spi[0]);
CJSON(spi_sclk, hw_if_spi[1]);
- CJSON(spi_cs, hw_if_spi[2]);
- PinManagerPinType spi[3] = { { spi_mosi, true }, { spi_sclk, true }, { spi_cs, true } };
- if (spi_mosi >= 0 && spi_sclk >= 0 && spi_cs >= 0 && pinManager.allocateMultiplePins(spi, 3, PinOwner::HW_SPI)) {
- #ifdef ESP8266
- SPI.begin();
- #else
- SPI.begin(spi_sclk, (int8_t)-1, spi_mosi, spi_cs);
- #endif
+ PinManagerPinType spi[3] = { { spi_mosi, true }, { spi_sclk, true } };
+ if (spi_mosi >= 0 && spi_sclk >= 0 && pinManager.allocateMultiplePins(spi, 2, PinOwner::HW_SPI)) {
+ // do not initialise bus here
} else {
spi_mosi = -1;
spi_sclk = -1;
- spi_cs = -1;
}
//int hw_status_pin = hw[F("status")]["pin"]; // -1
@@ -752,7 +746,6 @@ void serializeConfig() {
JsonArray hw_if_spi = hw_if.createNestedArray("spi-pin");
hw_if_spi.add(spi_mosi);
hw_if_spi.add(spi_sclk);
- hw_if_spi.add(spi_cs);
//JsonObject hw_status = hw.createNestedObject("status");
//hw_status["pin"] = -1;
diff --git a/wled00/const.h b/wled00/const.h
index 7a62a38d..d3953cd8 100644
--- a/wled00/const.h
+++ b/wled00/const.h
@@ -154,6 +154,7 @@
#define TYPE_WS2812_RGB 22
#define TYPE_GS8608 23 //same driver as WS2812, but will require signal 2x per second (else displays test pattern)
#define TYPE_WS2811_400KHZ 24 //half-speed WS2812 protocol, used by very old WS2811 units
+#define TYPE_TM1829 25
#define TYPE_SK6812_RGBW 30
#define TYPE_TM1814 31
//"Analog" types (PWM) (32-47)
@@ -168,6 +169,7 @@
#define TYPE_APA102 51
#define TYPE_LPD8806 52
#define TYPE_P9813 53
+#define TYPE_LPD6803 54
//Network types (master broadcast) (80-95)
#define TYPE_NET_DDP_RGB 80 //network DDP RGB bus (master broadcast bus)
#define TYPE_NET_E131_RGB 81 //network E131 RGB bus (master broadcast bus)
@@ -385,6 +387,7 @@
#if defined(ESP8266) && defined(HW_PIN_CSSPI)
#undef HW_PIN_CSSPI
#endif
+// defaults for VSPI
#ifndef HW_PIN_CLOCKSPI
#define HW_PIN_CLOCKSPI SCK
#endif
diff --git a/wled00/data/settings_leds.htm b/wled00/data/settings_leds.htm
index c531fb16..3a6c3901 100644
--- a/wled00/data/settings_leds.htm
+++ b/wled00/data/settings_leds.htm
@@ -176,7 +176,7 @@
gId("rf"+n).checked = (gId("rf"+n).checked || t == 31); // LEDs require data in off state
if (t > 31 && t < 48) d.getElementsByName("LC"+n)[0].value = 1; // for sanity change analog count just to 1 LED
}
- gId("rf"+n).onclick = (t == 31) ? (function(){return false}) : (function(){}); // prevent change for TM1814
+ gId("rf"+n).onclick = (t == 31) ? (()=>{return false}) : (()=>{}); // prevent change for TM1814
isRGBW |= (t == 30 || t == 31 || (t > 40 && t < 46 && t != 43)); // RGBW checkbox, TYPE_xxxx values from const.h
gId("co"+n).style.display = ((t >= 80 && t < 96) || (t >= 40 && t < 48)) ? "none":"inline"; // hide color order for PWM
gId("dig"+n+"w").style.display = (t == 30 || t == 31) ? "inline":"none"; // show swap channels dropdown
@@ -316,9 +316,11 @@ ${i+1}:
+
+
@@ -351,7 +353,7 @@ ${i+1}: