From 7924c648086099dadce795e111edc4b0aa10fe90 Mon Sep 17 00:00:00 2001 From: limpkin Date: Wed, 31 Dec 2025 08:42:38 +0100 Subject: [PATCH 1/3] support for ws2814 led strips, white channel first --- src/MoonBase/Nodes.cpp | 8 ++++++++ src/MoonBase/Nodes.h | 1 + src/MoonLight/Layers/VirtualLayer.h | 5 +++-- src/MoonLight/Nodes/Drivers/D_ParallelLEDDriver.h | 8 ++++---- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/MoonBase/Nodes.cpp b/src/MoonBase/Nodes.cpp index befc4d5d..1c848b27 100644 --- a/src/MoonBase/Nodes.cpp +++ b/src/MoonBase/Nodes.cpp @@ -353,6 +353,7 @@ void DriverNode::setup() { addControlValue("BGR"); addControlValue("RGBW"); // e.g. 4 channel par/dmx light addControlValue("GRBW"); // rgbw LED eg. sk6812 + addControlValue("WRGB"); // rgbw ws2814 LEDs addControlValue("Curtain GRB6"); // some LED curtains addControlValue("Curtain RGB2040"); // curtain RGB2040 addControlValue("Lightbar RGBWYP"); // 6 channel par/dmx light with UV etc @@ -458,6 +459,13 @@ void DriverNode::onUpdate(const Char<20>& oldValue, const JsonObject& control) { header->offsetBlue = 2; header->offsetWhite = 3; break; + case lightPreset_WRGB: + header->channelsPerLight = 4; + header->offsetRed = 1; + header->offsetGreen = 2; + header->offsetBlue = 3; + header->offsetWhite = 0; + break; case lightPreset_GRB6: header->channelsPerLight = 6; header->offsetRed = 1; diff --git a/src/MoonBase/Nodes.h b/src/MoonBase/Nodes.h index 3b4c9c5e..9b2a27c1 100644 --- a/src/MoonBase/Nodes.h +++ b/src/MoonBase/Nodes.h @@ -27,6 +27,7 @@ enum LightPresetsEnum { lightPreset_BGR, lightPreset_RGBW, // e.g. 4 channel par/dmx light lightPreset_GRBW, // rgbw LED eg. sk6812 + lightPreset_WRGB, // rgbw ws2814 LEDs lightPreset_GRB6, // some LED curtains lightPreset_RGB2040, // curtain 2040 lightPreset_RGBWYP, // 6 channel par/dmx light with UV etc diff --git a/src/MoonLight/Layers/VirtualLayer.h b/src/MoonLight/Layers/VirtualLayer.h index d3f6455e..11438a73 100644 --- a/src/MoonLight/Layers/VirtualLayer.h +++ b/src/MoonLight/Layers/VirtualLayer.h @@ -98,7 +98,7 @@ class VirtualLayer { uint16_t XYZUnModified(const Coord3D& position) const { return position.x + position.y * size.x + position.z * size.x * size.y; } void setRGB(const uint16_t indexV, CRGB color) { - if (layerP->lights.header.offsetWhite != UINT8_MAX && layerP->lights.header.offsetWhite == layerP->lights.header.offsetRGB + 3) { // W set and after RGB + if (layerP->lights.header.offsetWhite != UINT8_MAX) { // W set // using the simple algorithm of taking the minimum of RGB as white channel, this is good enough and fastest algorithm - we need speed 🔥 uint8_t rgbw[4]; rgbw[3] = MIN(MIN(color.r, color.g), color.b); @@ -112,7 +112,8 @@ class VirtualLayer { void setRGB(Coord3D pos, CRGB color) { setRGB(XYZ(pos), color); } void setWhite(const uint16_t indexV, const uint8_t value) { - if (layerP->lights.header.offsetWhite != UINT8_MAX) setLight(indexV, &value, layerP->lights.header.offsetWhite, sizeof(value)); + if (layerP->lights.header.offsetWhite == 0 && layerP->lights.header.channelsPerLight == 4) setLight(indexV, &value, 3, sizeof(value)); + else if (layerP->lights.header.offsetWhite != UINT8_MAX) setLight(indexV, &value, layerP->lights.header.offsetWhite, sizeof(value)); } void setWhite(Coord3D pos, const uint8_t value) { setWhite(XYZ(pos), value); } diff --git a/src/MoonLight/Nodes/Drivers/D_ParallelLEDDriver.h b/src/MoonLight/Nodes/Drivers/D_ParallelLEDDriver.h index ac3027e6..50f373f6 100644 --- a/src/MoonLight/Nodes/Drivers/D_ParallelLEDDriver.h +++ b/src/MoonLight/Nodes/Drivers/D_ParallelLEDDriver.h @@ -121,8 +121,8 @@ class ParallelLEDDriver : public DriverNode { uint8_t savedBrightness = ledsDriver._brightness; //(initLed sets it to 255 and thats not what we want) - EXT_LOGD(ML_TAG, "init Parallel LED Driver %d %d %d %d", layerP.lights.header.channelsPerLight, layerP.lights.header.offsetRed, layerP.lights.header.offsetGreen, layerP.lights.header.offsetBlue); - ledsDriver.initled(layerP.lights.channels, pins, layerP.ledsPerPin, nrOfPins, layerP.lights.header.channelsPerLight, layerP.lights.header.offsetRed, layerP.lights.header.offsetGreen, layerP.lights.header.offsetBlue); + EXT_LOGD(ML_TAG, "init Parallel LED Driver %d %d %d %d %d", layerP.lights.header.channelsPerLight, layerP.lights.header.offsetRed, layerP.lights.header.offsetGreen, layerP.lights.header.offsetBlue, layerP.lights.header.offsetWhite); + ledsDriver.initled(layerP.lights.channels, pins, layerP.ledsPerPin, nrOfPins, layerP.lights.header.channelsPerLight, layerP.lights.header.offsetRed, layerP.lights.header.offsetGreen, layerP.lights.header.offsetBlue, layerP.lights.header.offsetWhite); ledsDriver.setBrightness(savedBrightness); //(initLed sets it to 255 and thats not what we want) @@ -134,8 +134,8 @@ class ParallelLEDDriver : public DriverNode { } else { // don't call initled again as that will crash because if channelsPerLight (nb_components) change, the dma buffers are not big enough - EXT_LOGD(ML_TAG, "update Parallel LED Driver %d %d %d %d", layerP.lights.header.channelsPerLight, layerP.lights.header.offsetRed, layerP.lights.header.offsetGreen, layerP.lights.header.offsetBlue); - ledsDriver.updateDriver(pins, layerP.ledsPerPin, nrOfPins, dmaBuffer, layerP.lights.header.channelsPerLight, layerP.lights.header.offsetRed, layerP.lights.header.offsetGreen, layerP.lights.header.offsetBlue); + EXT_LOGD(ML_TAG, "update Parallel LED Driver %d %d %d %d %d", layerP.lights.header.channelsPerLight, layerP.lights.header.offsetRed, layerP.lights.header.offsetGreen, layerP.lights.header.offsetBlue, layerP.lights.header.offsetWhite); + ledsDriver.updateDriver(pins, layerP.ledsPerPin, nrOfPins, dmaBuffer, layerP.lights.header.channelsPerLight, layerP.lights.header.offsetRed, layerP.lights.header.offsetGreen, layerP.lights.header.offsetBlue, layerP.lights.header.offsetWhite); } #else // P4: Parlio Troy Driver From 117088bd5a1e603f8ad08a105d53c9760df98bc2 Mon Sep 17 00:00:00 2001 From: limpkin Date: Wed, 31 Dec 2025 08:50:52 +0100 Subject: [PATCH 2/3] compilation bug fix --- src/MoonLight/Nodes/Drivers/D_ParallelLEDDriver.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MoonLight/Nodes/Drivers/D_ParallelLEDDriver.h b/src/MoonLight/Nodes/Drivers/D_ParallelLEDDriver.h index bed63a84..6fe625aa 100644 --- a/src/MoonLight/Nodes/Drivers/D_ParallelLEDDriver.h +++ b/src/MoonLight/Nodes/Drivers/D_ParallelLEDDriver.h @@ -118,7 +118,7 @@ class ParallelLEDDriver : public DriverNode { uint8_t savedBrightness = ledsDriver._brightness; //(initLed sets it to 255 and thats not what we want) EXT_LOGD(ML_TAG, "init Parallel LED Driver %d %d %d %d %d", layerP.lights.header.channelsPerLight, layerP.lights.header.offsetRed, layerP.lights.header.offsetGreen, layerP.lights.header.offsetBlue, layerP.lights.header.offsetWhite); - ledsDriver.initled(layerP.lights.channels, pins, layerP.ledsPerPin, nrOfPins, layerP.lights.header.channelsPerLight, layerP.lights.header.offsetRed, layerP.lights.header.offsetGreen, layerP.lights.header.offsetBlue, layerP.lights.header.offsetWhite); + ledsDriver.initled(layerP.lights.channelsD, pins, layerP.ledsPerPin, nrOfPins, layerP.lights.header.channelsPerLight, layerP.lights.header.offsetRed, layerP.lights.header.offsetGreen, layerP.lights.header.offsetBlue, layerP.lights.header.offsetWhite); ledsDriver.setBrightness(savedBrightness); //(initLed sets it to 255 and thats not what we want) From d940ec7fa870414bbf8aadb5c04f28c36cf92e56 Mon Sep 17 00:00:00 2001 From: limpkin Date: Wed, 31 Dec 2025 11:45:16 +0100 Subject: [PATCH 3/3] followign review --- src/MoonLight/Layers/VirtualLayer.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/MoonLight/Layers/VirtualLayer.h b/src/MoonLight/Layers/VirtualLayer.h index 41e0fa26..9670594d 100644 --- a/src/MoonLight/Layers/VirtualLayer.h +++ b/src/MoonLight/Layers/VirtualLayer.h @@ -98,7 +98,7 @@ class VirtualLayer { uint16_t XYZUnModified(const Coord3D& position) const { return position.x + position.y * size.x + position.z * size.x * size.y; } void setRGB(const uint16_t indexV, CRGB color) { - if (layerP->lights.header.offsetWhite != UINT8_MAX) { // W set + if (layerP->lights.header.offsetWhite != UINT8_MAX && layerP->lights.header.channelsPerLight == 4) { // W set // using the simple algorithm of taking the minimum of RGB as white channel, this is good enough and fastest algorithm - we need speed 🔥 uint8_t rgbw[4]; rgbw[3] = MIN(MIN(color.r, color.g), color.b); @@ -112,8 +112,10 @@ class VirtualLayer { void setRGB(Coord3D pos, CRGB color) { setRGB(XYZ(pos), color); } void setWhite(const uint16_t indexV, const uint8_t value) { - if (layerP->lights.header.offsetWhite == 0 && layerP->lights.header.channelsPerLight == 4) setLight(indexV, &value, 3, sizeof(value)); - else if (layerP->lights.header.offsetWhite != UINT8_MAX) setLight(indexV, &value, layerP->lights.header.offsetWhite, sizeof(value)); + if (layerP->lights.header.offsetWhite != UINT8_MAX) { + if (layerP->lights.header.channelsPerLight == 4) setLight(indexV, &value, 3, sizeof(value)); // for rgbw lights + else setLight(indexV, &value, layerP->lights.header.offsetWhite, sizeof(value)); // for moving heads + } } void setWhite(Coord3D pos, const uint8_t value) { setWhite(XYZ(pos), value); }