Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new options for Artnet / sACN #4011

Open
wants to merge 2 commits into
base: 0_15
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion wled00/const.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,9 @@
#define DMX_MODE_EFFECT_SEGMENT 8 //trigger standalone effects of WLED (15 channels per segment)
#define DMX_MODE_EFFECT_SEGMENT_W 9 //trigger standalone effects of WLED (18 channels per segment)
#define DMX_MODE_PRESET 10 //apply presets (1 channel)

#define DMX_MODE_PRESET_MULTIPLE_RGB 11 //Preset and multi RGB
#define DMX_MODE_PRESET_MULTIPLE_RGBW 12 //Preset and multi RGBW
#define DMX_MODE_LAST 12 //Should always ahve the same ID as the last option
//Light capability byte (unused) 0bRCCCTTTT
//bits 0/1/2/3: specifies a type of LED driver. A single "driver" may have different chip models but must have the same protocol/behavior
//bits 4/5/6: specifies the class of LED driver - 0b000 (dec. 0-15) unconfigured/reserved
Expand Down
2 changes: 2 additions & 0 deletions wled00/data/settings_sync.htm
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ <h3>Realtime</h3>
<option value=5>Dimmer + Multi RGB</option>
<option value=6>Multi RGBW</option>
<option value=10>Preset</option>
<option value=11>Preset + Multi RGB</option>
<option value=12>Preset + Multi RGBW</option>
</select><br>
<a href="https://kno.wled.ge/interfaces/e1.31-dmx/" target="_blank">E1.31 info</a><br>
Timeout: <input name="ET" type="number" min="1" max="65000" required> ms<br>
Expand Down
93 changes: 92 additions & 1 deletion wled00/e131.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,94 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, byte protocol){
}
break;
}
case DMX_MODE_PRESET_MULTIPLE_RGB:
case DMX_MODE_PRESET_MULTIPLE_RGBW:
{
if (availDMXLen < 3) return;

static uint8_t mode;

//only check mode if we're in the first universe
if(previousUniverses==0)
{
mode = e131_data[dataOffset];
}

//mode 0-126: preset mode
if( mode < 127)
{
if(previousUniverses != 0) return;
// limit max. selectable preset to 250, even though DMX max. val is 255
uint8_t dmxValPreset = (e131_data[dataOffset+2] > 250 ? 250 : e131_data[dataOffset+2]);

// only apply preset if value changed
if (dmxValPreset != 0 && dmxValPreset != currentPreset &&
// only apply preset if not in playlist, or playlist changed
(currentPlaylist < 0 || dmxValPreset != currentPlaylist)) {
presetCycCurr = dmxValPreset;
unloadPlaylist(); // applying a preset unloads the playlist
applyPreset(dmxValPreset, CALL_MODE_NOTIFICATION);
}

// only change brightness if value changed
if (bri != e131_data[dataOffset+1]) {
bri = e131_data[dataOffset+1];
strip.setBrightness(scaledBri(bri), false);
stateUpdated(CALL_MODE_WS_SEND);
}
return;
}
//Mode 127-255: Raw pixel mode
else
{
bool is4Chan = (DMXMode == DMX_MODE_PRESET_MULTIPLE_RGBW);
const uint16_t dmxChannelsPerLed = is4Chan ? 4 : 3;
const uint16_t ledsPerUniverse = is4Chan ? MAX_4_CH_LEDS_PER_UNIVERSE : MAX_3_CH_LEDS_PER_UNIVERSE;
uint8_t stripBrightness = 255;
uint16_t previousLeds, dmxOffset, ledsTotal;

if (previousUniverses == 0) {
if (availDMXLen < 4) return;
dmxOffset = dataOffset+4;
previousLeds = 0;
// First DMX address is dimmer.
ledsTotal = (availDMXLen-4) / dmxChannelsPerLed;

} else {
// All subsequent universes start at the first channel.
dmxOffset = (protocol == P_ARTNET) ? 0 : 1;
const uint16_t dimmerOffset = 4;
uint16_t ledsInFirstUniverse = (((MAX_CHANNELS_PER_UNIVERSE - DMXAddress) + dmxLenOffset) - dimmerOffset) / dmxChannelsPerLed;
previousLeds = ledsInFirstUniverse + (previousUniverses - 1) * ledsPerUniverse;
ledsTotal = previousLeds + (dmxChannels / dmxChannelsPerLed);
}

// All LEDs already have values
if (previousLeds >= totalLen) {
return;
}

realtimeLock(realtimeTimeoutMs, mde);
if (realtimeOverride && !(realtimeMode && useMainSegmentOnly)) return;

if (ledsTotal > totalLen) {
ledsTotal = totalLen;
}

if (!is4Chan) {
for (uint16_t i = previousLeds; i < ledsTotal; i++) {
setRealtimePixel(i, e131_data[dmxOffset], e131_data[dmxOffset+1], e131_data[dmxOffset+2], 0);
dmxOffset+=3;
}
} else {
for (uint16_t i = previousLeds; i < ledsTotal; i++) {
setRealtimePixel(i, e131_data[dmxOffset], e131_data[dmxOffset+1], e131_data[dmxOffset+2], e131_data[dmxOffset+3]);
dmxOffset+=4;
}
}
}
break;
}
default:
DEBUG_PRINTLN(F("unknown E1.31 DMX mode"));
return; // nothing to do
Expand Down Expand Up @@ -353,10 +441,13 @@ void handleArtnetPollReply(IPAddress ipAddress) {
case DMX_MODE_MULTIPLE_DRGB:
case DMX_MODE_MULTIPLE_RGB:
case DMX_MODE_MULTIPLE_RGBW:
case DMX_MODE_PRESET_MULTIPLE_RGB:
case DMX_MODE_PRESET_MULTIPLE_RGBW:
{
bool is4Chan = (DMXMode == DMX_MODE_MULTIPLE_RGBW);
const unsigned dmxChannelsPerLed = is4Chan ? 4 : 3;
const unsigned dimmerOffset = (DMXMode == DMX_MODE_MULTIPLE_DRGB) ? 1 : 0;
const unsigned dimmerOffset = (DMXMode == DMX_MODE_MULTIPLE_DRGB) ? 1 :
(DMXMode == DMX_MODE_PRESET_MULTIPLE_RGB || DMXMode == DMX_MODE_PRESET_MULTIPLE_RGBW ) ? 4 : 0;
const unsigned dmxLenOffset = (DMXAddress == 0) ? 0 : 1; // For legacy DMX start address 0
const unsigned ledsInFirstUniverse = (((MAX_CHANNELS_PER_UNIVERSE - DMXAddress) + dmxLenOffset) - dimmerOffset) / dmxChannelsPerLed;
const unsigned totalLen = strip.getLengthTotal();
Expand Down
2 changes: 1 addition & 1 deletion wled00/set.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
t = request->arg(F("PY")).toInt();
if (t >= 0 && t <= 200) e131Priority = t;
t = request->arg(F("DM")).toInt();
if (t >= DMX_MODE_DISABLED && t <= DMX_MODE_PRESET) DMXMode = t;
if (t >= DMX_MODE_DISABLED && t <= DMX_MODE_LAST) DMXMode = t;
t = request->arg(F("ET")).toInt();
if (t > 99 && t <= 65000) realtimeTimeoutMs = t;
arlsForceMaxBri = request->hasArg(F("FB"));
Expand Down