-
Welcome to WLED!
+
Welcome to SR WLED!
Thank you for installing my application!
Next steps:
Connect the module to your local WiFi here!
diff --git a/wled00/dmx.cpp b/wled00/dmx.cpp
index 2842195472..0bdb4b6463 100644
--- a/wled00/dmx.cpp
+++ b/wled00/dmx.cpp
@@ -1,10 +1,13 @@
#include "wled.h"
/*
- * Support for DMX via MAX485.
- * Change the output pin in src/dependencies/ESPDMX.cpp if needed.
- * Library from:
+ * Support for DMX Output via MAX485.
+ * Change the output pin in src/dependencies/ESPDMX.cpp, if needed (ESP8266)
+ * Change the output pin in src/dependencies/SparkFunDMX.cpp, if needed (ESP32)
+ * ESP8266 Library from:
* https://github.com/Rickgg/ESP-Dmx
+ * ESP32 Library from:
+ * https://github.com/sparkfun/SparkFunDMX
*/
#ifdef WLED_ENABLE_DMX
@@ -14,10 +17,16 @@ void handleDMX()
// don't act, when in DMX Proxy mode
if (e131ProxyUniverse != 0) return;
- // TODO: calculate brightness manually if no shutter channel is set
-
uint8_t brightness = strip.getBrightness();
+ bool calc_brightness = true;
+
+ // check if no shutter channel is set
+ for (byte i = 0; i < DMXChannels; i++)
+ {
+ if (DMXFixtureMap[i] == 5) calc_brightness = false;
+ }
+
uint16_t len = strip.getLengthTotal();
for (int i = DMXStartLED; i < len; i++) { // uses the amount of LEDs as fixture count
@@ -35,16 +44,16 @@ void handleDMX()
dmx.write(DMXAddr, 0);
break;
case 1: // Red
- dmx.write(DMXAddr, r);
+ dmx.write(DMXAddr, calc_brightness ? (r * brightness) / 255 : r);
break;
case 2: // Green
- dmx.write(DMXAddr, g);
+ dmx.write(DMXAddr, calc_brightness ? (g * brightness) / 255 : g);
break;
case 3: // Blue
- dmx.write(DMXAddr, b);
+ dmx.write(DMXAddr, calc_brightness ? (b * brightness) / 255 : b);
break;
case 4: // White
- dmx.write(DMXAddr, w);
+ dmx.write(DMXAddr, calc_brightness ? (w * brightness) / 255 : w);
break;
case 5: // Shutter channel. Controls the brightness.
dmx.write(DMXAddr, brightness);
@@ -60,7 +69,11 @@ void handleDMX()
}
void initDMX() {
+ #ifdef ESP8266
dmx.init(512); // initialize with bus length
+ #else
+ dmx.initWrite(512); // initialize with bus length
+ #endif
}
#else
diff --git a/wled00/e131.cpp b/wled00/e131.cpp
index 6f7f193bdc..07f8c04d3c 100644
--- a/wled00/e131.cpp
+++ b/wled00/e131.cpp
@@ -12,7 +12,7 @@
//handles RGB data only
void handleDDPPacket(e131_packet_t* p) {
int lastPushSeq = e131LastSequenceNumber[0];
-
+
//reject late packets belonging to previous frame (assuming 4 packets max. before push)
if (e131SkipOutOfSequence && lastPushSeq) {
int sn = p->sequenceNum & 0xF;
@@ -33,7 +33,7 @@ void handleDDPPacket(e131_packet_t* p) {
if (p->flags & DDP_TIMECODE_FLAG) c = 4; //packet has timecode flag, we do not support it, but data starts 4 bytes later
realtimeLock(realtimeTimeoutMs, REALTIME_MODE_DDP);
-
+
if (!realtimeOverride) {
for (uint16_t i = start; i < stop; i++) {
setRealtimePixel(i, data[c], data[c+1], data[c+2], 0);
@@ -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);
diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h
index 80894fe970..cef5e9d75a 100644
--- a/wled00/fcn_declare.h
+++ b/wled00/fcn_declare.h
@@ -211,6 +211,7 @@ bool updateVal(const String* req, const char* key, byte* val, byte minv=0, byte
void notify(byte callMode, bool followUp=false);
uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, byte *buffer, uint8_t bri=255, bool isRGBW=false);
void realtimeLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC);
+void exitRealtime();
void handleNotifications();
void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w);
void refreshNodeList();
diff --git a/wled00/html_other.h b/wled00/html_other.h
index 014b1f731c..1bfa0bca54 100644
--- a/wled00/html_other.h
+++ b/wled00/html_other.h
@@ -40,9 +40,9 @@ const char PAGE_update[] PROGMEM = R"=====(
WLED Software Update