From 1d4d8852769fea56f9d3c4a2037b8f42eb0fffc3 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Sat, 11 Aug 2018 22:57:13 +0200 Subject: [PATCH] Release of WLED 0.7.1 to dev branch Added E1.31 support Added more realtime options Attempted to fix welcome page not showing on fresh install --- readme.md | 2 +- wled00/Structs.h | 33 ----- wled00/data/settings_leds.htm | Bin 8704 -> 8538 bytes wled00/data/settings_sec.htm | Bin 7958 -> 8446 bytes wled00/data/settings_sync.htm | Bin 8328 -> 9616 bytes wled00/htmls01.h | 29 ++-- wled00/src/dependencies/e131/E131.cpp | 82 +++++++++++ wled00/src/dependencies/e131/E131.h | 196 ++++++++++++++++++++++++++ wled00/wled00.ino | 16 ++- wled00/wled01_eeprom.ino | 35 ++++- wled00/wled02_xml.ino | 7 +- wled00/wled03_set.ino | 22 ++- wled00/wled04_file.ino | 5 +- wled00/wled05_init.ino | 24 +++- wled00/wled07_notify.ino | 75 ++++++---- wled00/wled08_led.ino | 17 ++- wled00/wled12_alexa.ino | 3 +- 17 files changed, 439 insertions(+), 107 deletions(-) delete mode 100644 wled00/Structs.h create mode 100644 wled00/src/dependencies/e131/E131.cpp create mode 100644 wled00/src/dependencies/e131/E131.h diff --git a/readme.md b/readme.md index c95fb2bb..778be9d0 100644 --- a/readme.md +++ b/readme.md @@ -24,7 +24,7 @@ WLED is a fast and (relatively) secure implementation of an ESP8266/ESP32 webser - Password protected OTA page for added security (OTA lock) - NTP and configurable analog clock function - Support for the Cronixie Clock kit by Diamex -- Realtime UDP Packet Control (Hyperion, WARLS, DRGB, DRGBW) +- Realtime UDP Packet Control (E1.31, Hyperion, WARLS, DRGB, DRGBW) ### Quick start guide and documentation: diff --git a/wled00/Structs.h b/wled00/Structs.h deleted file mode 100644 index 9a8bbd5d..00000000 --- a/wled00/Structs.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * These are some data object structs, currently unused - */ -#ifndef WLED_Structs_H -#define WLED_Structs_H - -struct Color { - byte white; - byte red; - byte green; - byte blue; -} - -struct Palette { - Color* paletteColors; - byte mainColor = 0; -} - -struct Segment { - uint16_t minLed = 0, maxLed = 10; - Palette segmentPalette; - byte segmentEffect = 0; - byte segmentEffectSpeed = 128; - byte segmentEffectIntensity = 128; -} - -struct Preset { - byte mainSegment; - Segment* segments; - String presetName; -} - -#endif diff --git a/wled00/data/settings_leds.htm b/wled00/data/settings_leds.htm index 83a84271d80847f5adc4eb8e10457012e3dbdfe8..ed28871bb310993bbff25e00ef4eeb634642df4b 100644 GIT binary patch delta 12 TcmZp0x#hHhMPc(Qg)l|{AzlQD delta 62 zcmccR)Zns#ML{&2!I2?|!G|H3L4hHkAq@zN8B!-F@+dNgGx$%Q$gj<=%V5M{%3wO# QkzafAJsyG0EDB+a0LwTIM*si- diff --git a/wled00/data/settings_sec.htm b/wled00/data/settings_sec.htm index 4e3a0556cfd4029f5abbc86b713f64db436644db..9ae3b3a4552600fb46c9e108bcf8a3e2ab407bda 100644 GIT binary patch delta 397 zcmbPc_s?;ImYA#pLkUA7LlHwdLn@GE%b>&%&yd8B0~E_+$lk0jc9sdhlF1(>_7hOC zR`MnR70puT38?Uwp6Z##kPmcdHbW-RX{ijAK&;Q;%3#P~48%$dcs&A?w*#xy1F4=I yD=jUW1T;Z`0nNnWopdN6uFdxnV DvYisj diff --git a/wled00/data/settings_sync.htm b/wled00/data/settings_sync.htm index 05640794ced8a9dad92a4e95995bb462fb916014..1a6fb48c88b27f8a35fc664c2b90ea9ec16846fe 100644 GIT binary patch delta 647 zcmZ`%O-lk%6g}1=EMpo!3UM0`u^;A&{O(=UXVW5FFEHq(?k8ni1s$J1j zCyHfcu!tpoHO#?-jv}^^!YYp8Vh!UMMUYWN=Zm3EE{|Lqxg4C3?^#(NE~6^$)L3GW zuLGNkU8=k6khqB0jfRNb7mt%G!DZ^^Wr&$XO1G#cogS0b@%de5E$UkAH>tEpS7~Nz z)Gp$jwK^_%c8H-L@gB_|8mvoKXT0^uoyL~mTfrrg#J1_)^>5oKuyRDb25UB%l4Slt zOD%(y>HaLly&4&>^(WX@9C%MnEKHf1zcZ^4=hCC;&&r?!&7Z18{c}38#e-4~RK$le zrI*O;QBS&&c=_Uiow0JpyvZj3=p%h7m5P2S{gPBZ2=G_ diff --git a/wled00/htmls01.h b/wled00/htmls01.h index a96a681d..035dd959 100644 --- a/wled00/htmls01.h +++ b/wled00/htmls01.h @@ -120,7 +120,6 @@ Fade down:

Advanced

Reverse LED order (rotate 180):
Init LEDs after WiFi:
-WARLS offset:
Skip first LED:
@@ -207,14 +206,23 @@ Send notifications on button press:
Send Alexa notifications:
Send Philips Hue change notifications:
Send notifications twice:
-Receive UDP realtime:
+

Realtime

+Receive UDP realtime:

+E1.31 (sACN)
+Use E1.31 multicast:
+E1.31 universe:
+Reboot required. Check out LedFx!

+Timeout: ms
+Force max brightness:
+Disable realtime gamma correction:
+Realtime LED offset:
Enable UI access during realtime: (can cause issues)

Alexa Voice Assistant

Emulate Alexa device:
Alexa invocation name:

Blynk

Device Auth token:
-Clear the token field to disable. Setup info +Clear the token field to disable. Setup info

Philips Hue

You can find the bridge IP and the light number in the 'About' section of the hue app.
Poll Hue light every ms:
@@ -350,7 +358,7 @@ HTTP traffic is unencrypted. An attacker in the same network can intercept form
Enable ArduinoOTA:

About

-WLED version 0.7.1

+WLED version 0.7.1

Contributors:
StormPie (Mobile HTML UI)

Thank you so much!

@@ -358,12 +366,13 @@ Thank you so much!

Licensed under the MIT license

Uses libraries:
ESP8266/ESP32 Arduino Core
-(ESP32) WebServer_tng by bbx10
-WS2812FX by kitesurfer1404 (modified)
-Timezone library by JChristensen
-Blynk library (compacted)
-Espalexa by Aircoookie (modified)

-UI icons by Linearicons created by Perxis! (CC-BY-SA 4.0)

+(ESP32) WebServer_tng by bbx10
+WS2812FX by kitesurfer1404 (modified)
+Timezone library by JChristensen
+Blynk library (compacted)
+E1.31 library by forkineye (modified)
+Espalexa by Aircoookie (modified)

+UI icons by Linearicons created by Perxis! (CC-BY-SA 4.0)

Server message: Response error!
diff --git a/wled00/src/dependencies/e131/E131.cpp b/wled00/src/dependencies/e131/E131.cpp new file mode 100644 index 00000000..06251576 --- /dev/null +++ b/wled00/src/dependencies/e131/E131.cpp @@ -0,0 +1,82 @@ +/* +* E131.cpp +* +* Project: E131 - E.131 (sACN) library for Arduino +* Copyright (c) 2015 Shelby Merrick +* http://www.forkineye.com +* +* This program is provided free for you to use in any way that you wish, +* subject to the laws and regulations where you are using it. Due diligence +* is strongly suggested before using this code. Please give credit where due. +* +* The Author makes no warranty of any kind, express or implied, with regard +* to this program or the documentation contained in this document. The +* Author shall not be liable in any event for incidental or consequential +* damages in connection with, or arising out of, the furnishing, performance +* or use of these programs. +* +*/ + +#include "E131.h" +#include + +/* E1.17 ACN Packet Identifier */ +const byte E131::ACN_ID[12] = { 0x41, 0x53, 0x43, 0x2d, 0x45, 0x31, 0x2e, 0x31, 0x37, 0x00, 0x00, 0x00 }; + +/* Constructor */ +E131::E131() { +#ifdef NO_DOUBLE_BUFFER + memset(pbuff1.raw, 0, sizeof(pbuff1.raw)); + packet = &pbuff1; + pwbuff = packet; +#else + memset(pbuff1.raw, 0, sizeof(pbuff1.raw)); + memset(pbuff2.raw, 0, sizeof(pbuff2.raw)); + packet = &pbuff1; + pwbuff = &pbuff2; +#endif + + stats.num_packets = 0; + stats.packet_errors = 0; +} + +void E131::initUnicast() { + udp.begin(E131_DEFAULT_PORT); +} + +void E131::initMulticast(uint16_t universe, uint8_t n) { + IPAddress address = IPAddress(239, 255, ((universe >> 8) & 0xff), + ((universe >> 0) & 0xff)); + #ifdef ARDUINO_ARCH_ESP32 + ip4_addr_t ifaddr; + ip4_addr_t multicast_addr; + + ifaddr.addr = static_cast(WiFi.localIP()); + for (uint8_t i = 1; i < n; i++) { + multicast_addr.addr = static_cast(IPAddress(239, 255, + (((universe + i) >> 8) & 0xff), (((universe + i) >> 0) + & 0xff))); + igmp_joingroup(&ifaddr, &multicast_addr); + } + udp.beginMulticast(address, E131_DEFAULT_PORT); + #else + ip_addr_t ifaddr; + ip_addr_t multicast_addr; + + ifaddr.addr = static_cast(WiFi.localIP()); + for (uint8_t i = 1; i < n; i++) { + multicast_addr.addr = static_cast(IPAddress(239, 255, + (((universe + i) >> 8) & 0xff), (((universe + i) >> 0) + & 0xff))); + igmp_joingroup(&ifaddr, &multicast_addr); + } + udp.beginMulticast(WiFi.localIP(), address, E131_DEFAULT_PORT); + #endif +} + +void E131::begin(e131_listen_t type, uint16_t universe, uint8_t n) { + if (type == E131_UNICAST) + initUnicast(); + if (type == E131_MULTICAST) + initMulticast(universe, n); +} diff --git a/wled00/src/dependencies/e131/E131.h b/wled00/src/dependencies/e131/E131.h new file mode 100644 index 00000000..68ab5d62 --- /dev/null +++ b/wled00/src/dependencies/e131/E131.h @@ -0,0 +1,196 @@ +/* +* E131.h +* +* Project: E131 - E.131 (sACN) library for Arduino +* Copyright (c) 2015 Shelby Merrick +* http://www.forkineye.com +* +* This program is provided free for you to use in any way that you wish, +* subject to the laws and regulations where you are using it. Due diligence +* is strongly suggested before using this code. Please give credit where due. +* +* The Author makes no warranty of any kind, express or implied, with regard +* to this program or the documentation contained in this document. The +* Author shall not be liable in any event for incidental or consequential +* damages in connection with, or arising out of, the furnishing, performance +* or use of these programs. +* +*/ + +#ifndef E131_H_ +#define E131_H_ + +#include "Arduino.h" + +/* Network interface detection. WiFi for ESP8266 and Ethernet for AVR */ +#if defined (ARDUINO_ARCH_ESP8266) +# include +# define NO_DOUBLE_BUFFER +#elif defined (ARDUINO_ARCH_ESP32) +# include +#endif +# include +# include +# include +# define _UDP WiFiUDP + +/* Defaults */ +#define E131_DEFAULT_PORT 5568 + +/* E1.31 Packet Offsets */ +#define E131_ROOT_PREAMBLE_SIZE 0 +#define E131_ROOT_POSTAMBLE_SIZE 2 +#define E131_ROOT_ID 4 +#define E131_ROOT_FLENGTH 16 +#define E131_ROOT_VECTOR 18 +#define E131_ROOT_CID 22 + +#define E131_FRAME_FLENGTH 38 +#define E131_FRAME_VECTOR 40 +#define E131_FRAME_SOURCE 44 +#define E131_FRAME_PRIORITY 108 +#define E131_FRAME_RESERVED 109 +#define E131_FRAME_SEQ 111 +#define E131_FRAME_OPT 112 +#define E131_FRAME_UNIVERSE 113 + +#define E131_DMP_FLENGTH 115 +#define E131_DMP_VECTOR 117 +#define E131_DMP_TYPE 118 +#define E131_DMP_ADDR_FIRST 119 +#define E131_DMP_ADDR_INC 121 +#define E131_DMP_COUNT 123 +#define E131_DMP_DATA 125 + +/* E1.31 Packet Structure */ +typedef union { + struct { + /* Root Layer */ + uint16_t preamble_size; + uint16_t postamble_size; + uint8_t acn_id[12]; + uint16_t root_flength; + uint32_t root_vector; + uint8_t cid[16]; + + /* Frame Layer */ + uint16_t frame_flength; + uint32_t frame_vector; + uint8_t source_name[64]; + uint8_t priority; + uint16_t reserved; + uint8_t sequence_number; + uint8_t options; + uint16_t universe; + + /* DMP Layer */ + uint16_t dmp_flength; + uint8_t dmp_vector; + uint8_t type; + uint16_t first_address; + uint16_t address_increment; + uint16_t property_value_count; + uint8_t property_values[513]; + } __attribute__((packed)); + + uint8_t raw[638]; +} 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; + +/* Status structure */ +typedef struct { + uint32_t num_packets; + uint32_t packet_errors; + IPAddress last_clientIP; + uint16_t last_clientPort; +} e131_stats_t; + +class E131 { + private: + /* Constants for packet validation */ + static const uint8_t ACN_ID[]; + static const uint32_t VECTOR_ROOT = 4; + static const uint32_t VECTOR_FRAME = 2; + static const uint8_t VECTOR_DMP = 2; + + e131_packet_t pbuff1; /* Packet buffer */ +#ifndef NO_DOUBLE_BUFFER + e131_packet_t pbuff2; /* Double buffer */ +#endif + e131_packet_t *pwbuff; /* Pointer to working packet buffer */ + _UDP udp; /* UDP handle */ + + /* Internal Initializers */ + void initUnicast(); + void initMulticast(uint16_t universe, uint8_t n = 1); + + public: + uint8_t *data; /* Pointer to DMX channel data */ + uint16_t universe; /* DMX Universe of last valid packet */ + e131_packet_t *packet; /* Pointer to last valid packet */ + e131_stats_t stats; /* Statistics tracker */ + + E131(); + + /* Generic UDP listener, no physical or IP configuration */ + void begin(e131_listen_t type, uint16_t universe = 1, uint8_t n = 1); + + /* Main packet parser */ + inline uint16_t parsePacket() { + e131_error_t error; + uint16_t retval = 0; + + int size = udp.parsePacket(); + if (size) { + udp.readBytes(pwbuff->raw, size); + error = validate(); + if (!error) { +#ifndef NO_DOUBLE_BUFFER + e131_packet_t *swap = packet; + packet = pwbuff; + pwbuff = swap; +#endif + universe = htons(packet->universe); + data = packet->property_values + 1; + retval = htons(packet->property_value_count) - 1; + stats.num_packets++; + stats.last_clientIP = udp.remoteIP(); + stats.last_clientPort = udp.remotePort(); + } + } + return retval; + } + + /* Packet validater */ + inline e131_error_t validate() { + if (memcmp(pwbuff->acn_id, ACN_ID, sizeof(pwbuff->acn_id))) + return ERROR_ACN_ID; + if (htonl(pwbuff->root_vector) != VECTOR_ROOT) + return ERROR_VECTOR_ROOT; + if (htonl(pwbuff->frame_vector) != VECTOR_FRAME) + return ERROR_VECTOR_FRAME; + if (pwbuff->dmp_vector != VECTOR_DMP) + return ERROR_VECTOR_DMP; + if (pwbuff->property_values[0] != 0) + return ERROR_IGNORE; + return ERROR_NONE; + } +}; + +#endif /* E131_H_ */ diff --git a/wled00/wled00.ino b/wled00/wled00.ino index be0bcdcb..c4afae66 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -36,9 +36,10 @@ #include "htmls02.h" #include "WS2812FX.h" #include "src/dependencies/blynk/BlynkSimpleEsp.h" +#include "src/dependencies/e131/E131.h" //version in format yymmddb (b = daily build) -#define VERSION 1808051 +#define VERSION 1808111 char versionString[] = "0.7.1"; //AP and OTA default passwords (change them!) @@ -193,6 +194,11 @@ uint32_t huePollIntervalMsTemp = huePollIntervalMs; char blynkApiKey[36] = ""; bool blynkEnabled = false; +//e1.31 +bool e131Enabled = true; +byte e131Universe = 1; +bool e131Multicast = false; + //overlay stuff byte overlayDefault = 0; byte overlayCurrent = 0; @@ -224,9 +230,10 @@ uint16_t presetCycleTime = 1250; unsigned long presetCycledTime = 0; byte presetCycCurr = presetCycleMin; bool presetApplyBri = true, presetApplyCol = true, presetApplyFx = true; bool saveCurrPresetCycConf = false; -uint32_t arlsTimeoutMillis = 2500; +uint16_t arlsTimeoutMillis = 2500; bool arlsTimeout = false; bool receiveDirect = true, enableRealtimeUI = false; +bool arlsDisableGammaCorrection = true, arlsForceMaxBri = false; IPAddress realtimeIP = (0,0,0,0); unsigned long arlsTimeoutTime = 0; byte auxTime = 0; @@ -236,7 +243,7 @@ bool showWelcomePage = false; bool useGammaCorrectionBri = false; bool useGammaCorrectionRGB = true; -int arlsOffset = -22; //10: -22 assuming arls52 +int arlsOffset = 0; //alexa udp WiFiUDP UDP; @@ -258,6 +265,7 @@ WebServer server(80); #else ESP8266WebServer server(80); #endif +E131 e131; HTTPClient hueClient; ESP8266HTTPUpdateServer httpUpdater; WiFiUDP notifierUdp, rgbUdp; @@ -338,8 +346,6 @@ bool oappendi(int i) //append new number to temp buffer efficiently } void setup() { - //init strings to defaults - wledInit(); } diff --git a/wled00/wled01_eeprom.ino b/wled00/wled01_eeprom.ino index 74ff413c..682b53f0 100644 --- a/wled00/wled01_eeprom.ino +++ b/wled00/wled01_eeprom.ino @@ -6,7 +6,7 @@ #define EEPSIZE 3072 //eeprom Version code, enables default settings instead of 0 init on update -#define EEPVER 6 +#define EEPVER 7 //0 -> old version, default //1 -> 0.4p 1711272 and up //2 -> 0.4p 1711302 and up @@ -14,8 +14,11 @@ //4 -> 0.5.0 and up //5 -> 0.5.1 and up //6 -> 0.6.0 and up +//7 -> 0.7.1 and up -//todo add settings +/* + * Erase all configuration data + */ void clearEEPROM() { for (int i = 0; i < EEPSIZE; i++) @@ -25,15 +28,15 @@ void clearEEPROM() EEPROM.commit(); } +/* + * Write configuration to flash + */ void saveSettingsToEEPROM() { if (EEPROM.read(233) != 233) //set no first boot flag { clearEEPROM(); EEPROM.write(233, 233); - } else - { - showWelcomePage = false; } for (int i = 0; i < 32; ++i) @@ -204,6 +207,14 @@ void saveSettingsToEEPROM() EEPROM.write(2180, macroCountdown); EEPROM.write(2181, macroNl); + EEPROM.write(2190, (e131Universe >> 0) & 0xFF); + EEPROM.write(2191, (e131Universe >> 8) & 0xFF); + EEPROM.write(2192, e131Multicast); + EEPROM.write(2193, (arlsTimeoutMillis >> 0) & 0xFF); + EEPROM.write(2194, (arlsTimeoutMillis >> 8) & 0xFF); + EEPROM.write(2195, arlsForceMaxBri); + EEPROM.write(2196, arlsDisableGammaCorrection); + EEPROM.write(2200,!receiveDirect); EEPROM.write(2201,enableRealtimeUI); EEPROM.write(2202,uiConfiguration); @@ -231,11 +242,13 @@ void saveSettingsToEEPROM() EEPROM.commit(); } +/* + * Read all configuration from flash + */ void loadSettingsFromEEPROM(bool first) { if (EEPROM.read(233) != 233) //first boot/reset to default { - showWelcomePage=true; saveSettingsToEEPROM(); return; } @@ -432,6 +445,16 @@ void loadSettingsFromEEPROM(bool first) macroCountdown = EEPROM.read(2180); macroNl = EEPROM.read(2181); } + + if (lastEEPROMversion > 6) + { + e131Universe = ((EEPROM.read(2190) << 0) & 0xFF) + ((EEPROM.read(2191) << 8) & 0xFF00); + e131Multicast = EEPROM.read(2192); + arlsTimeoutMillis = ((EEPROM.read(2193) << 0) & 0xFF) + ((EEPROM.read(2194) << 8) & 0xFF00); + arlsForceMaxBri = EEPROM.read(2195); + arlsDisableGammaCorrection = EEPROM.read(2196); + } + receiveDirect = !EEPROM.read(2200); enableRealtimeUI = EEPROM.read(2201); uiConfiguration = EEPROM.read(2202); diff --git a/wled00/wled02_xml.ino b/wled00/wled02_xml.ino index 88233fcc..414d5b94 100644 --- a/wled00/wled02_xml.ino +++ b/wled00/wled02_xml.ino @@ -198,7 +198,6 @@ void getSettingsJS(byte subPage) //get values for settings form in javascript sappend('c',"TW",nightlightFade); sappend('c',"RV",reverseMode); sappend('c',"EI",initLedsLast); - sappend('v',"WO",arlsOffset); sappend('c',"SL",skipFirstLed); } @@ -229,6 +228,12 @@ void getSettingsJS(byte subPage) //get values for settings form in javascript sappend('c',"SH",notifyHue); sappend('c',"S2",notifyTwice); sappend('c',"RD",receiveDirect); + sappend('c',"EM",e131Multicast); + sappend('v',"EU",e131Universe); + sappend('v',"ET",arlsTimeoutMillis); + sappend('c',"FB",arlsForceMaxBri); + sappend('c',"RG",arlsDisableGammaCorrection); + sappend('v',"WO",arlsOffset); sappend('c',"RU",enableRealtimeUI); sappend('c',"AL",alexaEnabled); sappends('s',"AI",alexaInvocationName); diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino index 9ddacbfc..a43fac2b 100644 --- a/wled00/wled03_set.ino +++ b/wled00/wled03_set.ino @@ -181,11 +181,6 @@ void handleSettingsSet(byte subPage) reverseMode = server.hasArg("RV"); initLedsLast = server.hasArg("EI"); strip.setReverseMode(reverseMode); - if (server.hasArg("WO")) - { - int i = server.arg("WO").toInt(); - if (i >= -255 && i <= 255) arlsOffset = i; - } skipFirstLed = server.hasArg("SL"); if (server.hasArg("BF")) { @@ -229,6 +224,23 @@ void handleSettingsSet(byte subPage) notifyButton = server.hasArg("SB"); notifyTwice = server.hasArg("S2"); receiveDirect = server.hasArg("RD"); + if (server.hasArg("EU")) + { + int i = server.arg("EU").toInt(); + if (i > 0 && i <= 63999) arlsTimeoutMillis = i; + } + if (server.hasArg("ET")) + { + int i = server.arg("ET").toInt(); + if (i > 99 && i <= 65000) arlsTimeoutMillis = i; + } + arlsForceMaxBri = server.hasArg("FB"); + arlsDisableGammaCorrection = server.hasArg("RG"); + if (server.hasArg("WO")) + { + int i = server.arg("WO").toInt(); + if (i >= -255 && i <= 255) arlsOffset = i; + } enableRealtimeUI = server.hasArg("RU"); alexaEnabled = server.hasArg("AL"); if (server.hasArg("AI")) strcpy(alexaInvocationName,server.arg("AI").c_str()); diff --git a/wled00/wled04_file.ino b/wled00/wled04_file.ino index f6d2b71d..66a10347 100644 --- a/wled00/wled04_file.ino +++ b/wled00/wled04_file.ino @@ -12,8 +12,7 @@ void handleSerial() strip.setRange(0, ledCount-1, 0); strip.setMode(0); } - arlsTimeout = true; - arlsTimeoutTime = millis() + 5200; + arlsLock(arlsTimeoutMillis); delay(1); byte hi = Serial.read(); byte ledc = Serial.read(); @@ -34,7 +33,7 @@ void handleSerial() to = 0; sc[j] = Serial.read(); } - strip.setPixelColor(i,sc[0],sc[1],sc[2],0); + setRealtimePixel(i,sc[0],sc[1],sc[2],0); } strip.show(); } diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index bb5434a2..e11d9f9f 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -5,6 +5,7 @@ void wledInit() { EEPROM.begin(EEPSIZE); + showWelcomePage = (EEPROM.read(233) != 233); ledCount = ((EEPROM.read(229) << 0) & 0xFF) + ((EEPROM.read(398) << 8) & 0xFF00); if (ledCount > 1200 || ledCount == 0) ledCount = 10; //RMT eats up too much RAM #ifdef ARDUINO_ARCH_ESP32 @@ -40,7 +41,7 @@ void wledInit() hueIP[2] = WiFi.localIP()[2]; } - if (udpPort > 0 && udpPort != ntpLocalPort && WiFi.status() == WL_CONNECTED) + if (udpPort > 0 && udpPort != ntpLocalPort) { udpConnected = notifierUdp.begin(udpPort); if (udpConnected && udpRgbPort != udpPort) udpRgbConnected = rgbUdp.begin(udpRgbPort); @@ -260,6 +261,8 @@ void wledInit() } initBlynk(blynkApiKey); + + initE131(); if (initLedsLast) initStrip(); userBegin(); @@ -400,6 +403,7 @@ void serveIndexOrWelcome() if(!handleFileRead("/welcome.htm")) { serveSettings(255); } + showWelcomePage = false; } } @@ -407,12 +411,18 @@ void serveRealtimeError(bool settings) { String mesg = "The "; mesg += (settings)?"settings":"WLED"; - mesg += " UI is not available while receiving real-time data (UDP from "; - mesg += realtimeIP[0]; - for (int i = 1; i < 4; i++) + mesg += " UI is not available while receiving real-time data ("; + if (realtimeIP[0] == 0) { - mesg += "."; - mesg += realtimeIP[i]; + mesg += "E1.31"; + } else { + mesg += "UDP from "; + mesg += realtimeIP[0]; + for (int i = 1; i < 4; i++) + { + mesg += "."; + mesg += realtimeIP[i]; + } } mesg += ")."; server.send(200, "text/plain", mesg); @@ -566,7 +576,7 @@ void getBuildInfo() #else oappend("strip-pin: gpio2"); #endif - oappend("\r\nbuild-type: dev\r\n"); + oappend("\r\nbuild-type: src\r\n"); } bool checkClientIsMobile(String useragent) diff --git a/wled00/wled07_notify.ino b/wled00/wled07_notify.ino index 4975d34d..78fa7848 100644 --- a/wled00/wled07_notify.ino +++ b/wled00/wled07_notify.ino @@ -59,6 +59,16 @@ void arlsLock(uint32_t timeoutMs) } arlsTimeout = true; arlsTimeoutTime = millis() + timeoutMs; + if (arlsForceMaxBri) strip.setBrightness(255); +} + +void initE131(){ + if (WiFi.status() == WL_CONNECTED && e131Enabled) + { + e131.begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST , e131Universe); + } else { + e131Enabled = false; + } } void handleNotifications() @@ -68,13 +78,29 @@ void handleNotifications() notify(notificationSentCallMode,true); } + //E1.31 protocol support + if(e131Enabled) { + uint16_t len = e131.parsePacket(); + if (len && e131.universe == e131Universe) { + arlsLock(arlsTimeoutMillis); + if (len > ledCount) len = ledCount; + for (uint16_t i = 0; i < len; i++) { + int j = i * 3; + + setRealtimePixel(i, e131.data[j], e131.data[j+1], e131.data[j+2], 0); + } + strip.show(); + } + } + //unlock strip when realtime UDP times out if (arlsTimeout && millis() > arlsTimeoutTime) { strip.unlockAll(); - if (bri == 0) strip.setBrightness(0); + strip.setBrightness(bri); arlsTimeout = false; strip.setMode(effectCurrent); + realtimeIP[0] = 0; } //receive UDP notifications @@ -89,16 +115,12 @@ void handleNotifications() if (packetSize > 1026 || packetSize < 3) return; byte udpIn[packetSize]; rgbUdp.read(udpIn, packetSize); - arlsLock(5200); + arlsLock(arlsTimeoutMillis); uint16_t id = 0; for (uint16_t i = 0; i < packetSize -2; i += 3) { - if (useGammaCorrectionRGB) - { - strip.setPixelColor(id, gamma8[udpIn[i]], gamma8[udpIn[i+1]], gamma8[udpIn[i+2]]); - } else { - strip.setPixelColor(id, udpIn[i], udpIn[i+1], udpIn[i+2]); - } + setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0); + id++; if (id >= ledCount) break; } strip.show(); @@ -168,25 +190,15 @@ void handleNotifications() { for (uint16_t i = 2; i < packetSize -3; i += 4) { - if (udpIn[i] + arlsOffset < ledCount && udpIn[i] + arlsOffset >= 0) - if (useGammaCorrectionRGB) - { - strip.setPixelColor(udpIn[i] + arlsOffset, gamma8[udpIn[i+1]], gamma8[udpIn[i+2]], gamma8[udpIn[i+3]]); - } else { - strip.setPixelColor(udpIn[i] + arlsOffset, udpIn[i+1], udpIn[i+2], udpIn[i+3]); - } + setRealtimePixel(udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3], 0); } } else if (udpIn[0] == 2) //drgb { uint16_t id = 0; for (uint16_t i = 2; i < packetSize -2; i += 3) { - if (useGammaCorrectionRGB) - { - strip.setPixelColor(id, gamma8[udpIn[i]], gamma8[udpIn[i+1]], gamma8[udpIn[i+2]]); - } else { - strip.setPixelColor(id, udpIn[i+0], udpIn[i+1], udpIn[i+2]); - } + setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0); + id++; if (id >= ledCount) break; } } else if (udpIn[0] == 3) //drgbw @@ -194,12 +206,8 @@ void handleNotifications() uint16_t id = 0; for (uint16_t i = 2; i < packetSize -3; i += 4) { - if (useGammaCorrectionRGB) - { - strip.setPixelColor(id, gamma8[udpIn[i]], gamma8[udpIn[i+1]], gamma8[udpIn[i+2]], gamma8[udpIn[i+3]]); - } else { - strip.setPixelColor(id, udpIn[i+0], udpIn[i+1], udpIn[i+2], udpIn[i+3]); - } + setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3]); + id++; if (id >= ledCount) break; } } @@ -210,4 +218,17 @@ void handleNotifications() } } +void setRealtimePixel(int i, byte r, byte g, byte b, byte w) +{ + if (i + arlsOffset < ledCount && i + arlsOffset >= 0) + { + if (!arlsDisableGammaCorrection && useGammaCorrectionRGB) + { + strip.setPixelColor(i + arlsOffset, gamma8[r], gamma8[g], gamma8[b], gamma8[w]); + } else { + strip.setPixelColor(i + arlsOffset, r, g, b, w); + } + } +} + diff --git a/wled00/wled08_led.ino b/wled00/wled08_led.ino index a309ff50..e3b001cc 100644 --- a/wled00/wled08_led.ino +++ b/wled00/wled08_led.ino @@ -3,14 +3,17 @@ */ void setAllLeds() { - double d = briT*briMultiplier; - int val = d/100; - if (val > 255) val = 255; - if (useGammaCorrectionBri) + if (!arlsTimeout || !arlsForceMaxBri) { - strip.setBrightness(gamma8[val]); - } else { - strip.setBrightness(val); + double d = briT*briMultiplier; + int val = d/100; + if (val > 255) val = 255; + if (useGammaCorrectionBri) + { + strip.setBrightness(gamma8[val]); + } else { + strip.setBrightness(val); + } } if (disableSecTransition) { diff --git a/wled00/wled12_alexa.ino b/wled00/wled12_alexa.ino index 7b48f591..bece759a 100644 --- a/wled00/wled12_alexa.ino +++ b/wled00/wled12_alexa.ino @@ -190,8 +190,7 @@ void alexaInitPages() { server.send(200, "text/xml", obuf); - DEBUG_PRINT("Sending :"); - DEBUG_PRINTLN(setup_xml); + DEBUG_PRINTLN("Sending setup_xml"); }); // openHAB support