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:
parent
ed3557ffca
commit
1d4d885276
@ -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:
|
||||
|
||||
|
@ -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.
@ -120,7 +120,6 @@ Fade down: <input type="checkbox" name="TW"><br>
|
||||
<h3>Advanced</h3>
|
||||
Reverse LED order (rotate 180): <input type="checkbox" name="RV"><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>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
||||
</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 Philips Hue change notifications: <input type="checkbox" name="SH"><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)
|
||||
<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>
|
||||
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>
|
||||
<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>
|
||||
@ -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>
|
||||
Enable ArduinoOTA: <input type="checkbox" name="AO"><br>
|
||||
<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>
|
||||
StormPie <i>(Mobile HTML UI)</i><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>
|
||||
<b>Uses libraries:</b><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><a href="https://github.com/kitesurfer1404/WS2812FX">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/blynkkk/blynk-library">Blynk</a> library (compacted)</i><br>
|
||||
<i><a href="https://github.com/Aircoookie/Espalexa">Espalexa</a> by Aircoookie (modified)</i><br><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>(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" target="_blank">WS2812FX</a> by kitesurfer1404 (modified)</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" target="_blank">Blynk</a> library (compacted)</i><br>
|
||||
<i><a href="https://github.com/forkineye/E131" target="_blank">E1.31</a> library by forkineye (modified)</i><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>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button>
|
||||
</form>
|
||||
|
82
wled00/src/dependencies/e131/E131.cpp
Normal file
82
wled00/src/dependencies/e131/E131.cpp
Normal 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);
|
||||
}
|
196
wled00/src/dependencies/e131/E131.h
Normal file
196
wled00/src/dependencies/e131/E131.h
Normal 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_ */
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
@ -261,6 +262,8 @@ void wledInit()
|
||||
|
||||
initBlynk(blynkApiKey);
|
||||
|
||||
initE131();
|
||||
|
||||
if (initLedsLast) initStrip();
|
||||
userBegin();
|
||||
if (macroBoot>0) applyMacro(macroBoot);
|
||||
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user