Fix multi-universe ArtNet output
The existing code was very buggy - a 512 channel ArtNet packet sent data to 171 LEDs, not 170. Also the second ArtNet universe was off-by-one. The math was very confusing with so many branches. The reduces the amount of code and amount of branching. Tested with Resolume + my own ArtNet software + 252 LEDs for ArtNet. Tested with LedFx for e1.31
This commit is contained in:
parent
a0d88b0cbe
commit
3a4f4c8c34
@ -2,7 +2,7 @@
|
|||||||
<html><head><meta name="viewport" content="width=500"><meta charset="utf-8"><title>Sync Settings</title>
|
<html><head><meta name="viewport" content="width=500"><meta charset="utf-8"><title>Sync Settings</title>
|
||||||
<script>var d=document;
|
<script>var d=document;
|
||||||
function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#sync-settings");}function B(){window.open("/settings","_self");}
|
function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#sync-settings");}function B(){window.open("/settings","_self");}
|
||||||
function adj(){if (d.Sf.DI.value == 6454) {if (d.Sf.DA.value == 1) d.Sf.DA.value = 0; if (d.Sf.EU.value == 1) d.Sf.EU.value = 0;}
|
function adj(){if (d.Sf.DI.value == 6454) {if (d.Sf.DA.value == 1) d.Sf.DA.value = 0; if (d.Sf.EU.value == 1) d.Sf.EU.value = 0;}
|
||||||
else if (d.Sf.DI.value == 5568) {if (d.Sf.DA.value == 0) d.Sf.DA.value = 1; if (d.Sf.EU.value == 0) d.Sf.EU.value = 1;} }
|
else if (d.Sf.DI.value == 5568) {if (d.Sf.DA.value == 0) d.Sf.DA.value = 1; if (d.Sf.EU.value == 0) d.Sf.EU.value = 1;} }
|
||||||
function SP(){var p = d.Sf.DI.value; d.getElementById("xp").style.display = (p > 0)?"none":"block"; if (p > 0) d.Sf.EP.value = p;}
|
function SP(){var p = d.Sf.DI.value; d.getElementById("xp").style.display = (p > 0)?"none":"block"; if (p > 0) d.Sf.EP.value = p;}
|
||||||
function SetVal(){switch(parseInt(d.Sf.EP.value)){case 5568: d.Sf.DI.value = 5568; break; case 6454: d.Sf.DI.value = 6454; break; }; SP();}
|
function SetVal(){switch(parseInt(d.Sf.EP.value)){case 5568: d.Sf.DI.value = 5568; break; case 6454: d.Sf.DI.value = 6454; break; }; SP();}
|
||||||
@ -41,7 +41,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>Network DMX input</i><br>
|
<i>Network DMX input</i><br>
|
||||||
Type:
|
Type:
|
||||||
<select name=DI onchange="SP(); adj();">
|
<select name=DI onchange="SP(); adj();">
|
||||||
<option value=5568>E1.31 (sACN)</option>
|
<option value=5568>E1.31 (sACN)</option>
|
||||||
<option value=6454>Art-Net</option>
|
<option value=6454>Art-Net</option>
|
||||||
@ -60,7 +60,7 @@ DMX mode:
|
|||||||
<option value=2>Single DRGB</option>
|
<option value=2>Single DRGB</option>
|
||||||
<option value=3>Effect</option>
|
<option value=3>Effect</option>
|
||||||
<option value=4>Multi RGB</option>
|
<option value=4>Multi RGB</option>
|
||||||
<option value=5>Multi DRGB</option>
|
<option value=5>Dimmer + Multi RGB</option>
|
||||||
</select><br>
|
</select><br>
|
||||||
<a href="https://github.com/Aircoookie/WLED/wiki/E1.31-DMX" target="_blank">E1.31 info</a><br>
|
<a href="https://github.com/Aircoookie/WLED/wiki/E1.31-DMX" target="_blank">E1.31 info</a><br>
|
||||||
Timeout: <input name="ET" type="number" min="1" max="65000" required> ms<br>
|
Timeout: <input name="ET" type="number" min="1" max="65000" required> ms<br>
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
#include "wled.h"
|
#include "wled.h"
|
||||||
|
|
||||||
|
#define MAX_LEDS_PER_UNIVERSE 170
|
||||||
|
#define MAX_CHANNELS_PER_UNIVERSE 512
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* E1.31 handler
|
* E1.31 handler
|
||||||
*/
|
*/
|
||||||
@ -38,7 +41,6 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, bool isArtnet){
|
|||||||
if (uni >= (e131Universe + E131_MAX_UNIVERSE_COUNT)) return;
|
if (uni >= (e131Universe + E131_MAX_UNIVERSE_COUNT)) return;
|
||||||
|
|
||||||
uint8_t previousUniverses = uni - e131Universe;
|
uint8_t previousUniverses = uni - e131Universe;
|
||||||
uint16_t possibleLEDsInCurrentUniverse;
|
|
||||||
|
|
||||||
if (e131SkipOutOfSequence)
|
if (e131SkipOutOfSequence)
|
||||||
if (seq < e131LastSequenceNumber[uni-e131Universe] && seq > 20 && e131LastSequenceNumber[uni-e131Universe] < 250){
|
if (seq < e131LastSequenceNumber[uni-e131Universe] && seq > 20 && e131LastSequenceNumber[uni-e131Universe] < 250){
|
||||||
@ -56,7 +58,7 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, bool isArtnet){
|
|||||||
// update status info
|
// update status info
|
||||||
realtimeIP = clientIP;
|
realtimeIP = clientIP;
|
||||||
byte wChannel = 0;
|
byte wChannel = 0;
|
||||||
|
|
||||||
switch (DMXMode) {
|
switch (DMXMode) {
|
||||||
case DMX_MODE_DISABLED:
|
case DMX_MODE_DISABLED:
|
||||||
return; // nothing to do
|
return; // nothing to do
|
||||||
@ -115,57 +117,32 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, bool isArtnet){
|
|||||||
return; // don't activate realtime live mode
|
return; // don't activate realtime live mode
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DMX_MODE_MULTIPLE_RGB:
|
|
||||||
realtimeLock(realtimeTimeoutMs, mde);
|
|
||||||
if (realtimeOverride) return;
|
|
||||||
if (previousUniverses == 0) {
|
|
||||||
// first universe of this fixture
|
|
||||||
possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress + 1) / 3;
|
|
||||||
for (uint16_t i = 0; i < ledCount; i++) {
|
|
||||||
if (i >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s)
|
|
||||||
setRealtimePixel(i, e131_data[DMXAddress+i*3+0], e131_data[DMXAddress+i*3+1], e131_data[DMXAddress+i*3+2], 0);
|
|
||||||
}
|
|
||||||
} else if (previousUniverses > 0 && uni < (e131Universe + E131_MAX_UNIVERSE_COUNT)) {
|
|
||||||
// additional universe(s) of this fixture
|
|
||||||
uint16_t numberOfLEDsInPreviousUniverses = ((512 - DMXAddress + 1) / 3); // first universe
|
|
||||||
if (previousUniverses > 1) numberOfLEDsInPreviousUniverses += (512 / 3) * (previousUniverses - 1); // extended universe(s) before current
|
|
||||||
possibleLEDsInCurrentUniverse = dmxChannels / 3;
|
|
||||||
for (uint16_t i = numberOfLEDsInPreviousUniverses; i < ledCount; i++) {
|
|
||||||
uint8_t j = i - numberOfLEDsInPreviousUniverses;
|
|
||||||
if (j >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s)
|
|
||||||
setRealtimePixel(i, e131_data[j*3+1], e131_data[j*3+2], e131_data[j*3+3], 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DMX_MODE_MULTIPLE_DRGB:
|
case DMX_MODE_MULTIPLE_DRGB:
|
||||||
realtimeLock(realtimeTimeoutMs, mde);
|
case DMX_MODE_MULTIPLE_RGB:
|
||||||
if (realtimeOverride) return;
|
{
|
||||||
if (previousUniverses == 0) {
|
realtimeLock(realtimeTimeoutMs, mde);
|
||||||
// first universe of this fixture
|
if (realtimeOverride) return;
|
||||||
if (DMXOldDimmer != e131_data[DMXAddress+0]) {
|
uint16_t previousLEDs, dmxOffset;
|
||||||
DMXOldDimmer = e131_data[DMXAddress+0];
|
if (previousUniverses == 0) {
|
||||||
bri = e131_data[DMXAddress+0];
|
if (dmxChannels-DMXAddress < 1) return;
|
||||||
strip.setBrightness(bri);
|
dmxOffset = DMXAddress;
|
||||||
|
previousLEDs = 0;
|
||||||
|
// First DMX address is dimmer in DMX_MODE_MULTIPLE_DRGB mode.
|
||||||
|
if (DMXMode == DMX_MODE_MULTIPLE_DRGB) {
|
||||||
|
strip.setBrightness( e131_data[dmxOffset++]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// All subsequent universes start at the first channel.
|
||||||
|
dmxOffset = isArtnet ? 0 : 1;
|
||||||
|
uint16_t possibleLEDsFirstUniverse = (MAX_CHANNELS_PER_UNIVERSE - DMXAddress) / 3;
|
||||||
|
previousLEDs = possibleLEDsFirstUniverse + (previousUniverses - 1) * MAX_LEDS_PER_UNIVERSE;
|
||||||
}
|
}
|
||||||
possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress) / 3;
|
uint16_t ledCount = previousLEDs + (dmxChannels - dmxOffset) / 3;
|
||||||
for (uint16_t i = 0; i < ledCount; i++) {
|
for (uint16_t i = previousLEDs; i < ledCount; i++) {
|
||||||
if (i >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s)
|
setRealtimePixel(i, e131_data[dmxOffset++], e131_data[dmxOffset++], e131_data[dmxOffset++], 0);
|
||||||
setRealtimePixel(i, e131_data[DMXAddress+i*3+1], e131_data[DMXAddress+i*3+2], e131_data[DMXAddress+i*3+3], 0);
|
|
||||||
}
|
|
||||||
} else if (previousUniverses > 0 && uni < (e131Universe + E131_MAX_UNIVERSE_COUNT)) {
|
|
||||||
// additional universe(s) of this fixture
|
|
||||||
uint16_t numberOfLEDsInPreviousUniverses = ((512 - DMXAddress + 1) / 3); // first universe
|
|
||||||
if (previousUniverses > 1) numberOfLEDsInPreviousUniverses += (512 / 3) * (previousUniverses - 1); // extended universe(s) before current
|
|
||||||
possibleLEDsInCurrentUniverse = dmxChannels / 3;
|
|
||||||
for (uint16_t i = numberOfLEDsInPreviousUniverses; i < ledCount; i++) {
|
|
||||||
uint8_t j = i - numberOfLEDsInPreviousUniverses;
|
|
||||||
if (j >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s)
|
|
||||||
setRealtimePixel(i, e131_data[j*3+1], e131_data[j*3+2], e131_data[j*3+3], 0);
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DEBUG_PRINTLN("unknown E1.31 DMX mode");
|
DEBUG_PRINTLN("unknown E1.31 DMX mode");
|
||||||
return; // nothing to do
|
return; // nothing to do
|
||||||
|
Loading…
Reference in New Issue
Block a user