Skip to content

Commit e54963e

Browse files
committed
Layers start with one, Art-net In tweaks
Installer: add Dig2Go Back-end ======== - Lights control: store nrOfPalettes - (virtual) Layers starting with 1 - Info: add layer number - Artnet in: layer start with 1, include universe - Infrared: use nrOfPalettes
1 parent 87f2be7 commit e54963e

File tree

7 files changed

+28
-20
lines changed

7 files changed

+28
-20
lines changed

docs/gettingstarted/installer.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ MoonLight v0.6.0, 7 November 2025
1212

1313
| Name | Image* | Flash | Shop & Board presets |
1414
|------|--------|-------|----------------------|
15-
| esp32-d0 | ![esp32-d0](../firmware/installer/images/esp32-d0.jpg){: style="width:100px"} | <esp-web-install-button manifest="https://moonmodules.org/MoonLight/firmware/installer/manifest_esp32-d0.json"></esp-web-install-button> | [Dig Uno](https://quinled.info/pre-assembled-quinled-dig-uno/):<br>![Dig Uno](https://quinled.info/wp-content/uploads/2020/02/QuinLED-Dig-Uno-v3_front.png){: style="width:100px"}<br>[Dig Quad](https://quinled.info/pre-assembled-quinled-dig-quad/):<br>![Dig Quad](https://quinled.info/wp-content/uploads/2021/11/QuinLED-Dig-Quad-AB_v3r1-2048x1154.png){: style="width:100px"} |
15+
| esp32-d0 | ![esp32-d0](../firmware/installer/images/esp32-d0.jpg){: style="width:100px"} | <esp-web-install-button manifest="https://moonmodules.org/MoonLight/firmware/installer/manifest_esp32-d0.json"></esp-web-install-button> | [Dig Uno](https://quinled.info/pre-assembled-quinled-dig-uno/):<br>![Dig Uno](https://quinled.info/wp-content/uploads/2020/02/QuinLED-Dig-Uno-v3_front.png){: style="width:100px"}<br>[Dig Quad](https://quinled.info/pre-assembled-quinled-dig-quad/):<br>![Dig Quad](https://quinled.info/wp-content/uploads/2021/11/QuinLED-Dig-Quad-AB_v3r1-2048x1154.png){: style="width:100px"}<br>[Dig2Go](https://quinled.info/quinled-dig2go/):<br>![Dig2Go](https://shop.allnetchina.cn/cdn/shop/products/Led_4.jpg?v=1680836018&width=1600){: style="width:100px"} |
1616
| esp32-d0-16mb | ![esp32-d0-16mb](../firmware/installer/images/esp32-d0-16mb.jpg){: style="width:100px"} | <esp-web-install-button manifest="https://moonmodules.org/MoonLight/firmware/installer/manifest_esp32-d0-16mb.json"></esp-web-install-button> | [Dig Octa](https://quinled.info/quinled-dig-octa/):<br>![Dig Octa](https://quinled.info/wp-content/uploads/2024/10/20240924_141857-2048x1444.png){: style="width:100px"}<br>[Serg ESP32](https://www.tindie.com/products/serg74/esp32-wroom-usb-c-d1-mini32-form-factor-board/){:target="_blank"} and [Shield](https://www.tindie.com/products/serg74/wled-shield-board-for-addressable-leds/)<br>![Shield](https://cdn.tindiemedia.com/images/resize/44YE-eNQ9pJQUh_SmtwwfBXFbAE=/p/fit-in/1370x912/filters:fill(fff)/i/93057/products/2021-08-14T14%3A44%3A14.418Z-shield_v3-1.jpg?1628927139){: style="width:100px"} |
1717
| esp32-s3-devkitc-1-n8r8v | ![esp32-s3-devkitc-1-n8r8v](../firmware/installer/images/esp32-s3-devkitc-1-n8r8v.jpg){: style="width:100px"} | <esp-web-install-button manifest="https://moonmodules.org/MoonLight/firmware/installer/manifest_esp32-s3-devkitc-1-n8r8v.json"></esp-web-install-button> | SE-16p<br>![SE-16p](../firmware/installer/images/esp32-s3-stephanelec-16p.jpg){: style="width:100px"} |
1818
| esp32-s3-devkitc-1-n16r8v | ![esp32-s3-devkitc-1-n16r8v](../firmware/installer/images/esp32-s3-devkitc-1-n8r8v.jpg){: style="width:100px"} | <esp-web-install-button manifest="https://moonmodules.org/MoonLight/firmware/installer/manifest_esp32-s3-devkitc-1-n16r8v.json"></esp-web-install-button> | [Ali*](https://s.click.aliexpress.com/e/_DBAtJ2H){:target="_blank"} |

src/MoonLight/Modules/ModuleChannels.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class ModuleChannels : public Module {
2929
control = addControl(controls, "view", "select");
3030
control["default"] = 0;
3131
addControlValue(control, "Physical layer");
32-
uint8_t i = 0;
32+
uint8_t i = 1; //start with 1
3333
for (VirtualLayer* layer : layerP.layers) {
3434
Char<32> layerName;
3535
layerName.format("Layer %d", i);

src/MoonLight/Modules/ModuleEffects.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ class ModuleEffects : public NodeManager {
6060
EXT_LOGV(ML_TAG, "");
6161
JsonObject control; // state.data has one or more properties
6262
control = addControl(controls, "layer", "select");
63-
control["default"] = 0;
64-
uint8_t i = 0;
63+
control["default"] = 1;
64+
uint8_t i = 1; //start with 1
6565
for (VirtualLayer* layer : layerP.layers) {
6666
addControlValue(control, i);
6767
i++;

src/MoonLight/Modules/ModuleLightsControl.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ class ModuleLightsControl : public Module {
7979
pinRelayLightsOn = pinObject["GPIO"];
8080
pinMode(pinRelayLightsOn, OUTPUT);
8181
uint8_t newBri = _state.data["lightsOn"] ? _state.data["brightness"] : 0;
82-
digitalWrite(pinRelayLightsOn, newBri>0?HIGH:LOW);
82+
digitalWrite(pinRelayLightsOn, newBri > 0 ? HIGH : LOW);
8383
EXT_LOGD(ML_TAG, "pinRelayLightsOn found %d", pinRelayLightsOn);
8484
} else if (usage == pin_Button_LightsOn) {
8585
pinButtonLightsOn = pinObject["GPIO"];
@@ -91,6 +91,7 @@ class ModuleLightsControl : public Module {
9191
});
9292
}
9393

94+
uint8_t nrOfPalettes = 0;
9495
// define the data model
9596
void setupDefinition(const JsonArray& controls) override {
9697
EXT_LOGV(ML_TAG, "");
@@ -122,6 +123,7 @@ class ModuleLightsControl : public Module {
122123
addControlValue(control, "Random");
123124
addControlValue(control, "Quin");
124125
addControlValue(control, "Orange");
126+
nrOfPalettes = control["values"].as<JsonArray>().size();
125127

126128
control = addControl(controls, "preset", "pad");
127129
control["width"] = 8;
@@ -156,7 +158,7 @@ class ModuleLightsControl : public Module {
156158
uint8_t newBri = _state.data["lightsOn"] ? _state.data["brightness"] : 0;
157159
if (!!layerP.lights.header.brightness != !!newBri && pinRelayLightsOn != UINT8_MAX) {
158160
EXT_LOGD(ML_TAG, "pinRelayLightsOn %s", !!newBri ? "On" : "Off");
159-
digitalWrite(pinRelayLightsOn, newBri>0?HIGH:LOW);
161+
digitalWrite(pinRelayLightsOn, newBri > 0 ? HIGH : LOW);
160162
};
161163
layerP.lights.header.brightness = newBri;
162164
} else if (updatedItem.name == "palette") {

src/MoonLight/Modules/ModuleMoonLightInfo.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class ModuleMoonLightInfo : public Module {
2222
void setupDefinition(const JsonArray& controls) override {
2323
EXT_LOGV(ML_TAG, "");
2424
JsonObject control; // state.data has one or more properties
25-
JsonArray rows; // if a control is an array, this is the rows of the array
25+
JsonArray rows; // if a control is an array, this is the rows of the array
2626

2727
addControl(controls, "nrOfLights", "number", 0, 65535, true);
2828
addControl(controls, "channelsPerLight", "number", 0, 65535, true);
@@ -34,6 +34,7 @@ class ModuleMoonLightInfo : public Module {
3434
control["crud"] = "r";
3535
rows = control["n"].to<JsonArray>();
3636
{
37+
addControl(rows, "layer", "number", 0, 255, true);
3738
addControl(rows, "nrOfLights", "number", 0, 65535, true);
3839
addControl(rows, "size", "coord3D", 0, UINT16_MAX, true);
3940
addControl(rows, "mappingTable#", "number", 0, 65535, true);
@@ -80,6 +81,7 @@ class ModuleMoonLightInfo : public Module {
8081
}
8182
}
8283

84+
data["layers"][index]["layer"] = index + 1; // start with one
8385
data["layers"][index]["nrOfLights"] = layer->nrOfLights;
8486
data["layers"][index]["size"]["x"] = layer->size.x;
8587
data["layers"][index]["size"]["y"] = layer->size.y;

src/MoonLight/Nodes/Drivers/D_ArtnetIn.h

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ class ArtNetInDriver : public Node {
2727
uint8_t packetBuffer[1500];
2828

2929
bool ddp = false;
30-
uint8_t view = 0;
30+
uint8_t view = 0; // physical layer
3131
uint16_t port = 6454;
3232

3333
void setup() override {
3434
addControl(ddp, "DDP", "checkbox");
3535
addControl(port, "port", "number", 0, 65538);
3636
addControl(view, "view", "select");
3737
addControlValue("Physical layer");
38-
uint8_t i = 0;
38+
uint8_t i = 1; // start with one
3939
for (VirtualLayer* layer : layerP.layers) {
4040
Char<32> layerName;
4141
layerName.format("Layer %d", i);
@@ -95,8 +95,6 @@ class ArtNetInDriver : public Node {
9595
};
9696

9797
void handleArtNet() {
98-
// LightsHeader* header = &layerP.lights.header;
99-
10098
int packetSize = artnetUdp.parsePacket();
10199

102100
if (packetSize >= sizeof(ArtNetHeader)) {
@@ -107,7 +105,7 @@ class ArtNetInDriver : public Node {
107105
ArtNetHeader* header = (ArtNetHeader*)packetBuffer;
108106
uint16_t opcode = header->opcode;
109107
//
110-
// EXT_LOGD(ML_TAG, "%d", header->universe);
108+
EXT_LOGD(ML_TAG, "size:%d universe:%d", packetSize, header->universe);
111109

112110
// Check if it's a DMX packet (opcode 0x5000)
113111
if (opcode == 0x5000) {
@@ -120,10 +118,17 @@ class ArtNetInDriver : public Node {
120118
uint8_t* dmxData = packetBuffer + sizeof(ArtNetHeader);
121119

122120
// Map DMX channels to LEDs (3 channels per LED: RGB)
123-
int numPixels = min((uint16_t)(dataLength / layerP.lights.header.channelsPerLight), (uint16_t)(layerP.lights.header.nrOfLights));
121+
// Calculate starting LED position based on universe
122+
// Each Art-Net universe supports up to 512 DMX channels
123+
int startPixel = universe * (512 / layerP.lights.header.channelsPerLight);
124+
int numPixels = min((uint16_t)(dataLength / layerP.lights.header.channelsPerLight), (uint16_t)(layerP.lights.header.nrOfLights - startPixel));
124125

126+
// Write to the correct offset
125127
for (int i = 0; i < numPixels; i++) {
126-
memcpy(&layerP.lights.channels[i * layerP.lights.header.channelsPerLight], &dmxData[i * layerP.lights.header.channelsPerLight], layerP.lights.header.channelsPerLight);
128+
int ledIndex = startPixel + i;
129+
if (ledIndex < layerP.lights.header.nrOfLights) {
130+
memcpy(&layerP.lights.channels[ledIndex * layerP.lights.header.channelsPerLight], &dmxData[i * layerP.lights.header.channelsPerLight], layerP.lights.header.channelsPerLight);
131+
}
127132
}
128133

129134
// FastLED.show();
@@ -177,5 +182,3 @@ class ArtNetInDriver : public Node {
177182
};
178183

179184
#endif
180-
181-
// #include <WiFi.h>

src/MoonLight/Nodes/Drivers/D_Infrared.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -350,12 +350,13 @@ class IRDriver : public Node {
350350

351351
// do not process longpress
352352
if (nec_repeat == false) {
353+
ModuleLightsControl* lc = (ModuleLightsControl*)moduleControl;
353354
if (combined_code == codeOff || combined_code == codeOn) { // Lights on/off
354355
newState["lightsOn"] = state.data["lightsOn"].as<bool>() ? false : true;
355-
} else if (combined_code == codePaletteInc) { // palette increase
356-
newState["palette"] = min(state.data["palette"].as<uint8_t>() + 1, 10); // to do: replace 8 with max palette count
357-
} else if (combined_code == codePaletteDec) { // palette decrease
358-
newState["palette"] = max(state.data["palette"].as<uint8_t>() - 1, 0);
356+
} else if (combined_code == codePaletteInc) { // palette increase
357+
newState["palette"] = MIN(state.data["palette"].as<uint8_t>() + 1, lc->nrOfPalettes); // to do: replace 8 with max palette count
358+
} else if (combined_code == codePaletteDec) { // palette decrease
359+
newState["palette"] = MAX(state.data["palette"].as<uint8_t>() - 1, 0);
359360
} else if (combined_code == codePresetDec) { // next button - go to previous preset
360361
newState["preset"] = state.data["preset"];
361362
newState["preset"]["action"] = "click";

0 commit comments

Comments
 (0)