diff --git a/wled00/data/settings_sync.htm b/wled00/data/settings_sync.htm
index b4bcf059..5cf4b608 100644
--- a/wled00/data/settings_sync.htm
+++ b/wled00/data/settings_sync.htm
@@ -85,6 +85,7 @@
Realtime
Receive UDP realtime:
E1.31 (sACN)
+ Skip out-of-sequence packets (freeze instead of flicker):
Multicast mode:
E1.31 start universe:
Reboot required. Check out LedFx!
diff --git a/wled00/html_settings.h b/wled00/html_settings.h
index 7340e62d..c7badc16 100644
--- a/wled00/html_settings.h
+++ b/wled00/html_settings.h
@@ -284,6 +284,7 @@ Send notifications twice:
Realtime
Receive UDP realtime:
E1.31 (sACN)
+Skip out-of-sequence packets (freeze instead of flicker):
Use E1.31 multicast:
E1.31 start universe:
Reboot required. Check out LedFx!
diff --git a/wled00/wled00.ino b/wled00/wled00.ino
index 325cc73e..a6b16924 100644
--- a/wled00/wled00.ino
+++ b/wled00/wled00.ino
@@ -206,12 +206,14 @@ bool receiveDirect = true; //receive UDP realtime
bool arlsDisableGammaCorrection = true; //activate if gamma correction is handled by the source
bool arlsForceMaxBri = false; //enable to force max brightness if source has very dark colors that would be black
+#define E131_MAX_UNIVERSE_COUNT 9
uint16_t e131Universe = 1; //settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes)
uint8_t DMXMode = DMX_MODE_MULTIPLE_RGB; //DMX mode (s.a.)
uint16_t DMXAddress = 1; //DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol]
uint8_t DMXOldDimmer = 0; //only update brightness on change
-uint8_t e131LastSequenceNumber = 0; //to detect packet loss
+uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; //to detect packet loss
bool e131Multicast = false; //multicast or unicast
+bool e131SkipOutOfSequence = false; //freeze instead of flickering
bool mqttEnabled = false;
char mqttDeviceTopic[33] = ""; //main MQTT topic (individual per device, default is wled/mac)
@@ -464,8 +466,6 @@ void handleE131Packet(e131_packet_t*, IPAddress);
void arlsLock(uint32_t,byte);
void handleOverlayDraw();
-#define E131_MAX_UNIVERSE_COUNT 9
-
//udp interface objects
WiFiUDP notifierUdp, rgbUdp;
WiFiUDP ntpUdp;
diff --git a/wled00/wled01_eeprom.ino b/wled00/wled01_eeprom.ino
index acfc8dce..1f0e8426 100644
--- a/wled00/wled01_eeprom.ino
+++ b/wled00/wled01_eeprom.ino
@@ -6,7 +6,7 @@
#define EEPSIZE 2560 //Maximum is 4096
//eeprom Version code, enables default settings instead of 0 init on update
-#define EEPVER 17
+#define EEPVER 18
//0 -> old version, default
//1 -> 0.4p 1711272 and up
//2 -> 0.4p 1711302 and up
@@ -25,6 +25,7 @@
//15-> 0.9.0-b3
//16-> 0.9.1
//17-> 0.9.1-dmx
+//18-> 0.9.1-e131
void commit()
{
@@ -208,6 +209,7 @@ void saveSettingsToEEPROM()
EEPROM.write(2181, macroNl);
EEPROM.write(2182, macroDoublePress);
+ EEPROM.write(2189, e131SkipOutOfSequence);
EEPROM.write(2190, e131Universe & 0xFF);
EEPROM.write(2191, (e131Universe >> 8) & 0xFF);
EEPROM.write(2192, e131Multicast);
@@ -505,6 +507,12 @@ void loadSettingsFromEEPROM(bool first)
noWifiSleep = EEPROM.read(370);
//}
+ if (lastEEPROMversion > 17)
+ {
+ e131SkipOutOfSequence = EEPROM.read(2189);
+ } else {
+ e131SkipOutOfSequence = true;
+ }
receiveDirect = !EEPROM.read(2200);
notifyMacro = EEPROM.read(2201);
diff --git a/wled00/wled02_xml.ino b/wled00/wled02_xml.ino
index d538e0c4..100be482 100644
--- a/wled00/wled02_xml.ino
+++ b/wled00/wled02_xml.ino
@@ -74,8 +74,6 @@ char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr)
mesg += ".";
mesg += realtimeIP[i];
}
- mesg += " seq=";
- mesg += e131LastSequenceNumber;
} else if (realtimeMode == REALTIME_MODE_UDP || realtimeMode == REALTIME_MODE_HYPERION) {
mesg += "UDP from ";
mesg += realtimeIP[0];
@@ -326,6 +324,7 @@ void getSettingsJS(byte subPage, char* dest)
sappend('c',"SM",notifyMacro);
sappend('c',"S2",notifyTwice);
sappend('c',"RD",receiveDirect);
+ sappend('c',"ES",e131SkipOutOfSequence);
sappend('c',"EM",e131Multicast);
sappend('v',"EU",e131Universe);
sappend('v',"DA",DMXAddress);
diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino
index d3897149..5a7f4db6 100644
--- a/wled00/wled03_set.ino
+++ b/wled00/wled03_set.ino
@@ -138,6 +138,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
notifyTwice = request->hasArg("S2");
receiveDirect = request->hasArg("RD");
+ e131SkipOutOfSequence = request->hasArg("ES");
e131Multicast = request->hasArg("EM");
t = request->arg("EU").toInt();
if (t > 0 && t <= 63999) e131Universe = t;
diff --git a/wled00/wled07_notify.ino b/wled00/wled07_notify.ino
index 7f691dd0..b1fab41e 100644
--- a/wled00/wled07_notify.ino
+++ b/wled00/wled07_notify.ino
@@ -88,26 +88,31 @@ void arlsLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC)
void handleE131Packet(e131_packet_t* p, IPAddress clientIP){
//E1.31 protocol support
-
- // skip out-of-sequence packets
- if (p->sequence_number < e131LastSequenceNumber && p->sequence_number > 20 && e131LastSequenceNumber < 250){
- DEBUG_PRINT("skipping E1.31 frame (last seq=");
- DEBUG_PRINT(e131LastSequenceNumber);
- DEBUG_PRINT(", current seq=");
- DEBUG_PRINT(p->sequence_number);
- DEBUG_PRINTLN(")");
- return;
- }
- e131LastSequenceNumber = p->sequence_number;
- // update status info
- realtimeIP = clientIP;
-
uint16_t uni = htons(p->universe);
uint8_t previousUniverses = uni - e131Universe;
uint16_t possibleLEDsInCurrentUniverse;
uint16_t dmxChannels = htons(p->property_value_count) -1;
+ // only listen for universes we're handling & allocated memory
+ if (uni >= (e131Universe + E131_MAX_UNIVERSE_COUNT)) return;
+
+ if (e131SkipOutOfSequence)
+ if (p->sequence_number < e131LastSequenceNumber[uni-e131Universe] && p->sequence_number > 20 && e131LastSequenceNumber[uni-e131Universe] < 250){
+ DEBUG_PRINT("skipping E1.31 frame (last seq=");
+ DEBUG_PRINT(e131LastSequenceNumber[uni-e131Universe]);
+ DEBUG_PRINT(", current seq=");
+ DEBUG_PRINT(p->sequence_number);
+ DEBUG_PRINT(", universe=");
+ DEBUG_PRINT(uni);
+ DEBUG_PRINTLN(")");
+ return;
+ }
+ e131LastSequenceNumber[uni-e131Universe] = p->sequence_number;
+
+ // update status info
+ realtimeIP = clientIP;
+
switch (DMXMode) {
case DMX_MODE_DISABLED:
return; // nothing to do