diff --git a/wled00/e131.cpp b/wled00/e131.cpp index 6f7f193b..4ac2081c 100644 --- a/wled00/e131.cpp +++ b/wled00/e131.cpp @@ -105,6 +105,13 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, byte protocol){ realtimeIP = clientIP; byte wChannel = 0; uint16_t totalLen = strip.getLengthTotal(); + uint16_t availDMXLen = dmxChannels - DMXAddress + 1; + uint16_t dataOffset = DMXAddress; + + // DMX data in Art-Net packet starts at index 0, for E1.31 at index 1 + if (protocol == P_ARTNET && dataOffset > 0) { + dataOffset--; + } switch (DMXMode) { case DMX_MODE_DISABLED: @@ -113,55 +120,55 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, byte protocol){ case DMX_MODE_SINGLE_RGB: // RGB only if (uni != e131Universe) return; - if (dmxChannels-DMXAddress+1 < 3) return; + if (availDMXLen < 3) return; realtimeLock(realtimeTimeoutMs, mde); if (realtimeOverride) return; - wChannel = (dmxChannels-DMXAddress+1 > 3) ? e131_data[DMXAddress+3] : 0; + wChannel = (availDMXLen > 3) ? e131_data[dataOffset+3] : 0; for (uint16_t i = 0; i < totalLen; i++) - setRealtimePixel(i, e131_data[DMXAddress+0], e131_data[DMXAddress+1], e131_data[DMXAddress+2], wChannel); + setRealtimePixel(i, e131_data[dataOffset+0], e131_data[dataOffset+1], e131_data[dataOffset+2], wChannel); break; case DMX_MODE_SINGLE_DRGB: // Dimmer + RGB if (uni != e131Universe) return; - if (dmxChannels-DMXAddress+1 < 4) return; + if (availDMXLen < 4) return; realtimeLock(realtimeTimeoutMs, mde); if (realtimeOverride) return; - wChannel = (dmxChannels-DMXAddress+1 > 4) ? e131_data[DMXAddress+4] : 0; - if (DMXOldDimmer != e131_data[DMXAddress+0]) { - DMXOldDimmer = e131_data[DMXAddress+0]; - bri = e131_data[DMXAddress+0]; + wChannel = (availDMXLen > 4) ? e131_data[dataOffset+4] : 0; + if (DMXOldDimmer != e131_data[dataOffset+0]) { + DMXOldDimmer = e131_data[dataOffset+0]; + bri = e131_data[dataOffset+0]; strip.setBrightness(bri, true); } for (uint16_t i = 0; i < totalLen; i++) - setRealtimePixel(i, e131_data[DMXAddress+1], e131_data[DMXAddress+2], e131_data[DMXAddress+3], wChannel); + setRealtimePixel(i, e131_data[dataOffset+1], e131_data[dataOffset+2], e131_data[dataOffset+3], wChannel); break; case DMX_MODE_EFFECT: // Length 1: Apply Preset ID, length 11-13: apply effect config if (uni != e131Universe) return; - if (dmxChannels-DMXAddress+1 < 11) { - if (dmxChannels-DMXAddress+1 > 1) return; - applyPreset(e131_data[DMXAddress+0], CALL_MODE_NOTIFICATION); + if (availDMXLen < 11) { + if (availDMXLen > 1) return; + applyPreset(e131_data[dataOffset+0], CALL_MODE_NOTIFICATION); return; } - if (DMXOldDimmer != e131_data[DMXAddress+0]) { - DMXOldDimmer = e131_data[DMXAddress+0]; - bri = e131_data[DMXAddress+0]; + if (DMXOldDimmer != e131_data[dataOffset+0]) { + DMXOldDimmer = e131_data[dataOffset+0]; + bri = e131_data[dataOffset+0]; } - if (e131_data[DMXAddress+1] < MODE_COUNT) - effectCurrent = e131_data[DMXAddress+ 1]; - effectSpeed = e131_data[DMXAddress+ 2]; // flickers - effectIntensity = e131_data[DMXAddress+ 3]; - effectPalette = e131_data[DMXAddress+ 4]; - col[0] = e131_data[DMXAddress+ 5]; - col[1] = e131_data[DMXAddress+ 6]; - col[2] = e131_data[DMXAddress+ 7]; - colSec[0] = e131_data[DMXAddress+ 8]; - colSec[1] = e131_data[DMXAddress+ 9]; - colSec[2] = e131_data[DMXAddress+10]; - if (dmxChannels-DMXAddress+1 > 11) + if (e131_data[dataOffset+1] < MODE_COUNT) + effectCurrent = e131_data[dataOffset+ 1]; + effectSpeed = e131_data[dataOffset+ 2]; // flickers + effectIntensity = e131_data[dataOffset+ 3]; + effectPalette = e131_data[dataOffset+ 4]; + col[0] = e131_data[dataOffset+ 5]; + col[1] = e131_data[dataOffset+ 6]; + col[2] = e131_data[dataOffset+ 7]; + colSec[0] = e131_data[dataOffset+ 8]; + colSec[1] = e131_data[dataOffset+ 9]; + colSec[2] = e131_data[dataOffset+10]; + if (availDMXLen > 11) { - col[3] = e131_data[DMXAddress+11]; //white - colSec[3] = e131_data[DMXAddress+12]; + col[3] = e131_data[dataOffset+11]; //white + colSec[3] = e131_data[dataOffset+12]; } transitionDelayTemp = 0; // act fast colorUpdated(CALL_MODE_NOTIFICATION); // don't send UDP @@ -177,22 +184,26 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, byte protocol){ const uint16_t dmxChannelsPerLed = is4Chan ? 4 : 3; const uint16_t ledsPerUniverse = is4Chan ? MAX_4_CH_LEDS_PER_UNIVERSE : MAX_3_CH_LEDS_PER_UNIVERSE; if (realtimeOverride) return; - uint16_t previousLeds, dmxOffset; + uint16_t previousLeds, dmxOffset, ledsTotal; if (previousUniverses == 0) { - if (dmxChannels-DMXAddress < 1) return; - dmxOffset = DMXAddress; + if (availDMXLen < 1) return; + dmxOffset = dataOffset; previousLeds = 0; // First DMX address is dimmer in DMX_MODE_MULTIPLE_DRGB mode. if (DMXMode == DMX_MODE_MULTIPLE_DRGB) { strip.setBrightness(e131_data[dmxOffset++], true); + ledsTotal = (availDMXLen - 1) / dmxChannelsPerLed; + } else { + ledsTotal = availDMXLen / dmxChannelsPerLed; } } else { // All subsequent universes start at the first channel. dmxOffset = (protocol == P_ARTNET) ? 0 : 1; - uint16_t ledsInFirstUniverse = (MAX_CHANNELS_PER_UNIVERSE - DMXAddress) / dmxChannelsPerLed; + uint16_t dimmerOffset = (DMXMode == DMX_MODE_MULTIPLE_DRGB) ? 1 : 0; + uint16_t ledsInFirstUniverse = ((MAX_CHANNELS_PER_UNIVERSE - DMXAddress + 1) - dimmerOffset) / dmxChannelsPerLed; previousLeds = ledsInFirstUniverse + (previousUniverses - 1) * ledsPerUniverse; + ledsTotal = previousLeds + (dmxChannels / dmxChannelsPerLed); } - uint16_t ledsTotal = previousLeds + (dmxChannels - dmxOffset +1) / dmxChannelsPerLed; if (!is4Chan) { for (uint16_t i = previousLeds; i < ledsTotal; i++) { setRealtimePixel(i, e131_data[dmxOffset], e131_data[dmxOffset+1], e131_data[dmxOffset+2], 0);