Merge pull request #766 from pille/E1.31-sequencenumber-per-universe
fixes #742
This commit is contained in:
commit
7b4dc43147
@ -85,6 +85,7 @@
|
|||||||
<h3>Realtime</h3>
|
<h3>Realtime</h3>
|
||||||
Receive UDP realtime: <input type="checkbox" name="RD"><br><br>
|
Receive UDP realtime: <input type="checkbox" name="RD"><br><br>
|
||||||
E1.31 (sACN)<br>
|
E1.31 (sACN)<br>
|
||||||
|
Skip out-of-sequence packets (freeze instead of flicker): <input type="checkbox" name="ES"><br>
|
||||||
Multicast mode: <input type="checkbox" name="EM"><br>
|
Multicast mode: <input type="checkbox" name="EM"><br>
|
||||||
E1.31 start universe: <input name="EU" type="number" min="1" max="63999" required><br>
|
E1.31 start universe: <input name="EU" type="number" min="1" max="63999" required><br>
|
||||||
<i>Reboot required.</i> Check out <a href="https://github.com/ahodges9/LedFx" target="_blank">LedFx</a>!<br><br>
|
<i>Reboot required.</i> Check out <a href="https://github.com/ahodges9/LedFx" target="_blank">LedFx</a>!<br><br>
|
||||||
|
@ -284,6 +284,7 @@ Send notifications twice: <input type="checkbox" name="S2">
|
|||||||
<h3>Realtime</h3>
|
<h3>Realtime</h3>
|
||||||
Receive UDP realtime: <input type="checkbox" name="RD"><br><br>
|
Receive UDP realtime: <input type="checkbox" name="RD"><br><br>
|
||||||
<i>E1.31 (sACN)</i><br>
|
<i>E1.31 (sACN)</i><br>
|
||||||
|
Skip out-of-sequence packets (freeze instead of flicker): <input type="checkbox" name="ES"><br>
|
||||||
Use E1.31 multicast: <input type="checkbox" name="EM"><br>
|
Use E1.31 multicast: <input type="checkbox" name="EM"><br>
|
||||||
E1.31 start universe: <input name="EU" type="number" min="1" max="63999" required><br>
|
E1.31 start universe: <input name="EU" type="number" min="1" max="63999" required><br>
|
||||||
<i>Reboot required.</i> Check out <a href="https://github.com/ahodges9/LedFx" target="_blank">LedFx</a>!<br>
|
<i>Reboot required.</i> Check out <a href="https://github.com/ahodges9/LedFx" target="_blank">LedFx</a>!<br>
|
||||||
|
@ -206,12 +206,14 @@ bool receiveDirect = true; //receive UDP realtime
|
|||||||
bool arlsDisableGammaCorrection = true; //activate if gamma correction is handled by the source
|
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
|
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)
|
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.)
|
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]
|
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 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 e131Multicast = false; //multicast or unicast
|
||||||
|
bool e131SkipOutOfSequence = false; //freeze instead of flickering
|
||||||
|
|
||||||
bool mqttEnabled = false;
|
bool mqttEnabled = false;
|
||||||
char mqttDeviceTopic[33] = ""; //main MQTT topic (individual per device, default is wled/mac)
|
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 arlsLock(uint32_t,byte);
|
||||||
void handleOverlayDraw();
|
void handleOverlayDraw();
|
||||||
|
|
||||||
#define E131_MAX_UNIVERSE_COUNT 9
|
|
||||||
|
|
||||||
//udp interface objects
|
//udp interface objects
|
||||||
WiFiUDP notifierUdp, rgbUdp;
|
WiFiUDP notifierUdp, rgbUdp;
|
||||||
WiFiUDP ntpUdp;
|
WiFiUDP ntpUdp;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#define EEPSIZE 2560 //Maximum is 4096
|
#define EEPSIZE 2560 //Maximum is 4096
|
||||||
|
|
||||||
//eeprom Version code, enables default settings instead of 0 init on update
|
//eeprom Version code, enables default settings instead of 0 init on update
|
||||||
#define EEPVER 17
|
#define EEPVER 18
|
||||||
//0 -> old version, default
|
//0 -> old version, default
|
||||||
//1 -> 0.4p 1711272 and up
|
//1 -> 0.4p 1711272 and up
|
||||||
//2 -> 0.4p 1711302 and up
|
//2 -> 0.4p 1711302 and up
|
||||||
@ -25,6 +25,7 @@
|
|||||||
//15-> 0.9.0-b3
|
//15-> 0.9.0-b3
|
||||||
//16-> 0.9.1
|
//16-> 0.9.1
|
||||||
//17-> 0.9.1-dmx
|
//17-> 0.9.1-dmx
|
||||||
|
//18-> 0.9.1-e131
|
||||||
|
|
||||||
void commit()
|
void commit()
|
||||||
{
|
{
|
||||||
@ -208,6 +209,7 @@ void saveSettingsToEEPROM()
|
|||||||
EEPROM.write(2181, macroNl);
|
EEPROM.write(2181, macroNl);
|
||||||
EEPROM.write(2182, macroDoublePress);
|
EEPROM.write(2182, macroDoublePress);
|
||||||
|
|
||||||
|
EEPROM.write(2189, e131SkipOutOfSequence);
|
||||||
EEPROM.write(2190, e131Universe & 0xFF);
|
EEPROM.write(2190, e131Universe & 0xFF);
|
||||||
EEPROM.write(2191, (e131Universe >> 8) & 0xFF);
|
EEPROM.write(2191, (e131Universe >> 8) & 0xFF);
|
||||||
EEPROM.write(2192, e131Multicast);
|
EEPROM.write(2192, e131Multicast);
|
||||||
@ -505,6 +507,12 @@ void loadSettingsFromEEPROM(bool first)
|
|||||||
noWifiSleep = EEPROM.read(370);
|
noWifiSleep = EEPROM.read(370);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
if (lastEEPROMversion > 17)
|
||||||
|
{
|
||||||
|
e131SkipOutOfSequence = EEPROM.read(2189);
|
||||||
|
} else {
|
||||||
|
e131SkipOutOfSequence = true;
|
||||||
|
}
|
||||||
|
|
||||||
receiveDirect = !EEPROM.read(2200);
|
receiveDirect = !EEPROM.read(2200);
|
||||||
notifyMacro = EEPROM.read(2201);
|
notifyMacro = EEPROM.read(2201);
|
||||||
|
@ -74,8 +74,6 @@ char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr)
|
|||||||
mesg += ".";
|
mesg += ".";
|
||||||
mesg += realtimeIP[i];
|
mesg += realtimeIP[i];
|
||||||
}
|
}
|
||||||
mesg += " seq=";
|
|
||||||
mesg += e131LastSequenceNumber;
|
|
||||||
} else if (realtimeMode == REALTIME_MODE_UDP || realtimeMode == REALTIME_MODE_HYPERION) {
|
} else if (realtimeMode == REALTIME_MODE_UDP || realtimeMode == REALTIME_MODE_HYPERION) {
|
||||||
mesg += "UDP from ";
|
mesg += "UDP from ";
|
||||||
mesg += realtimeIP[0];
|
mesg += realtimeIP[0];
|
||||||
@ -326,6 +324,7 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
sappend('c',"SM",notifyMacro);
|
sappend('c',"SM",notifyMacro);
|
||||||
sappend('c',"S2",notifyTwice);
|
sappend('c',"S2",notifyTwice);
|
||||||
sappend('c',"RD",receiveDirect);
|
sappend('c',"RD",receiveDirect);
|
||||||
|
sappend('c',"ES",e131SkipOutOfSequence);
|
||||||
sappend('c',"EM",e131Multicast);
|
sappend('c',"EM",e131Multicast);
|
||||||
sappend('v',"EU",e131Universe);
|
sappend('v',"EU",e131Universe);
|
||||||
sappend('v',"DA",DMXAddress);
|
sappend('v',"DA",DMXAddress);
|
||||||
|
@ -138,6 +138,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
notifyTwice = request->hasArg("S2");
|
notifyTwice = request->hasArg("S2");
|
||||||
|
|
||||||
receiveDirect = request->hasArg("RD");
|
receiveDirect = request->hasArg("RD");
|
||||||
|
e131SkipOutOfSequence = request->hasArg("ES");
|
||||||
e131Multicast = request->hasArg("EM");
|
e131Multicast = request->hasArg("EM");
|
||||||
t = request->arg("EU").toInt();
|
t = request->arg("EU").toInt();
|
||||||
if (t > 0 && t <= 63999) e131Universe = t;
|
if (t > 0 && t <= 63999) e131Universe = t;
|
||||||
|
@ -88,26 +88,31 @@ void arlsLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC)
|
|||||||
|
|
||||||
void handleE131Packet(e131_packet_t* p, IPAddress clientIP){
|
void handleE131Packet(e131_packet_t* p, IPAddress clientIP){
|
||||||
//E1.31 protocol support
|
//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);
|
uint16_t uni = htons(p->universe);
|
||||||
uint8_t previousUniverses = uni - e131Universe;
|
uint8_t previousUniverses = uni - e131Universe;
|
||||||
uint16_t possibleLEDsInCurrentUniverse;
|
uint16_t possibleLEDsInCurrentUniverse;
|
||||||
uint16_t dmxChannels = htons(p->property_value_count) -1;
|
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) {
|
switch (DMXMode) {
|
||||||
case DMX_MODE_DISABLED:
|
case DMX_MODE_DISABLED:
|
||||||
return; // nothing to do
|
return; // nothing to do
|
||||||
|
Loading…
Reference in New Issue
Block a user