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
This commit is contained in:
cschwinne 2018-08-11 22:57:13 +02:00
parent ed3557ffca
commit 1d4d885276
17 changed files with 439 additions and 107 deletions

View File

@ -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) - Password protected OTA page for added security (OTA lock)
- NTP and configurable analog clock function - NTP and configurable analog clock function
- Support for the Cronixie Clock kit by Diamex - 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: ### Quick start guide and documentation:

View File

@ -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

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -120,7 +120,6 @@ Fade down: <input type="checkbox" name="TW"><br>
<h3>Advanced</h3> <h3>Advanced</h3>
Reverse LED order (rotate 180): <input type="checkbox" name="RV"><br> Reverse LED order (rotate 180): <input type="checkbox" name="RV"><br>
Init LEDs after WiFi: <input type="checkbox" name="EI"><br> Init LEDs after WiFi: <input type="checkbox" name="EI"><br>
WARLS offset: <input name="WO" type="number" min="-255" max="255" required><br>
Skip first LED: <input type="checkbox" name="SL"><hr> Skip first LED: <input type="checkbox" name="SL"><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>
@ -207,14 +206,23 @@ 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 notifications twice: <input type="checkbox" name="S2"><br> Send notifications twice: <input type="checkbox" name="S2"><br>
Receive UDP realtime: <input type="checkbox" name="RD"><br> <h3>Realtime</h3>
Receive UDP realtime: <input type="checkbox" name="RD"><br><br>
<i>E1.31 (sACN)</i><br>
Use E1.31 multicast: <input type="checkbox" name="EM"><br>
E1.31 universe: <input name="EU" type="number" min="1" max="63999" required><br>
<i>Reboot required.</i> Check out <a href="https://github.com/ahodges9/LedFx" target="_blank">LedFx</a>!<br><br>
Timeout: <input name="ET" type="number" min="1" max="65000" required> ms<br>
Force max brightness: <input type="checkbox" name="FB"><br>
Disable realtime gamma correction: <input type="checkbox" name="RG"><br>
Realtime LED offset: <input name="WO" type="number" min="-255" max="255" required><br>
Enable UI access during realtime: <input type="checkbox" name="RU"> (can cause issues) Enable UI access during realtime: <input type="checkbox" name="RU"> (can cause issues)
<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>
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">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>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" required> every <input name="HI" type="number" min="100" max="65000" required> ms: <input type="checkbox" name="HP"><br> Poll Hue light <input name="HL" type="number" min="1" max="99" required> every <input name="HI" type="number" min="100" max="65000" required> ms: <input type="checkbox" name="HP"><br>
@ -350,7 +358,7 @@ HTTP traffic is unencrypted. An attacker in the same network can intercept form
<button type="button" onclick="U()">Manual OTA Update</button><br> <button type="button" onclick="U()">Manual OTA Update</button><br>
Enable ArduinoOTA: <input type="checkbox" name="AO"><br> Enable ArduinoOTA: <input type="checkbox" name="AO"><br>
<h3>About</h3> <h3>About</h3>
<a href="https://github.com/Aircoookie/WLED">WLED</a> version 0.7.1<br><br> <a href="https://github.com/Aircoookie/WLED" target="_blank">WLED</a> version 0.7.1<br><br>
<b>Contributors:</b><br> <b>Contributors:</b><br>
StormPie <i>(Mobile HTML UI)</i><br><br> StormPie <i>(Mobile HTML UI)</i><br><br>
Thank you so much!<br><br> Thank you so much!<br><br>
@ -358,12 +366,13 @@ Thank you so much!<br><br>
<i>Licensed under the MIT license</i><br><br> <i>Licensed under the MIT license</i><br><br>
<b>Uses libraries:</b><br> <b>Uses libraries:</b><br>
<i>ESP8266/ESP32 Arduino Core</i><br> <i>ESP8266/ESP32 Arduino Core</i><br>
<i>(ESP32) <a href="https://github.com/bbx10/WebServer_tng">WebServer_tng</a> by bbx10</i><br> <i>(ESP32) <a href="https://github.com/bbx10/WebServer_tng" target="_blank">WebServer_tng</a> by bbx10</i><br>
<i><a href="https://github.com/kitesurfer1404/WS2812FX">WS2812FX</a> by kitesurfer1404 (modified)</i><br> <i><a href="https://github.com/kitesurfer1404/WS2812FX" target="_blank">WS2812FX</a> by kitesurfer1404 (modified)</i><br>
<i><a href="https://github.com/JChristensen/Timezone">Timezone</a> library by JChristensen</i><br> <i><a href="https://github.com/JChristensen/Timezone" target="_blank">Timezone</a> library by JChristensen</i><br>
<i><a href="https://github.com/blynkkk/blynk-library">Blynk</a> library (compacted)</i><br> <i><a href="https://github.com/blynkkk/blynk-library" target="_blank">Blynk</a> library (compacted)</i><br>
<i><a href="https://github.com/Aircoookie/Espalexa">Espalexa</a> by Aircoookie (modified)</i><br><br> <i><a href="https://github.com/forkineye/E131" target="_blank">E1.31</a> library by forkineye (modified)</i><br>
<i>UI icons by <a href="https://linearicons.com">Linearicons</a> created by <a href="https://perxis.com">Perxis</a>! (CC-BY-SA 4.0)</i> <br><br> <i><a href="https://github.com/Aircoookie/Espalexa" target="_blank">Espalexa</a> by Aircoookie (modified)</i><br><br>
<i>UI icons by <a href="https://linearicons.com" target="_blank">Linearicons</a> created by <a href="https://perxis.com" target="_blank">Perxis</a>! (CC-BY-SA 4.0)</i> <br><br>
Server message: <span class="msg"> Response error! </span><hr> Server message: <span class="msg"> Response error! </span><hr>
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button> <button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button>
</form> </form>

View File

@ -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 <string.h>
/* 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<uint32_t>(WiFi.localIP());
for (uint8_t i = 1; i < n; i++) {
multicast_addr.addr = static_cast<uint32_t>(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<uint32_t>(WiFi.localIP());
for (uint8_t i = 1; i < n; i++) {
multicast_addr.addr = static_cast<uint32_t>(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);
}

View File

@ -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 <ESP8266WiFi.h>
# define NO_DOUBLE_BUFFER
#elif defined (ARDUINO_ARCH_ESP32)
# include <WiFi.h>
#endif
# include <WiFiUdp.h>
# include <lwip/ip_addr.h>
# include <lwip/igmp.h>
# 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_ */

View File

@ -36,9 +36,10 @@
#include "htmls02.h" #include "htmls02.h"
#include "WS2812FX.h" #include "WS2812FX.h"
#include "src/dependencies/blynk/BlynkSimpleEsp.h" #include "src/dependencies/blynk/BlynkSimpleEsp.h"
#include "src/dependencies/e131/E131.h"
//version in format yymmddb (b = daily build) //version in format yymmddb (b = daily build)
#define VERSION 1808051 #define VERSION 1808111
char versionString[] = "0.7.1"; char versionString[] = "0.7.1";
//AP and OTA default passwords (change them!) //AP and OTA default passwords (change them!)
@ -193,6 +194,11 @@ uint32_t huePollIntervalMsTemp = huePollIntervalMs;
char blynkApiKey[36] = ""; char blynkApiKey[36] = "";
bool blynkEnabled = false; bool blynkEnabled = false;
//e1.31
bool e131Enabled = true;
byte e131Universe = 1;
bool e131Multicast = false;
//overlay stuff //overlay stuff
byte overlayDefault = 0; byte overlayDefault = 0;
byte overlayCurrent = 0; byte overlayCurrent = 0;
@ -224,9 +230,10 @@ uint16_t presetCycleTime = 1250;
unsigned long presetCycledTime = 0; byte presetCycCurr = presetCycleMin; unsigned long presetCycledTime = 0; byte presetCycCurr = presetCycleMin;
bool presetApplyBri = true, presetApplyCol = true, presetApplyFx = true; bool presetApplyBri = true, presetApplyCol = true, presetApplyFx = true;
bool saveCurrPresetCycConf = false; bool saveCurrPresetCycConf = false;
uint32_t arlsTimeoutMillis = 2500; uint16_t arlsTimeoutMillis = 2500;
bool arlsTimeout = false; bool arlsTimeout = false;
bool receiveDirect = true, enableRealtimeUI = false; bool receiveDirect = true, enableRealtimeUI = false;
bool arlsDisableGammaCorrection = true, arlsForceMaxBri = false;
IPAddress realtimeIP = (0,0,0,0); IPAddress realtimeIP = (0,0,0,0);
unsigned long arlsTimeoutTime = 0; unsigned long arlsTimeoutTime = 0;
byte auxTime = 0; byte auxTime = 0;
@ -236,7 +243,7 @@ bool showWelcomePage = false;
bool useGammaCorrectionBri = false; bool useGammaCorrectionBri = false;
bool useGammaCorrectionRGB = true; bool useGammaCorrectionRGB = true;
int arlsOffset = -22; //10: -22 assuming arls52 int arlsOffset = 0;
//alexa udp //alexa udp
WiFiUDP UDP; WiFiUDP UDP;
@ -258,6 +265,7 @@ WebServer server(80);
#else #else
ESP8266WebServer server(80); ESP8266WebServer server(80);
#endif #endif
E131 e131;
HTTPClient hueClient; HTTPClient hueClient;
ESP8266HTTPUpdateServer httpUpdater; ESP8266HTTPUpdateServer httpUpdater;
WiFiUDP notifierUdp, rgbUdp; WiFiUDP notifierUdp, rgbUdp;
@ -338,8 +346,6 @@ bool oappendi(int i) //append new number to temp buffer efficiently
} }
void setup() { void setup() {
//init strings to defaults
wledInit(); wledInit();
} }

View File

@ -6,7 +6,7 @@
#define EEPSIZE 3072 #define EEPSIZE 3072
//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 6 #define EEPVER 7
//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
@ -14,8 +14,11 @@
//4 -> 0.5.0 and up //4 -> 0.5.0 and up
//5 -> 0.5.1 and up //5 -> 0.5.1 and up
//6 -> 0.6.0 and up //6 -> 0.6.0 and up
//7 -> 0.7.1 and up
//todo add settings /*
* Erase all configuration data
*/
void clearEEPROM() void clearEEPROM()
{ {
for (int i = 0; i < EEPSIZE; i++) for (int i = 0; i < EEPSIZE; i++)
@ -25,15 +28,15 @@ void clearEEPROM()
EEPROM.commit(); EEPROM.commit();
} }
/*
* Write configuration to flash
*/
void saveSettingsToEEPROM() void saveSettingsToEEPROM()
{ {
if (EEPROM.read(233) != 233) //set no first boot flag if (EEPROM.read(233) != 233) //set no first boot flag
{ {
clearEEPROM(); clearEEPROM();
EEPROM.write(233, 233); EEPROM.write(233, 233);
} else
{
showWelcomePage = false;
} }
for (int i = 0; i < 32; ++i) for (int i = 0; i < 32; ++i)
@ -204,6 +207,14 @@ void saveSettingsToEEPROM()
EEPROM.write(2180, macroCountdown); EEPROM.write(2180, macroCountdown);
EEPROM.write(2181, macroNl); 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(2200,!receiveDirect);
EEPROM.write(2201,enableRealtimeUI); EEPROM.write(2201,enableRealtimeUI);
EEPROM.write(2202,uiConfiguration); EEPROM.write(2202,uiConfiguration);
@ -231,11 +242,13 @@ void saveSettingsToEEPROM()
EEPROM.commit(); EEPROM.commit();
} }
/*
* Read all configuration from flash
*/
void loadSettingsFromEEPROM(bool first) void loadSettingsFromEEPROM(bool first)
{ {
if (EEPROM.read(233) != 233) //first boot/reset to default if (EEPROM.read(233) != 233) //first boot/reset to default
{ {
showWelcomePage=true;
saveSettingsToEEPROM(); saveSettingsToEEPROM();
return; return;
} }
@ -432,6 +445,16 @@ void loadSettingsFromEEPROM(bool first)
macroCountdown = EEPROM.read(2180); macroCountdown = EEPROM.read(2180);
macroNl = EEPROM.read(2181); 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); receiveDirect = !EEPROM.read(2200);
enableRealtimeUI = EEPROM.read(2201); enableRealtimeUI = EEPROM.read(2201);
uiConfiguration = EEPROM.read(2202); uiConfiguration = EEPROM.read(2202);

View File

@ -198,7 +198,6 @@ void getSettingsJS(byte subPage) //get values for settings form in javascript
sappend('c',"TW",nightlightFade); sappend('c',"TW",nightlightFade);
sappend('c',"RV",reverseMode); sappend('c',"RV",reverseMode);
sappend('c',"EI",initLedsLast); sappend('c',"EI",initLedsLast);
sappend('v',"WO",arlsOffset);
sappend('c',"SL",skipFirstLed); 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',"SH",notifyHue);
sappend('c',"S2",notifyTwice); sappend('c',"S2",notifyTwice);
sappend('c',"RD",receiveDirect); 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',"RU",enableRealtimeUI);
sappend('c',"AL",alexaEnabled); sappend('c',"AL",alexaEnabled);
sappends('s',"AI",alexaInvocationName); sappends('s',"AI",alexaInvocationName);

View File

@ -181,11 +181,6 @@ void handleSettingsSet(byte subPage)
reverseMode = server.hasArg("RV"); reverseMode = server.hasArg("RV");
initLedsLast = server.hasArg("EI"); initLedsLast = server.hasArg("EI");
strip.setReverseMode(reverseMode); strip.setReverseMode(reverseMode);
if (server.hasArg("WO"))
{
int i = server.arg("WO").toInt();
if (i >= -255 && i <= 255) arlsOffset = i;
}
skipFirstLed = server.hasArg("SL"); skipFirstLed = server.hasArg("SL");
if (server.hasArg("BF")) if (server.hasArg("BF"))
{ {
@ -229,6 +224,23 @@ void handleSettingsSet(byte subPage)
notifyButton = server.hasArg("SB"); notifyButton = server.hasArg("SB");
notifyTwice = server.hasArg("S2"); notifyTwice = server.hasArg("S2");
receiveDirect = server.hasArg("RD"); 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"); enableRealtimeUI = server.hasArg("RU");
alexaEnabled = server.hasArg("AL"); alexaEnabled = server.hasArg("AL");
if (server.hasArg("AI")) strcpy(alexaInvocationName,server.arg("AI").c_str()); if (server.hasArg("AI")) strcpy(alexaInvocationName,server.arg("AI").c_str());

View File

@ -12,8 +12,7 @@ void handleSerial()
strip.setRange(0, ledCount-1, 0); strip.setRange(0, ledCount-1, 0);
strip.setMode(0); strip.setMode(0);
} }
arlsTimeout = true; arlsLock(arlsTimeoutMillis);
arlsTimeoutTime = millis() + 5200;
delay(1); delay(1);
byte hi = Serial.read(); byte hi = Serial.read();
byte ledc = Serial.read(); byte ledc = Serial.read();
@ -34,7 +33,7 @@ void handleSerial()
to = 0; to = 0;
sc[j] = Serial.read(); 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(); strip.show();
} }

View File

@ -5,6 +5,7 @@
void wledInit() void wledInit()
{ {
EEPROM.begin(EEPSIZE); 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; ledCount = ((EEPROM.read(229) << 0) & 0xFF) + ((EEPROM.read(398) << 8) & 0xFF00); if (ledCount > 1200 || ledCount == 0) ledCount = 10;
//RMT eats up too much RAM //RMT eats up too much RAM
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
@ -40,7 +41,7 @@ void wledInit()
hueIP[2] = WiFi.localIP()[2]; hueIP[2] = WiFi.localIP()[2];
} }
if (udpPort > 0 && udpPort != ntpLocalPort && WiFi.status() == WL_CONNECTED) if (udpPort > 0 && udpPort != ntpLocalPort)
{ {
udpConnected = notifierUdp.begin(udpPort); udpConnected = notifierUdp.begin(udpPort);
if (udpConnected && udpRgbPort != udpPort) udpRgbConnected = rgbUdp.begin(udpRgbPort); if (udpConnected && udpRgbPort != udpPort) udpRgbConnected = rgbUdp.begin(udpRgbPort);
@ -261,6 +262,8 @@ void wledInit()
initBlynk(blynkApiKey); initBlynk(blynkApiKey);
initE131();
if (initLedsLast) initStrip(); if (initLedsLast) initStrip();
userBegin(); userBegin();
if (macroBoot>0) applyMacro(macroBoot); if (macroBoot>0) applyMacro(macroBoot);
@ -400,6 +403,7 @@ void serveIndexOrWelcome()
if(!handleFileRead("/welcome.htm")) { if(!handleFileRead("/welcome.htm")) {
serveSettings(255); serveSettings(255);
} }
showWelcomePage = false;
} }
} }
@ -407,13 +411,19 @@ void serveRealtimeError(bool settings)
{ {
String mesg = "The "; String mesg = "The ";
mesg += (settings)?"settings":"WLED"; mesg += (settings)?"settings":"WLED";
mesg += " UI is not available while receiving real-time data (UDP from "; mesg += " UI is not available while receiving real-time data (";
if (realtimeIP[0] == 0)
{
mesg += "E1.31";
} else {
mesg += "UDP from ";
mesg += realtimeIP[0]; mesg += realtimeIP[0];
for (int i = 1; i < 4; i++) for (int i = 1; i < 4; i++)
{ {
mesg += "."; mesg += ".";
mesg += realtimeIP[i]; mesg += realtimeIP[i];
} }
}
mesg += ")."; mesg += ").";
server.send(200, "text/plain", mesg); server.send(200, "text/plain", mesg);
} }
@ -566,7 +576,7 @@ void getBuildInfo()
#else #else
oappend("strip-pin: gpio2"); oappend("strip-pin: gpio2");
#endif #endif
oappend("\r\nbuild-type: dev\r\n"); oappend("\r\nbuild-type: src\r\n");
} }
bool checkClientIsMobile(String useragent) bool checkClientIsMobile(String useragent)

View File

@ -59,6 +59,16 @@ void arlsLock(uint32_t timeoutMs)
} }
arlsTimeout = true; arlsTimeout = true;
arlsTimeoutTime = millis() + timeoutMs; 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() void handleNotifications()
@ -68,13 +78,29 @@ void handleNotifications()
notify(notificationSentCallMode,true); 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 //unlock strip when realtime UDP times out
if (arlsTimeout && millis() > arlsTimeoutTime) if (arlsTimeout && millis() > arlsTimeoutTime)
{ {
strip.unlockAll(); strip.unlockAll();
if (bri == 0) strip.setBrightness(0); strip.setBrightness(bri);
arlsTimeout = false; arlsTimeout = false;
strip.setMode(effectCurrent); strip.setMode(effectCurrent);
realtimeIP[0] = 0;
} }
//receive UDP notifications //receive UDP notifications
@ -89,16 +115,12 @@ void handleNotifications()
if (packetSize > 1026 || packetSize < 3) return; if (packetSize > 1026 || packetSize < 3) return;
byte udpIn[packetSize]; byte udpIn[packetSize];
rgbUdp.read(udpIn, packetSize); rgbUdp.read(udpIn, packetSize);
arlsLock(5200); arlsLock(arlsTimeoutMillis);
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)
{ {
if (useGammaCorrectionRGB) setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0);
{
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]);
}
id++; if (id >= ledCount) break; id++; if (id >= ledCount) break;
} }
strip.show(); strip.show();
@ -168,25 +190,15 @@ void handleNotifications()
{ {
for (uint16_t i = 2; i < packetSize -3; i += 4) for (uint16_t i = 2; i < packetSize -3; i += 4)
{ {
if (udpIn[i] + arlsOffset < ledCount && udpIn[i] + arlsOffset >= 0) setRealtimePixel(udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3], 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]);
}
} }
} else if (udpIn[0] == 2) //drgb } else if (udpIn[0] == 2) //drgb
{ {
uint16_t id = 0; uint16_t id = 0;
for (uint16_t i = 2; i < packetSize -2; i += 3) for (uint16_t i = 2; i < packetSize -2; i += 3)
{ {
if (useGammaCorrectionRGB) setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0);
{
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]);
}
id++; if (id >= ledCount) break; id++; if (id >= ledCount) break;
} }
} else if (udpIn[0] == 3) //drgbw } else if (udpIn[0] == 3) //drgbw
@ -194,12 +206,8 @@ void handleNotifications()
uint16_t id = 0; uint16_t id = 0;
for (uint16_t i = 2; i < packetSize -3; i += 4) for (uint16_t i = 2; i < packetSize -3; i += 4)
{ {
if (useGammaCorrectionRGB) setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3]);
{
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]);
}
id++; if (id >= ledCount) break; 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);
}
}
}

View File

@ -3,6 +3,8 @@
*/ */
void setAllLeds() { void setAllLeds() {
if (!arlsTimeout || !arlsForceMaxBri)
{
double d = briT*briMultiplier; double d = briT*briMultiplier;
int val = d/100; int val = d/100;
if (val > 255) val = 255; if (val > 255) val = 255;
@ -12,6 +14,7 @@ void setAllLeds() {
} else { } else {
strip.setBrightness(val); strip.setBrightness(val);
} }
}
if (disableSecTransition) if (disableSecTransition)
{ {
for (byte i = 0; i<3; i++) for (byte i = 0; i<3; i++)

View File

@ -190,8 +190,7 @@ void alexaInitPages() {
server.send(200, "text/xml", obuf); server.send(200, "text/xml", obuf);
DEBUG_PRINT("Sending :"); DEBUG_PRINTLN("Sending setup_xml");
DEBUG_PRINTLN(setup_xml);
}); });
// openHAB support // openHAB support