Add Art-Net support (#417)
This commit is contained in:
parent
3006d25406
commit
e12757dbb9
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
### Development versions after 0.9.1 release
|
### Development versions after 0.9.1 release
|
||||||
|
|
||||||
|
#### Build 2004120
|
||||||
|
|
||||||
|
- Added Art-Net support
|
||||||
|
- Added OTA platform to platformio.ini
|
||||||
|
|
||||||
#### Build 2004100
|
#### Build 2004100
|
||||||
|
|
||||||
@ -23,7 +27,7 @@
|
|||||||
|
|
||||||
#### Build 2003262
|
#### Build 2003262
|
||||||
|
|
||||||
- Fixed compilation for Analog LEDs
|
- Fixed compilation for Analog LEDs
|
||||||
- Fixed sync settings network port fields too small
|
- Fixed sync settings network port fields too small
|
||||||
|
|
||||||
#### Build 2003261
|
#### Build 2003261
|
||||||
|
@ -30,6 +30,7 @@ default_envs = d1_mini, esp01, esp01_1m_ota, esp32dev
|
|||||||
; default_envs = d1_mini
|
; default_envs = d1_mini
|
||||||
; default_envs = heltec_wifi_kit_8
|
; default_envs = heltec_wifi_kit_8
|
||||||
; default_envs = d1_mini_debug
|
; default_envs = d1_mini_debug
|
||||||
|
; default_envs = d1_mini_ota
|
||||||
; default_envs = esp32dev
|
; default_envs = esp32dev
|
||||||
; default_envs = esp8285_4CH_MagicHome
|
; default_envs = esp8285_4CH_MagicHome
|
||||||
; default_envs = esp8285_4CH_H801
|
; default_envs = esp8285_4CH_H801
|
||||||
@ -241,6 +242,15 @@ platform = ${common.platform_latest}
|
|||||||
board_build.ldscript = ${common.ldscript_4m1m}
|
board_build.ldscript = ${common.ldscript_4m1m}
|
||||||
build_flags = ${common.build_flags_esp8266} ${common.debug_flags}
|
build_flags = ${common.build_flags_esp8266} ${common.debug_flags}
|
||||||
|
|
||||||
|
[env:d1_mini_ota]
|
||||||
|
board = d1_mini
|
||||||
|
upload_protocol = espota
|
||||||
|
# exchange for your WLED IP
|
||||||
|
upload_port = "10.10.1.27"
|
||||||
|
platform = ${common.platform_latest}
|
||||||
|
board_build.ldscript = ${common.ldscript_4m1m}
|
||||||
|
build_flags = ${common.build_flags_esp8266}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# custom board configurations
|
# custom board configurations
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#define REALTIME_MODE_HYPERION 3
|
#define REALTIME_MODE_HYPERION 3
|
||||||
#define REALTIME_MODE_E131 4
|
#define REALTIME_MODE_E131 4
|
||||||
#define REALTIME_MODE_ADALIGHT 5
|
#define REALTIME_MODE_ADALIGHT 5
|
||||||
|
#define REALTIME_MODE_ARTNET 6
|
||||||
|
|
||||||
//E1.31 DMX modes
|
//E1.31 DMX modes
|
||||||
#define DMX_MODE_DISABLED 0 //not used
|
#define DMX_MODE_DISABLED 0 //not used
|
||||||
|
@ -1,141 +1,105 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html><head><meta name="viewport" content="width=500"><meta charset="utf-8"><title>Sync Settings</title>
|
||||||
<head>
|
<script>var d=document;
|
||||||
<meta name="viewport" content="width=500">
|
function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#sync-settings");}function B(){window.open("/settings","_self");}function GetV(){var d=document;}
|
||||||
<title>Sync Settings</title>
|
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;}
|
||||||
<script>
|
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 H()
|
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();}
|
||||||
window.open("https://github.com/Aircoookie/WLED/wiki/Settings#sync-settings");
|
function S(){GetV();SetVal();}
|
||||||
}
|
</script>
|
||||||
function B()
|
<style>body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%;margin:0}hr{border-color:#666}button{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}.helpB{text-align:left;position:absolute;width:60px}input{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.5ch solid #333}input[type=number]{width:4em}select{background:#333;color:#fff;font-family:Verdana,sans-serif;border:0.5ch solid #333}td{padding:2px;}.d5{width:4.5em !important;}</style></head>
|
||||||
{
|
<body onload="S()">
|
||||||
window.open("/settings","_self");
|
<form id="form_s" name="Sf" method="post">
|
||||||
}
|
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
||||||
function GetV()
|
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
||||||
{
|
<h2>Sync setup</h2>
|
||||||
//values injected by server while sending HTML
|
<h3>Button setup</h3>
|
||||||
}
|
On/Off button enabled: <input type="checkbox" name="BT"><br>
|
||||||
</script>
|
Infrared remote:
|
||||||
<style>
|
<select name=IR>
|
||||||
:root {
|
<option value=0>Disabled</option>
|
||||||
--aCol: #abc;
|
<option value=1>24-key RGB</option>
|
||||||
--bCol: #fff;
|
<option value=2>24-key with CT</option>
|
||||||
--cCol: #ddd;
|
<option value=3>40-key blue</option>
|
||||||
--dCol: #000;
|
<option value=4>44-key RGB</option>
|
||||||
--sCol: #0004;
|
<option value=5>21-key RGB</option>
|
||||||
}
|
<option value=6>6-key black</option>
|
||||||
body {
|
</select><br>
|
||||||
font-family: Verdana, Helvetica, sans-serif;
|
<a href="https://github.com/Aircoookie/WLED/wiki/Infrared-Control" target="_blank">IR info</a>
|
||||||
text-align: center;
|
<h3>WLED Broadcast</h3>
|
||||||
background: var(--cCol);
|
UDP Port: <input name="UP" type="number" min="1" max="65535" class="d5" required><br>
|
||||||
color: var(--dCol);
|
Receive <input type="checkbox" name="RB">Brightness, <input type="checkbox" name="RC">Color, and <input type="checkbox" name="RX">Effects<br>
|
||||||
line-height: 200%;
|
Send notifications on direct change: <input type="checkbox" name="SD"><br>
|
||||||
margin: 0;
|
Send notifications on button press: <input type="checkbox" name="SB"><br>
|
||||||
background-attachment: fixed;
|
Send Alexa notifications: <input type="checkbox" name="SA"><br>
|
||||||
}
|
Send Philips Hue change notifications: <input type="checkbox" name="SH"><br>
|
||||||
hr {
|
Send Macro notifications: <input type="checkbox" name="SM"><br>
|
||||||
border-color: var(--dCol);
|
Send notifications twice: <input type="checkbox" name="S2">
|
||||||
filter: drop-shadow( -5px -5px 5px var(--sCol) );
|
<h3>Realtime</h3>
|
||||||
}
|
Receive UDP realtime: <input type="checkbox" name="RD"><br><br>
|
||||||
button {
|
<i>Network DMX input</i><br>
|
||||||
background: var(--bCol);
|
Type:
|
||||||
color: var(--dCol);
|
<select name=DI onchange="SP(); adj();">
|
||||||
border: 0.3ch solid var(--bCol);
|
<option value=5568>E1.31 (sACN)</option>
|
||||||
display: inline-block;
|
<option value=6454>Art-Net</option>
|
||||||
filter: drop-shadow( -5px -5px 5px var(--sCol) );
|
<option value=0 selected>Custom port</option>
|
||||||
font-size: 20px;
|
</select><br>
|
||||||
margin: 8px;
|
<div id=xp>Port: <input name="EP" type="number" min="1" max="65535" value="5568" class="d5" required><br></div>
|
||||||
margin-top: 12px;
|
Multicast: <input type="checkbox" name="EM"><br>
|
||||||
}
|
Start universe: <input name="EU" type="number" min="0" max="63999" required><br>
|
||||||
.helpB {
|
<i>Reboot required.</i> Check out <a href="https://github.com/ahodges9/LedFx" target="_blank">LedFx</a>!<br>
|
||||||
text-align: left;
|
Skip out-of-sequence packets: <input type="checkbox" name="ES"><br>
|
||||||
position: absolute;
|
DMX start address: <input name="DA" type="number" min="0" max="510" required><br>
|
||||||
width:60px;
|
DMX mode:
|
||||||
}
|
<select name=DM>
|
||||||
input {
|
<option value=0>Disabled</option>
|
||||||
background: var(--bCol);
|
<option value=1>Single RGB</option>
|
||||||
color: var(--dCol);
|
<option value=2>Single DRGB</option>
|
||||||
border: 0.5ch solid var(--bCol);
|
<option value=3>Effect</option>
|
||||||
filter: drop-shadow( -5px -5px 5px var(--sCol) );
|
<option value=4>Multi RGB</option>
|
||||||
}
|
<option value=5>Multi DRGB</option>
|
||||||
input[type=number] {
|
</select><br>
|
||||||
width: 3em;
|
<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>
|
||||||
</style>
|
Force max brightness: <input type="checkbox" name="FB"><br>
|
||||||
</head>
|
Disable realtime gamma correction: <input type="checkbox" name="RG"><br>
|
||||||
<body onload="GetV()">
|
Realtime LED offset: <input name="WO" type="number" min="-255" max="255" required>
|
||||||
<form id="form_s" name="Sf" method="post">
|
<h3>Alexa Voice Assistant</h3>
|
||||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
Emulate Alexa device: <input type="checkbox" name="AL"><br>
|
||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
Alexa invocation name: <input name="AI" maxlength="32">
|
||||||
<h2>Sync setup</h2>
|
<h3>Blynk</h3>
|
||||||
<h3>Button setup</h3>
|
<b>Blynk, MQTT and Hue sync all connect to external hosts!<br>
|
||||||
On/Off button enabled: <input type="checkbox" name="BT"><br>
|
This may impact the responsiveness of the ESP8266.</b><br>
|
||||||
Infrared receiver enabled: <input type="checkbox" name="IR"><br>
|
For best results, only use one of these services at a time.<br>
|
||||||
<a href="https://github.com/Aircoookie/WLED/wiki/Infrared-Control" target="_blank">IR info</a>
|
(alternatively, connect a second ESP to them and use the UDP sync)<br><br>
|
||||||
<h3>WLED Sync UDP Broadcast</h3>
|
Device Auth token: <input name="BK" maxlength="33"><br>
|
||||||
UDP Port: <input name="UP" type="number" min="1" max="65535" required><br>
|
<i>Clear the token field to disable. </i><a href="https://github.com/Aircoookie/WLED/wiki/Blynk" target="_blank">Setup info</a>
|
||||||
Receive <input type="checkbox" name="RB">Brightness, <input type="checkbox" name="RC">Color, and <input type="checkbox" name="RX">Effects<br>
|
<h3>MQTT</h3>
|
||||||
Send notifications on direct change: <input type="checkbox" name="SD"><br>
|
Enable MQTT: <input type="checkbox" name="MQ"><br>
|
||||||
Send notifications on button press: <input type="checkbox" name="SB"><br>
|
Broker: <input name="MS" maxlength="32">
|
||||||
Send Alexa notifications: <input type="checkbox" name="SA"><br>
|
Port: <input name="MQPORT" type="number" min="1" max="65535" class="d5"><br>
|
||||||
Send Philips Hue change notifications: <input type="checkbox" name="SH"><br>
|
<b>The MQTT credentials are sent over an unsecured connection.<br>
|
||||||
Send Macro notifications: <input type="checkbox" name="SM"><br>
|
Never use the MQTT password for another service!</b><br>
|
||||||
Send notifications twice: <input type="checkbox" name="S2">
|
Username: <input name="MQUSER" maxlength="40"><br>
|
||||||
<h3>Realtime</h3>
|
Password: <input type="password" input name="MQPASS" maxlength="40"><br>
|
||||||
Receive UDP realtime: <input type="checkbox" name="RD"><br><br>
|
Client ID: <input name="MQCID" maxlength="40"><br>
|
||||||
E1.31 (sACN)<br>
|
Device Topic: <input name="MD" maxlength="32"><br>
|
||||||
Skip out-of-sequence packets (freeze instead of flicker): <input type="checkbox" name="ES"><br>
|
Group Topic: <input name="MG" maxlength="32"><br>
|
||||||
Multicast mode: <input type="checkbox" name="EM"><br>
|
<i>Reboot required to apply changes. </i><a href="https://github.com/Aircoookie/WLED/wiki/MQTT" target="_blank">MQTT info</a>
|
||||||
E1.31 start universe: <input name="EU" type="number" min="1" max="63999" required><br>
|
<h3>Philips Hue</h3>
|
||||||
<i>Reboot required.</i> Check out <a href="https://github.com/ahodges9/LedFx" target="_blank">LedFx</a>!<br><br>
|
<i>You can find the bridge IP and the light number in the 'About' section of the hue app.</i><br>
|
||||||
DMX start address: <input name="DA" type="number" min="1" max="510" value="1" required><br>
|
Poll Hue light <input name="HL" type="number" min="1" max="99" > every <input name="HI" type="number" min="100" max="65000"> ms: <input type="checkbox" name="HP"><br>
|
||||||
DMX mode: <input name="DM" type="radio" value="0"> disabled<br>
|
Then, receive <input type="checkbox" name="HO"> On/Off, <input type="checkbox" name="HB"> Brightness, and <input type="checkbox" name="HC"> Color<br>
|
||||||
<input name="DM" type="radio" value="1"> Single RGB (3 Channels for all LEDs: Red Green Blue)<br>
|
Hue Bridge IP:<br>
|
||||||
<input name="DM" type="radio" value="2"> Single DRGB (4 Channels for all LEDs: Dimmer Red Green Blue)<br>
|
<input name="H0" type="number" min="0" max="255" > .
|
||||||
<input name="DM" type="radio" value="3"> Effect (11 Channels parametrizing Effects: Dimmer Effect Speed Intensity Palette PriRed PriGreen PriBlue SecRed SecGreen SecBlue)<br>
|
<input name="H1" type="number" min="0" max="255" > .
|
||||||
<input name="DM" type="radio" value="4"> Multiple RGB (3 Channels for each LED: Red Green Blue)<br>
|
<input name="H2" type="number" min="0" max="255" > .
|
||||||
<input name="DM" type="radio" value="5"> Multiple DRGB (1+3 Channels for each LED: Dimmer Red1 Green1 Blue1 Red2 Green2 Blue2...)<br>
|
<input name="H3" type="number" min="0" max="255" ><br>
|
||||||
<i>Reboot required.</i> Check out <a href="https://github.com/ahodges9/LedFx" target="_blank">LedFx</a>!<br><br>
|
<b>Press the pushlink button on the bridge, after that save this page!</b><br>
|
||||||
Timeout: <input name="ET" type="number" min="100" max="65000" required> ms<br>
|
(when first connecting)<br>
|
||||||
Force max brightness: <input type="checkbox" name="FB"><br>
|
Hue status: <span class="hms"> Disabled in this build </span><hr>
|
||||||
Disable realtime gamma correction: <input type="checkbox" name="RG"><br>
|
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
||||||
Realtime LED offset: <input name="WO" type="number" min="-255" max="255" required>
|
</form>
|
||||||
<h3>Alexa Voice Assistant</h3>
|
|
||||||
Emulate Alexa device: <input type="checkbox" name="AL"><br>
|
|
||||||
Alexa invocation name: <input name="AI" maxlength="32">
|
|
||||||
<h3>Blynk</h3>
|
|
||||||
<b>Blynk, MQTT and Hue sync all connect to external hosts!<br>
|
|
||||||
This may impact the responsiveness of the ESP8266.</b><br>
|
|
||||||
For best results, only use one of these services at a time.<br>
|
|
||||||
(alternatively, connect a second ESP to them and use the UDP sync)<br><br>
|
|
||||||
Device Auth token: <input name="BK" maxlength="33"><br>
|
|
||||||
<i>Clear the token field to disable. </i><a href="https://github.com/Aircoookie/WLED/wiki/Blynk" target="_blank">Setup info</a>
|
|
||||||
<h3>MQTT</h3>
|
|
||||||
Enable MQTT: <input type="checkbox" name="MQ"><br>
|
|
||||||
Broker: <input name="MS" maxlength="32"><br>
|
|
||||||
Port: <input name="MQPORT" type="number" min="1" max="65535"><br>
|
|
||||||
<b>The MQTT credentials are sent over an unsecured connection.<br>
|
|
||||||
Never use the MQTT password for another service!</b><br>
|
|
||||||
Username: <input name="MQTTUSER" maxlength="32"><br>
|
|
||||||
Password: <input type="password" input name="MQTTPASS" maxlength="32"><br>
|
|
||||||
Client ID: <input name="MQTTCID" maxlength="32"><br>
|
|
||||||
Device Topic: <input name="MD" maxlength="32"><br>
|
|
||||||
Group Topic: <input name="MG" maxlength="32"><br>
|
|
||||||
<a href="https://github.com/Aircoookie/WLED/wiki/MQTT" target="_blank">MQTT info</a>
|
|
||||||
<h3>Philips Hue</h3>
|
|
||||||
<i>You can find the bridge IP and the light number in the 'About' section of the hue app.</i><br>
|
|
||||||
Poll Hue light <input name="HL" type="number" min="1" max="99"> every <input name="HI" type="number" min="100" max="65000"> ms: <input type="checkbox" name="HP"><br>
|
|
||||||
Then, receive <input type="checkbox" name="HO"> On/Off, <input type="checkbox" name="HB"> Brightness, and <input type="checkbox" name="HC"> Color<br>
|
|
||||||
Hue Bridge IP:<br>
|
|
||||||
<input name="H0" type="number" min="0" max="255"> .
|
|
||||||
<input name="H1" type="number" min="0" max="255"> .
|
|
||||||
<input name="H2" type="number" min="0" max="255"> .
|
|
||||||
<input name="H3" type="number" min="0" max="255"><br>
|
|
||||||
<b>Press the pushlink button on the bridge, after that save this page!</b><br>
|
|
||||||
(when first connecting)<br>
|
|
||||||
Hue status: <span class="hms"> Internal ESP Error! </span><hr>
|
|
||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
|
||||||
</form>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -4,29 +4,45 @@
|
|||||||
* E1.31 handler
|
* E1.31 handler
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void handleE131Packet(e131_packet_t* p, IPAddress clientIP){
|
void handleE131Packet(e131_packet_t* p, IPAddress clientIP, bool isArtnet){
|
||||||
//E1.31 protocol support
|
//E1.31 protocol support
|
||||||
|
|
||||||
uint16_t uni = htons(p->universe);
|
uint16_t uni = 0, dmxChannels = 0;
|
||||||
uint8_t previousUniverses = uni - e131Universe;
|
uint8_t* e131_data = nullptr;
|
||||||
uint16_t possibleLEDsInCurrentUniverse;
|
uint8_t seq = 0, mde = REALTIME_MODE_E131;
|
||||||
uint16_t dmxChannels = htons(p->property_value_count) -1;
|
|
||||||
|
if (isArtnet)
|
||||||
|
{
|
||||||
|
uni = p->art_universe;
|
||||||
|
dmxChannels = htons(p->art_length);
|
||||||
|
e131_data = p->art_data;
|
||||||
|
seq = p->art_sequence_number;
|
||||||
|
mde = REALTIME_MODE_ARTNET;
|
||||||
|
} else {
|
||||||
|
uni = htons(p->universe);
|
||||||
|
dmxChannels = htons(p->property_value_count) -1;
|
||||||
|
e131_data = p->property_values;
|
||||||
|
seq = p->sequence_number;
|
||||||
|
}
|
||||||
|
|
||||||
// only listen for universes we're handling & allocated memory
|
// only listen for universes we're handling & allocated memory
|
||||||
if (uni >= (e131Universe + E131_MAX_UNIVERSE_COUNT)) return;
|
if (uni >= (e131Universe + E131_MAX_UNIVERSE_COUNT)) return;
|
||||||
|
|
||||||
|
uint8_t previousUniverses = uni - e131Universe;
|
||||||
|
uint16_t possibleLEDsInCurrentUniverse;
|
||||||
|
|
||||||
if (e131SkipOutOfSequence)
|
if (e131SkipOutOfSequence)
|
||||||
if (p->sequence_number < e131LastSequenceNumber[uni-e131Universe] && p->sequence_number > 20 && e131LastSequenceNumber[uni-e131Universe] < 250){
|
if (seq < e131LastSequenceNumber[uni-e131Universe] && seq > 20 && e131LastSequenceNumber[uni-e131Universe] < 250){
|
||||||
DEBUG_PRINT("skipping E1.31 frame (last seq=");
|
DEBUG_PRINT("skipping E1.31 frame (last seq=");
|
||||||
DEBUG_PRINT(e131LastSequenceNumber[uni-e131Universe]);
|
DEBUG_PRINT(e131LastSequenceNumber[uni-e131Universe]);
|
||||||
DEBUG_PRINT(", current seq=");
|
DEBUG_PRINT(", current seq=");
|
||||||
DEBUG_PRINT(p->sequence_number);
|
DEBUG_PRINT(seq);
|
||||||
DEBUG_PRINT(", universe=");
|
DEBUG_PRINT(", universe=");
|
||||||
DEBUG_PRINT(uni);
|
DEBUG_PRINT(uni);
|
||||||
DEBUG_PRINTLN(")");
|
DEBUG_PRINTLN(")");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
e131LastSequenceNumber[uni-e131Universe] = p->sequence_number;
|
e131LastSequenceNumber[uni-e131Universe] = seq;
|
||||||
|
|
||||||
// update status info
|
// update status info
|
||||||
realtimeIP = clientIP;
|
realtimeIP = clientIP;
|
||||||
@ -39,46 +55,46 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP){
|
|||||||
case DMX_MODE_SINGLE_RGB:
|
case DMX_MODE_SINGLE_RGB:
|
||||||
if (uni != e131Universe) return;
|
if (uni != e131Universe) return;
|
||||||
if (dmxChannels-DMXAddress+1 < 3) return;
|
if (dmxChannels-DMXAddress+1 < 3) return;
|
||||||
arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131);
|
realtimeLock(realtimeTimeoutMs, mde);
|
||||||
for (uint16_t i = 0; i < ledCount; i++)
|
for (uint16_t i = 0; i < ledCount; i++)
|
||||||
setRealtimePixel(i, p->property_values[DMXAddress+0], p->property_values[DMXAddress+1], p->property_values[DMXAddress+2], 0);
|
setRealtimePixel(i, e131_data[DMXAddress+0], e131_data[DMXAddress+1], e131_data[DMXAddress+2], 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DMX_MODE_SINGLE_DRGB:
|
case DMX_MODE_SINGLE_DRGB:
|
||||||
if (uni != e131Universe) return;
|
if (uni != e131Universe) return;
|
||||||
if (dmxChannels-DMXAddress+1 < 4) return;
|
if (dmxChannels-DMXAddress+1 < 4) return;
|
||||||
arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131);
|
realtimeLock(realtimeTimeoutMs, mde);
|
||||||
if (DMXOldDimmer != p->property_values[DMXAddress+0]) {
|
if (DMXOldDimmer != e131_data[DMXAddress+0]) {
|
||||||
DMXOldDimmer = p->property_values[DMXAddress+0];
|
DMXOldDimmer = e131_data[DMXAddress+0];
|
||||||
bri = p->property_values[DMXAddress+0];
|
bri = e131_data[DMXAddress+0];
|
||||||
strip.setBrightness(bri);
|
strip.setBrightness(bri);
|
||||||
}
|
}
|
||||||
for (uint16_t i = 0; i < ledCount; i++)
|
for (uint16_t i = 0; i < ledCount; i++)
|
||||||
setRealtimePixel(i, p->property_values[DMXAddress+1], p->property_values[DMXAddress+2], p->property_values[DMXAddress+3], 0);
|
setRealtimePixel(i, e131_data[DMXAddress+1], e131_data[DMXAddress+2], e131_data[DMXAddress+3], 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DMX_MODE_EFFECT:
|
case DMX_MODE_EFFECT:
|
||||||
if (uni != e131Universe) return;
|
if (uni != e131Universe) return;
|
||||||
if (dmxChannels-DMXAddress+1 < 11) return;
|
if (dmxChannels-DMXAddress+1 < 11) return;
|
||||||
if (DMXOldDimmer != p->property_values[DMXAddress+0]) {
|
if (DMXOldDimmer != e131_data[DMXAddress+0]) {
|
||||||
DMXOldDimmer = p->property_values[DMXAddress+0];
|
DMXOldDimmer = e131_data[DMXAddress+0];
|
||||||
bri = p->property_values[DMXAddress+0];
|
bri = e131_data[DMXAddress+0];
|
||||||
}
|
}
|
||||||
if (p->property_values[DMXAddress+1] < MODE_COUNT)
|
if (e131_data[DMXAddress+1] < MODE_COUNT)
|
||||||
effectCurrent = p->property_values[DMXAddress+ 1];
|
effectCurrent = e131_data[DMXAddress+ 1];
|
||||||
effectSpeed = p->property_values[DMXAddress+ 2]; // flickers
|
effectSpeed = e131_data[DMXAddress+ 2]; // flickers
|
||||||
effectIntensity = p->property_values[DMXAddress+ 3];
|
effectIntensity = e131_data[DMXAddress+ 3];
|
||||||
effectPalette = p->property_values[DMXAddress+ 4];
|
effectPalette = e131_data[DMXAddress+ 4];
|
||||||
col[0] = p->property_values[DMXAddress+ 5];
|
col[0] = e131_data[DMXAddress+ 5];
|
||||||
col[1] = p->property_values[DMXAddress+ 6];
|
col[1] = e131_data[DMXAddress+ 6];
|
||||||
col[2] = p->property_values[DMXAddress+ 7];
|
col[2] = e131_data[DMXAddress+ 7];
|
||||||
colSec[0] = p->property_values[DMXAddress+ 8];
|
colSec[0] = e131_data[DMXAddress+ 8];
|
||||||
colSec[1] = p->property_values[DMXAddress+ 9];
|
colSec[1] = e131_data[DMXAddress+ 9];
|
||||||
colSec[2] = p->property_values[DMXAddress+10];
|
colSec[2] = e131_data[DMXAddress+10];
|
||||||
if (dmxChannels-DMXAddress+1 > 11)
|
if (dmxChannels-DMXAddress+1 > 11)
|
||||||
{
|
{
|
||||||
col[3] = p->property_values[DMXAddress+11]; //white
|
col[3] = e131_data[DMXAddress+11]; //white
|
||||||
colSec[3] = p->property_values[DMXAddress+12];
|
colSec[3] = e131_data[DMXAddress+12];
|
||||||
}
|
}
|
||||||
transitionDelayTemp = 0; // act fast
|
transitionDelayTemp = 0; // act fast
|
||||||
colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); // don't send UDP
|
colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); // don't send UDP
|
||||||
@ -86,13 +102,13 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP){
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DMX_MODE_MULTIPLE_RGB:
|
case DMX_MODE_MULTIPLE_RGB:
|
||||||
arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131);
|
realtimeLock(realtimeTimeoutMs, mde);
|
||||||
if (previousUniverses == 0) {
|
if (previousUniverses == 0) {
|
||||||
// first universe of this fixture
|
// first universe of this fixture
|
||||||
possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress + 1) / 3;
|
possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress + 1) / 3;
|
||||||
for (uint16_t i = 0; i < ledCount; i++) {
|
for (uint16_t i = 0; i < ledCount; i++) {
|
||||||
if (i >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s)
|
if (i >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s)
|
||||||
setRealtimePixel(i, p->property_values[DMXAddress+i*3+0], p->property_values[DMXAddress+i*3+1], p->property_values[DMXAddress+i*3+2], 0);
|
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)) {
|
} else if (previousUniverses > 0 && uni < (e131Universe + E131_MAX_UNIVERSE_COUNT)) {
|
||||||
// additional universe(s) of this fixture
|
// additional universe(s) of this fixture
|
||||||
@ -102,24 +118,24 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP){
|
|||||||
for (uint16_t i = numberOfLEDsInPreviousUniverses; i < ledCount; i++) {
|
for (uint16_t i = numberOfLEDsInPreviousUniverses; i < ledCount; i++) {
|
||||||
uint8_t j = i - numberOfLEDsInPreviousUniverses;
|
uint8_t j = i - numberOfLEDsInPreviousUniverses;
|
||||||
if (j >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s)
|
if (j >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s)
|
||||||
setRealtimePixel(i, p->property_values[j*3+1], p->property_values[j*3+2], p->property_values[j*3+3], 0);
|
setRealtimePixel(i, e131_data[j*3+1], e131_data[j*3+2], e131_data[j*3+3], 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DMX_MODE_MULTIPLE_DRGB:
|
case DMX_MODE_MULTIPLE_DRGB:
|
||||||
arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131);
|
realtimeLock(realtimeTimeoutMs, mde);
|
||||||
if (previousUniverses == 0) {
|
if (previousUniverses == 0) {
|
||||||
// first universe of this fixture
|
// first universe of this fixture
|
||||||
if (DMXOldDimmer != p->property_values[DMXAddress+0]) {
|
if (DMXOldDimmer != e131_data[DMXAddress+0]) {
|
||||||
DMXOldDimmer = p->property_values[DMXAddress+0];
|
DMXOldDimmer = e131_data[DMXAddress+0];
|
||||||
bri = p->property_values[DMXAddress+0];
|
bri = e131_data[DMXAddress+0];
|
||||||
strip.setBrightness(bri);
|
strip.setBrightness(bri);
|
||||||
}
|
}
|
||||||
possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress) / 3;
|
possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress) / 3;
|
||||||
for (uint16_t i = 0; i < ledCount; i++) {
|
for (uint16_t i = 0; i < ledCount; i++) {
|
||||||
if (i >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s)
|
if (i >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s)
|
||||||
setRealtimePixel(i, p->property_values[DMXAddress+i*3+1], p->property_values[DMXAddress+i*3+2], p->property_values[DMXAddress+i*3+3], 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)) {
|
} else if (previousUniverses > 0 && uni < (e131Universe + E131_MAX_UNIVERSE_COUNT)) {
|
||||||
// additional universe(s) of this fixture
|
// additional universe(s) of this fixture
|
||||||
@ -129,7 +145,7 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP){
|
|||||||
for (uint16_t i = numberOfLEDsInPreviousUniverses; i < ledCount; i++) {
|
for (uint16_t i = numberOfLEDsInPreviousUniverses; i < ledCount; i++) {
|
||||||
uint8_t j = i - numberOfLEDsInPreviousUniverses;
|
uint8_t j = i - numberOfLEDsInPreviousUniverses;
|
||||||
if (j >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s)
|
if (j >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s)
|
||||||
setRealtimePixel(i, p->property_values[j*3+1], p->property_values[j*3+2], p->property_values[j*3+3], 0);
|
setRealtimePixel(i, e131_data[j*3+1], e131_data[j*3+2], e131_data[j*3+3], 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -42,7 +42,7 @@ void initDMX();
|
|||||||
void handleDMX();
|
void handleDMX();
|
||||||
|
|
||||||
//e131.cpp
|
//e131.cpp
|
||||||
void handleE131Packet(e131_packet_t* p, IPAddress clientIP);
|
void handleE131Packet(e131_packet_t* p, IPAddress clientIP, bool isArtnet);
|
||||||
|
|
||||||
//file.cpp
|
//file.cpp
|
||||||
bool handleFileRead(AsyncWebServerRequest*, String path);
|
bool handleFileRead(AsyncWebServerRequest*, String path);
|
||||||
@ -103,12 +103,6 @@ void handleNightlight();
|
|||||||
bool initMqtt();
|
bool initMqtt();
|
||||||
void publishMqtt();
|
void publishMqtt();
|
||||||
|
|
||||||
//notify.cpp
|
|
||||||
void notify(byte callMode, bool followUp=false);
|
|
||||||
void arlsLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC);
|
|
||||||
void handleNotifications();
|
|
||||||
void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w);
|
|
||||||
|
|
||||||
//ntp.cpp
|
//ntp.cpp
|
||||||
void handleNetworkTime();
|
void handleNetworkTime();
|
||||||
void sendNTPPacket();
|
void sendNTPPacket();
|
||||||
@ -140,6 +134,12 @@ bool handleSet(AsyncWebServerRequest *request, const String& req);
|
|||||||
int getNumVal(const String* req, uint16_t pos);
|
int getNumVal(const String* req, uint16_t pos);
|
||||||
bool updateVal(const String* req, const char* key, byte* val, byte minv=0, byte maxv=255);
|
bool updateVal(const String* req, const char* key, byte* val, byte minv=0, byte maxv=255);
|
||||||
|
|
||||||
|
//udp.cpp
|
||||||
|
void notify(byte callMode, bool followUp=false);
|
||||||
|
void realtimeLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC);
|
||||||
|
void handleNotifications();
|
||||||
|
void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w);
|
||||||
|
|
||||||
//usermod.cpp
|
//usermod.cpp
|
||||||
void userSetup();
|
void userSetup();
|
||||||
void userConnected();
|
void userConnected();
|
||||||
|
@ -252,16 +252,16 @@ Sync button toggles both send and receive: <input type="checkbox" name="ST"><br>
|
|||||||
|
|
||||||
//sync settings
|
//sync settings
|
||||||
const char PAGE_settings_sync[] PROGMEM = R"=====(<!DOCTYPE html>
|
const char PAGE_settings_sync[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||||
<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>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#sync-settings");}function B(){window.open("/settings","_self");}function GetV(){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 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}}}}function SP(){var a=d.Sf.DI.value;d.getElementById("xp").style.display=(a>0)?"none":"block";if(a>0){d.Sf.EP.value=a}}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 S(){GetV();SetVal()};function GetV(){
|
||||||
%CSS%%SCSS%</head>
|
%CSS%%SCSS%</head>
|
||||||
<body onload="GetV()">
|
<body onload=S()>
|
||||||
<form id="form_s" name="Sf" method="post">
|
<form id=form_s name=Sf method=post>
|
||||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
<div class=helpB><button type=button onclick=H()>?</button></div>
|
||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
<button type=button onclick=B()>Back</button><button type=submit>Save</button><hr>
|
||||||
<h2>Sync setup</h2>
|
<h2>Sync setup</h2>
|
||||||
<h3>Button setup</h3>
|
<h3>Button setup</h3>
|
||||||
On/Off button enabled: <input type="checkbox" name="BT"><br>
|
On/Off button enabled: <input type=checkbox name=BT><br>
|
||||||
Infrared remote:
|
Infrared remote:
|
||||||
<select name=IR>
|
<select name=IR>
|
||||||
<option value=0>Disabled</option>
|
<option value=0>Disabled</option>
|
||||||
@ -272,24 +272,31 @@ Infrared remote:
|
|||||||
<option value=5>21-key RGB</option>
|
<option value=5>21-key RGB</option>
|
||||||
<option value=6>6-key black</option>
|
<option value=6>6-key black</option>
|
||||||
</select><br>
|
</select><br>
|
||||||
<a href="https://github.com/Aircoookie/WLED/wiki/Infrared-Control" target="_blank">IR info</a>
|
<a href=https://github.com/Aircoookie/WLED/wiki/Infrared-Control target=_blank>IR info</a>
|
||||||
<h3>WLED Broadcast</h3>
|
<h3>WLED Broadcast</h3>
|
||||||
UDP Port: <input name="UP" type="number" min="1" max="65535" class="d5" required><br>
|
UDP Port: <input name=UP type=number min=1 max=65535 class=d5 required><br>
|
||||||
Receive <input type="checkbox" name="RB">Brightness, <input type="checkbox" name="RC">Color, and <input type="checkbox" name="RX">Effects<br>
|
Receive <input type=checkbox name=RB>Brightness, <input type=checkbox name=RC>Color, and <input type=checkbox name=RX>Effects<br>
|
||||||
Send notifications on direct change: <input type="checkbox" name="SD"><br>
|
Send notifications on direct change: <input type=checkbox name=SD><br>
|
||||||
Send notifications on button press: <input type="checkbox" name="SB"><br>
|
Send notifications on button press: <input type=checkbox name=SB><br>
|
||||||
Send Alexa notifications: <input type="checkbox" name="SA"><br>
|
Send Alexa notifications: <input type=checkbox name=SA><br>
|
||||||
Send Philips Hue change notifications: <input type="checkbox" name="SH"><br>
|
Send Philips Hue change notifications: <input type=checkbox name=SH><br>
|
||||||
Send Macro notifications: <input type="checkbox" name="SM"><br>
|
Send Macro notifications: <input type=checkbox name=SM><br>
|
||||||
Send notifications twice: <input type="checkbox" name="S2">
|
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>Network DMX input</i><br>
|
||||||
Use E1.31 multicast: <input type="checkbox" name="EM"><br>
|
Type:
|
||||||
E1.31 start universe: <input name="EU" type="number" min="1" max="63999" required><br>
|
<select name=DI onchange=SP();adj()>
|
||||||
Skip out-of-sequence packets: <input type="checkbox" name="ES"><br>
|
<option value=5568>E1.31 (sACN)</option>
|
||||||
<i>Reboot required.</i> Check out <a href="https://github.com/ahodges9/LedFx" target="_blank">LedFx</a>!<br>
|
<option value=6454>Art-Net</option>
|
||||||
DMX start address: <input name="DA" type="number" min="1" max="510" value="1" required><br>
|
<option value=0 selected>Custom port</option>
|
||||||
|
</select><br>
|
||||||
|
<div id=xp>Port: <input name=EP type=number min=1 max=65535 value=5568 class=d5 required><br></div>
|
||||||
|
Multicast: <input type=checkbox name=EM><br>
|
||||||
|
Start universe: <input name=EU type=number min=0 max=63999 required><br>
|
||||||
|
<i>Reboot required.</i> Check out <a href=https://github.com/ahodges9/LedFx target=_blank>LedFx</a>!<br>
|
||||||
|
Skip out-of-sequence packets: <input type=checkbox name=ES><br>
|
||||||
|
DMX start address: <input name=DA type=number min=0 max=510 required><br>
|
||||||
DMX mode:
|
DMX mode:
|
||||||
<select name=DM>
|
<select name=DM>
|
||||||
<option value=0>Disabled</option>
|
<option value=0>Disabled</option>
|
||||||
@ -299,49 +306,48 @@ DMX mode:
|
|||||||
<option value=4>Multi RGB</option>
|
<option value=4>Multi RGB</option>
|
||||||
<option value=5>Multi DRGB</option>
|
<option value=5>Multi DRGB</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>
|
||||||
Force max brightness: <input type="checkbox" name="FB"><br>
|
Force max brightness: <input type=checkbox name=FB><br>
|
||||||
Disable realtime gamma correction: <input type="checkbox" name="RG"><br>
|
Disable realtime gamma correction: <input type=checkbox name=RG><br>
|
||||||
Realtime LED offset: <input name="WO" type="number" min="-255" max="255" required>
|
Realtime LED offset: <input name=WO type=number min=-255 max=255 required>
|
||||||
<h3>Alexa Voice Assistant</h3>
|
<h3>Alexa Voice Assistant</h3>
|
||||||
Emulate Alexa device: <input type="checkbox" name="AL"><br>
|
Emulate Alexa device: <input type=checkbox name=AL><br>
|
||||||
Alexa invocation name: <input name="AI" maxlength="32">
|
Alexa invocation name: <input name=AI maxlength=32>
|
||||||
<h3>Blynk</h3>
|
<h3>Blynk</h3>
|
||||||
<b>Blynk, MQTT and Hue sync all connect to external hosts!<br>
|
<b>Blynk, MQTT and Hue sync all connect to external hosts!<br>
|
||||||
This may impact the responsiveness of the ESP8266.</b><br>
|
This may impact the responsiveness of the ESP8266.</b><br>
|
||||||
For best results, only use one of these services at a time.<br>
|
For best results, only use one of these services at a time.<br>
|
||||||
(alternatively, connect a second ESP to them and use the UDP sync)<br><br>
|
(alternatively, connect a second ESP to them and use the UDP sync)<br><br>
|
||||||
Device Auth token: <input name="BK" maxlength="33"><br>
|
Device Auth token: <input name=BK maxlength=33><br>
|
||||||
<i>Clear the token field to disable. </i><a href="https://github.com/Aircoookie/WLED/wiki/Blynk" target="_blank">Setup info</a>
|
<i>Clear the token field to disable. </i><a href=https://github.com/Aircoookie/WLED/wiki/Blynk target=_blank>Setup info</a>
|
||||||
<h3>MQTT</h3>
|
<h3>MQTT</h3>
|
||||||
Enable MQTT: <input type="checkbox" name="MQ"><br>
|
Enable MQTT: <input type=checkbox name=MQ><br>
|
||||||
Broker: <input name="MS" maxlength="32">
|
Broker: <input name=MS maxlength=32>
|
||||||
Port: <input name="MQPORT" type="number" min="1" max="65535" class="d5"><br>
|
Port: <input name=MQPORT type=number min=1 max=65535 class=d5><br>
|
||||||
<b>The MQTT credentials are sent over an unsecured connection.<br>
|
<b>The MQTT credentials are sent over an unsecured connection.<br>
|
||||||
Never use the MQTT password for another service!</b><br>
|
Never use the MQTT password for another service!</b><br>
|
||||||
Username: <input name="MQUSER" maxlength="40"><br>
|
Username: <input name=MQUSER maxlength=40><br>
|
||||||
Password: <input type="password" input name="MQPASS" maxlength="40"><br>
|
Password: <input type=password input name=MQPASS maxlength=40><br>
|
||||||
Client ID: <input name="MQCID" maxlength="40"><br>
|
Client ID: <input name=MQCID maxlength=40><br>
|
||||||
Device Topic: <input name="MD" maxlength="32"><br>
|
Device Topic: <input name=MD maxlength=32><br>
|
||||||
Group Topic: <input name="MG" maxlength="32"><br>
|
Group Topic: <input name=MG maxlength=32><br>
|
||||||
<i>Reboot required to apply changes. </i><a href="https://github.com/Aircoookie/WLED/wiki/MQTT" target="_blank">MQTT info</a>
|
<i>Reboot required to apply changes. </i><a href=https://github.com/Aircoookie/WLED/wiki/MQTT target=_blank>MQTT info</a>
|
||||||
<h3>Philips Hue</h3>
|
<h3>Philips Hue</h3>
|
||||||
<i>You can find the bridge IP and the light number in the 'About' section of the hue app.</i><br>
|
<i>You can find the bridge IP and the light number in the 'About' section of the hue app.</i><br>
|
||||||
Poll Hue light <input name="HL" type="number" min="1" max="99" > every <input name="HI" type="number" min="100" max="65000"> ms: <input type="checkbox" name="HP"><br>
|
Poll Hue light <input name=HL type=number min=1 max=99> every <input name=HI type=number min=100 max=65000> ms: <input type=checkbox name=HP><br>
|
||||||
Then, receive <input type="checkbox" name="HO"> On/Off, <input type="checkbox" name="HB"> Brightness, and <input type="checkbox" name="HC"> Color<br>
|
Then, receive <input type=checkbox name=HO> On/Off, <input type=checkbox name=HB> Brightness, and <input type=checkbox name=HC> Color<br>
|
||||||
Hue Bridge IP:<br>
|
Hue Bridge IP:<br>
|
||||||
<input name="H0" type="number" min="0" max="255" > .
|
<input name=H0 type=number min=0 max=255> .
|
||||||
<input name="H1" type="number" min="0" max="255" > .
|
<input name=H1 type=number min=0 max=255> .
|
||||||
<input name="H2" type="number" min="0" max="255" > .
|
<input name=H2 type=number min=0 max=255> .
|
||||||
<input name="H3" type="number" min="0" max="255" ><br>
|
<input name=H3 type=number min=0 max=255><br>
|
||||||
<b>Press the pushlink button on the bridge, after that save this page!</b><br>
|
<b>Press the pushlink button on the bridge, after that save this page!</b><br>
|
||||||
(when first connecting)<br>
|
(when first connecting)<br>
|
||||||
Hue status: <span class="hms"> Disabled in this build </span><hr>
|
Hue status: <span class=hms> Disabled in this build </span><hr>
|
||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
<button type=button onclick=B()>Back</button><button type=submit>Save</button>
|
||||||
</form>
|
</form>
|
||||||
</body>
|
</body></html>)=====";
|
||||||
</html>)=====";
|
|
||||||
|
|
||||||
|
|
||||||
//time and macro settings
|
//time and macro settings
|
||||||
|
@ -142,10 +142,12 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
receiveDirect = request->hasArg("RD");
|
receiveDirect = request->hasArg("RD");
|
||||||
e131SkipOutOfSequence = request->hasArg("ES");
|
e131SkipOutOfSequence = request->hasArg("ES");
|
||||||
e131Multicast = request->hasArg("EM");
|
e131Multicast = request->hasArg("EM");
|
||||||
|
t = request->arg("EP").toInt();
|
||||||
|
if (t > 0) e131Port = t;
|
||||||
t = request->arg("EU").toInt();
|
t = request->arg("EU").toInt();
|
||||||
if (t > 0 && t <= 63999) e131Universe = t;
|
if (t >= 0 && t <= 63999) e131Universe = t;
|
||||||
t = request->arg("DA").toInt();
|
t = request->arg("DA").toInt();
|
||||||
if (t > 0 && t <= 510) DMXAddress = t;
|
if (t >= 0 && t <= 510) DMXAddress = t;
|
||||||
t = request->arg("DM").toInt();
|
t = request->arg("DM").toInt();
|
||||||
if (t >= DMX_MODE_DISABLED && t <= DMX_MODE_MULTIPLE_DRGB) DMXMode = t;
|
if (t >= DMX_MODE_DISABLED && t <= DMX_MODE_MULTIPLE_DRGB) DMXMode = t;
|
||||||
t = request->arg("ET").toInt();
|
t = request->arg("ET").toInt();
|
||||||
|
@ -23,6 +23,9 @@
|
|||||||
// E1.17 ACN Packet Identifier
|
// E1.17 ACN Packet Identifier
|
||||||
const byte ESPAsyncE131::ACN_ID[12] = { 0x41, 0x53, 0x43, 0x2d, 0x45, 0x31, 0x2e, 0x31, 0x37, 0x00, 0x00, 0x00 };
|
const byte ESPAsyncE131::ACN_ID[12] = { 0x41, 0x53, 0x43, 0x2d, 0x45, 0x31, 0x2e, 0x31, 0x37, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
|
// Art-Net Packet Identifier
|
||||||
|
const byte ESPAsyncE131::ART_ID[8] = { 0x41, 0x72, 0x74, 0x2d, 0x4e, 0x65, 0x74, 0x00 };
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
ESPAsyncE131::ESPAsyncE131(e131_packet_callback_function callback) {
|
ESPAsyncE131::ESPAsyncE131(e131_packet_callback_function callback) {
|
||||||
_callback = callback;
|
_callback = callback;
|
||||||
@ -34,13 +37,14 @@ ESPAsyncE131::ESPAsyncE131(e131_packet_callback_function callback) {
|
|||||||
//
|
//
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool ESPAsyncE131::begin(e131_listen_t type, uint16_t universe, uint8_t n) {
|
bool ESPAsyncE131::begin(bool multicast, uint16_t port, uint16_t universe, uint8_t n) {
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
if (type == E131_UNICAST)
|
if (multicast) {
|
||||||
success = initUnicast();
|
success = initMulticast(port, universe, n);
|
||||||
if (type == E131_MULTICAST)
|
} else {
|
||||||
success = initMulticast(universe, n);
|
success = initUnicast(port);
|
||||||
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
@ -51,10 +55,10 @@ bool ESPAsyncE131::begin(e131_listen_t type, uint16_t universe, uint8_t n) {
|
|||||||
//
|
//
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool ESPAsyncE131::initUnicast() {
|
bool ESPAsyncE131::initUnicast(uint16_t port) {
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
if (udp.listen(E131_DEFAULT_PORT)) {
|
if (udp.listen(port)) {
|
||||||
udp.onPacket(std::bind(&ESPAsyncE131::parsePacket, this,
|
udp.onPacket(std::bind(&ESPAsyncE131::parsePacket, this,
|
||||||
std::placeholders::_1));
|
std::placeholders::_1));
|
||||||
success = true;
|
success = true;
|
||||||
@ -62,13 +66,13 @@ bool ESPAsyncE131::initUnicast() {
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ESPAsyncE131::initMulticast(uint16_t universe, uint8_t n) {
|
bool ESPAsyncE131::initMulticast(uint16_t port, uint16_t universe, uint8_t n) {
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
IPAddress address = IPAddress(239, 255, ((universe >> 8) & 0xff),
|
IPAddress address = IPAddress(239, 255, ((universe >> 8) & 0xff),
|
||||||
((universe >> 0) & 0xff));
|
((universe >> 0) & 0xff));
|
||||||
|
|
||||||
if (udp.listenMulticast(address, E131_DEFAULT_PORT)) {
|
if (udp.listenMulticast(address, port)) {
|
||||||
ip4_addr_t ifaddr;
|
ip4_addr_t ifaddr;
|
||||||
ip4_addr_t multicast_addr;
|
ip4_addr_t multicast_addr;
|
||||||
|
|
||||||
@ -95,22 +99,31 @@ bool ESPAsyncE131::initMulticast(uint16_t universe, uint8_t n) {
|
|||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void ESPAsyncE131::parsePacket(AsyncUDPPacket _packet) {
|
void ESPAsyncE131::parsePacket(AsyncUDPPacket _packet) {
|
||||||
e131_error_t error = ERROR_NONE;
|
bool error = false, isArtnet = false;
|
||||||
|
|
||||||
sbuff = reinterpret_cast<e131_packet_t *>(_packet.data());
|
sbuff = reinterpret_cast<e131_packet_t *>(_packet.data());
|
||||||
|
|
||||||
|
//E1.31 packet identifier ("ACS-E1.17")
|
||||||
if (memcmp(sbuff->acn_id, ESPAsyncE131::ACN_ID, sizeof(sbuff->acn_id)))
|
if (memcmp(sbuff->acn_id, ESPAsyncE131::ACN_ID, sizeof(sbuff->acn_id)))
|
||||||
error = ERROR_ACN_ID;
|
isArtnet = true; //not E1.31
|
||||||
if (htonl(sbuff->root_vector) != ESPAsyncE131::VECTOR_ROOT)
|
|
||||||
error = ERROR_VECTOR_ROOT;
|
if (isArtnet) {
|
||||||
if (htonl(sbuff->frame_vector) != ESPAsyncE131::VECTOR_FRAME)
|
if (memcmp(sbuff->art_id, ESPAsyncE131::ART_ID, sizeof(sbuff->art_id)))
|
||||||
error = ERROR_VECTOR_FRAME;
|
error = true; //not "Art-Net"
|
||||||
if (sbuff->dmp_vector != ESPAsyncE131::VECTOR_DMP)
|
if (sbuff->art_opcode != ARTNET_OPCODE_OPDMX)
|
||||||
error = ERROR_VECTOR_DMP;
|
error = true; //not a DMX packet
|
||||||
if (sbuff->property_values[0] != 0)
|
} else { //E1.31 error handling
|
||||||
error = ERROR_IGNORE;
|
if (htonl(sbuff->root_vector) != ESPAsyncE131::VECTOR_ROOT)
|
||||||
|
error = true;
|
||||||
|
if (htonl(sbuff->frame_vector) != ESPAsyncE131::VECTOR_FRAME)
|
||||||
|
error = true;
|
||||||
|
if (sbuff->dmp_vector != ESPAsyncE131::VECTOR_DMP)
|
||||||
|
error = true;
|
||||||
|
if (sbuff->property_values[0] != 0)
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!error) {
|
if (!error) {
|
||||||
_callback(sbuff, _packet.remoteIP());
|
_callback(sbuff, _packet.remoteIP(), isArtnet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -14,9 +14,12 @@
|
|||||||
* Author shall not be liable in any event for incidental or consequential
|
* Author shall not be liable in any event for incidental or consequential
|
||||||
* damages in connection with, or arising out of, the furnishing, performance
|
* damages in connection with, or arising out of, the furnishing, performance
|
||||||
* or use of these programs.
|
* or use of these programs.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Inspired by https://github.com/hideakitai/ArtNet for ArtNet support
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef ESPASYNCE131_H_
|
#ifndef ESPASYNCE131_H_
|
||||||
#define ESPASYNCE131_H_
|
#define ESPASYNCE131_H_
|
||||||
|
|
||||||
@ -40,7 +43,10 @@ typedef struct ip_addr ip4_addr_t;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Defaults
|
// Defaults
|
||||||
#define E131_DEFAULT_PORT 5568
|
#define E131_DEFAULT_PORT 5568
|
||||||
|
#define ARTNET_DEFAULT_PORT 6454
|
||||||
|
|
||||||
|
#define ARTNET_OPCODE_OPDMX 0x5000
|
||||||
|
|
||||||
// E1.31 Packet Offsets
|
// E1.31 Packet Offsets
|
||||||
#define E131_ROOT_PREAMBLE_SIZE 0
|
#define E131_ROOT_PREAMBLE_SIZE 0
|
||||||
@ -69,7 +75,7 @@ typedef struct ip_addr ip4_addr_t;
|
|||||||
|
|
||||||
// E1.31 Packet Structure
|
// E1.31 Packet Structure
|
||||||
typedef union {
|
typedef union {
|
||||||
struct {
|
struct { //E1.31 packet
|
||||||
// Root Layer
|
// Root Layer
|
||||||
uint16_t preamble_size;
|
uint16_t preamble_size;
|
||||||
uint16_t postamble_size;
|
uint16_t postamble_size;
|
||||||
@ -97,34 +103,30 @@ typedef union {
|
|||||||
uint16_t property_value_count;
|
uint16_t property_value_count;
|
||||||
uint8_t property_values[513];
|
uint8_t property_values[513];
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct { //Art-Net packet
|
||||||
|
uint8_t art_id[8];
|
||||||
|
uint16_t art_opcode;
|
||||||
|
uint16_t art_protocol_ver;
|
||||||
|
uint8_t art_sequence_number;
|
||||||
|
uint8_t art_physical;
|
||||||
|
uint16_t art_universe;
|
||||||
|
uint16_t art_length;
|
||||||
|
|
||||||
|
uint8_t art_data[512];
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
uint8_t raw[638];
|
uint8_t raw[638];
|
||||||
} e131_packet_t;
|
} e131_packet_t;
|
||||||
|
|
||||||
// Error Types
|
|
||||||
typedef enum {
|
|
||||||
ERROR_NONE,
|
|
||||||
ERROR_IGNORE,
|
|
||||||
ERROR_ACN_ID,
|
|
||||||
ERROR_PACKET_SIZE,
|
|
||||||
ERROR_VECTOR_ROOT,
|
|
||||||
ERROR_VECTOR_FRAME,
|
|
||||||
ERROR_VECTOR_DMP
|
|
||||||
} e131_error_t;
|
|
||||||
|
|
||||||
// E1.31 Listener Types
|
|
||||||
typedef enum {
|
|
||||||
E131_UNICAST,
|
|
||||||
E131_MULTICAST
|
|
||||||
} e131_listen_t;
|
|
||||||
|
|
||||||
// new packet callback
|
// new packet callback
|
||||||
typedef void (*e131_packet_callback_function) (e131_packet_t* p, IPAddress clientIP);
|
typedef void (*e131_packet_callback_function) (e131_packet_t* p, IPAddress clientIP, bool isArtnet);
|
||||||
|
|
||||||
class ESPAsyncE131 {
|
class ESPAsyncE131 {
|
||||||
private:
|
private:
|
||||||
// Constants for packet validation
|
// Constants for packet validation
|
||||||
static const uint8_t ACN_ID[];
|
static const uint8_t ACN_ID[];
|
||||||
|
static const uint8_t ART_ID[];
|
||||||
static const uint32_t VECTOR_ROOT = 4;
|
static const uint32_t VECTOR_ROOT = 4;
|
||||||
static const uint32_t VECTOR_FRAME = 2;
|
static const uint32_t VECTOR_FRAME = 2;
|
||||||
static const uint8_t VECTOR_DMP = 2;
|
static const uint8_t VECTOR_DMP = 2;
|
||||||
@ -133,8 +135,8 @@ class ESPAsyncE131 {
|
|||||||
AsyncUDP udp; // AsyncUDP
|
AsyncUDP udp; // AsyncUDP
|
||||||
|
|
||||||
// Internal Initializers
|
// Internal Initializers
|
||||||
bool initUnicast();
|
bool initUnicast(uint16_t port);
|
||||||
bool initMulticast(uint16_t universe, uint8_t n = 1);
|
bool initMulticast(uint16_t port, uint16_t universe, uint8_t n = 1);
|
||||||
|
|
||||||
// Packet parser callback
|
// Packet parser callback
|
||||||
void parsePacket(AsyncUDPPacket _packet);
|
void parsePacket(AsyncUDPPacket _packet);
|
||||||
@ -145,7 +147,7 @@ class ESPAsyncE131 {
|
|||||||
ESPAsyncE131(e131_packet_callback_function callback);
|
ESPAsyncE131(e131_packet_callback_function callback);
|
||||||
|
|
||||||
// Generic UDP listener, no physical or IP configuration
|
// Generic UDP listener, no physical or IP configuration
|
||||||
bool begin(e131_listen_t type, uint16_t universe = 1, uint8_t n = 1);
|
bool begin(bool multicast, uint16_t port = E131_DEFAULT_PORT, uint16_t universe = 1, uint8_t n = 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ESPASYNCE131_H_
|
#endif // ESPASYNCE131_H_
|
@ -72,7 +72,7 @@ void notify(byte callMode, bool followUp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void arlsLock(uint32_t timeoutMs, byte md)
|
void realtimeLock(uint32_t timeoutMs, byte md)
|
||||||
{
|
{
|
||||||
if (!realtimeMode){
|
if (!realtimeMode){
|
||||||
for (uint16_t i = 0; i < ledCount; i++)
|
for (uint16_t i = 0; i < ledCount; i++)
|
||||||
@ -121,7 +121,7 @@ void handleNotifications()
|
|||||||
DEBUG_PRINTLN(rgbUdp.remoteIP());
|
DEBUG_PRINTLN(rgbUdp.remoteIP());
|
||||||
uint8_t lbuf[packetSize];
|
uint8_t lbuf[packetSize];
|
||||||
rgbUdp.read(lbuf, packetSize);
|
rgbUdp.read(lbuf, packetSize);
|
||||||
arlsLock(realtimeTimeoutMs, REALTIME_MODE_HYPERION);
|
realtimeLock(realtimeTimeoutMs, REALTIME_MODE_HYPERION);
|
||||||
uint16_t id = 0;
|
uint16_t id = 0;
|
||||||
for (uint16_t i = 0; i < packetSize -2; i += 3)
|
for (uint16_t i = 0; i < packetSize -2; i += 3)
|
||||||
{
|
{
|
||||||
@ -208,7 +208,7 @@ void handleNotifications()
|
|||||||
realtimeTimeout = 0;
|
realtimeTimeout = 0;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
arlsLock(udpIn[1]*1000 +1, REALTIME_MODE_UDP);
|
realtimeLock(udpIn[1]*1000 +1, REALTIME_MODE_UDP);
|
||||||
}
|
}
|
||||||
if (udpIn[0] == 1) //warls
|
if (udpIn[0] == 1) //warls
|
||||||
{
|
{
|
||||||
|
@ -371,7 +371,7 @@ void WLED::initInterfaces()
|
|||||||
ntpConnected = ntpUdp.begin(ntpLocalPort);
|
ntpConnected = ntpUdp.begin(ntpLocalPort);
|
||||||
|
|
||||||
initBlynk(blynkApiKey);
|
initBlynk(blynkApiKey);
|
||||||
e131.begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST, e131Universe, E131_MAX_UNIVERSE_COUNT);
|
e131.begin(e131Multicast, e131Port, e131Universe, E131_MAX_UNIVERSE_COUNT);
|
||||||
reconnectHue();
|
reconnectHue();
|
||||||
initMqtt();
|
initMqtt();
|
||||||
interfacesInited = true;
|
interfacesInited = true;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// version code in format yymmddb (b = daily build)
|
// version code in format yymmddb (b = daily build)
|
||||||
#define VERSION 2004100
|
#define VERSION 2004120
|
||||||
|
|
||||||
// ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS).
|
// ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS).
|
||||||
|
|
||||||
@ -227,6 +227,7 @@ WLED_GLOBAL bool arlsDisableGammaCorrection _INIT(true); // activate if
|
|||||||
WLED_GLOBAL bool arlsForceMaxBri _INIT(false); // enable to force max brightness if source has very dark colors that would be black
|
WLED_GLOBAL bool arlsForceMaxBri _INIT(false); // enable to force max brightness if source has very dark colors that would be black
|
||||||
|
|
||||||
WLED_GLOBAL uint16_t e131Universe _INIT(1); // settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes)
|
WLED_GLOBAL uint16_t e131Universe _INIT(1); // settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes)
|
||||||
|
WLED_GLOBAL uint16_t e131Port _INIT(5568); // DMX in port. E1.31 default is 5568, Art-Net is 6454
|
||||||
WLED_GLOBAL byte DMXMode _INIT(DMX_MODE_MULTIPLE_RGB); // DMX mode (s.a.)
|
WLED_GLOBAL byte DMXMode _INIT(DMX_MODE_MULTIPLE_RGB); // DMX mode (s.a.)
|
||||||
WLED_GLOBAL uint16_t DMXAddress _INIT(1); // DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol]
|
WLED_GLOBAL uint16_t DMXAddress _INIT(1); // DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol]
|
||||||
WLED_GLOBAL byte DMXOldDimmer _INIT(0); // only update brightness on change
|
WLED_GLOBAL byte DMXOldDimmer _INIT(0); // only update brightness on change
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//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 18
|
#define EEPVER 19
|
||||||
//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
|
||||||
@ -27,6 +27,7 @@
|
|||||||
//16-> 0.9.1
|
//16-> 0.9.1
|
||||||
//17-> 0.9.1-dmx
|
//17-> 0.9.1-dmx
|
||||||
//18-> 0.9.1-e131
|
//18-> 0.9.1-e131
|
||||||
|
//19-> 0.9.1n
|
||||||
|
|
||||||
void commit()
|
void commit()
|
||||||
{
|
{
|
||||||
@ -210,6 +211,9 @@ void saveSettingsToEEPROM()
|
|||||||
EEPROM.write(2181, macroNl);
|
EEPROM.write(2181, macroNl);
|
||||||
EEPROM.write(2182, macroDoublePress);
|
EEPROM.write(2182, macroDoublePress);
|
||||||
|
|
||||||
|
EEPROM.write(2187, e131Port & 0xFF);
|
||||||
|
EEPROM.write(2188, (e131Port >> 8) & 0xFF);
|
||||||
|
|
||||||
EEPROM.write(2189, e131SkipOutOfSequence);
|
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);
|
||||||
@ -515,6 +519,11 @@ void loadSettingsFromEEPROM(bool first)
|
|||||||
e131SkipOutOfSequence = true;
|
e131SkipOutOfSequence = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lastEEPROMversion > 18)
|
||||||
|
{
|
||||||
|
e131Port = EEPROM.read(2187) + ((EEPROM.read(2188) << 8) & 0xFF00);
|
||||||
|
}
|
||||||
|
|
||||||
receiveDirect = !EEPROM.read(2200);
|
receiveDirect = !EEPROM.read(2200);
|
||||||
notifyMacro = EEPROM.read(2201);
|
notifyMacro = EEPROM.read(2201);
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ void handleSerial()
|
|||||||
if (--count > 0) state = AdaState::Data_Red;
|
if (--count > 0) state = AdaState::Data_Red;
|
||||||
else {
|
else {
|
||||||
if (!realtimeMode && bri == 0) strip.setBrightness(briLast);
|
if (!realtimeMode && bri == 0) strip.setBrightness(briLast);
|
||||||
arlsLock(realtimeTimeoutMs, REALTIME_MODE_ADALIGHT);
|
realtimeLock(realtimeTimeoutMs, REALTIME_MODE_ADALIGHT);
|
||||||
|
|
||||||
strip.show();
|
strip.show();
|
||||||
state = AdaState::Header_A;
|
state = AdaState::Header_A;
|
||||||
|
@ -63,9 +63,10 @@ char* XML_response(AsyncWebServerRequest *request, char* dest)
|
|||||||
if (realtimeMode)
|
if (realtimeMode)
|
||||||
{
|
{
|
||||||
String mesg = "Live ";
|
String mesg = "Live ";
|
||||||
if (realtimeMode == REALTIME_MODE_E131)
|
if (realtimeMode == REALTIME_MODE_E131 || realtimeMode == REALTIME_MODE_ARTNET)
|
||||||
{
|
{
|
||||||
mesg += "E1.31 mode ";
|
mesg += (realtimeMode == REALTIME_MODE_E131) ? "E1.31" : "Art-Net";
|
||||||
|
mesg += " mode ";
|
||||||
mesg += DMXMode;
|
mesg += DMXMode;
|
||||||
mesg += F(" at DMX Address ");
|
mesg += F(" at DMX Address ");
|
||||||
mesg += DMXAddress;
|
mesg += DMXAddress;
|
||||||
@ -326,6 +327,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('v',"EP",e131Port);
|
||||||
sappend('c',"ES",e131SkipOutOfSequence);
|
sappend('c',"ES",e131SkipOutOfSequence);
|
||||||
sappend('c',"EM",e131Multicast);
|
sappend('c',"EM",e131Multicast);
|
||||||
sappend('v',"EU",e131Universe);
|
sappend('v',"EU",e131Universe);
|
||||||
|
Loading…
Reference in New Issue
Block a user