Merge branch 'master' into CCT-support

This commit is contained in:
Christian Schwinne 2021-11-18 16:50:24 +01:00 committed by GitHub
commit 0465298507
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 367 additions and 50 deletions

View File

@ -2,6 +2,20 @@
### Builds after release 0.12.0 ### Builds after release 0.12.0
#### Build 2111160
- Version bump to 0.13.0-b5 "Toki"
- Improv Serial support (PR #2334)
- Button improvements (PR #2284)
- Added two time zones (PR #2264, 2311)
- JSON in/decrementing support for brightness and presets
- Fixed no gamma correction for JSON individual LED control
- Preset cycle bugfix
- Removed ledCount
- LED settings buffer bugfix
- Network pin conflict bugfix
- Changed default ESP32 partition layout to 4M, 1M FS
#### Build 2110110 #### Build 2110110
- Version bump to 0.13.0-b4 "Toki" - Version bump to 0.13.0-b4 "Toki"

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "wled", "name": "wled",
"version": "0.13.0-b4", "version": "0.13.0-b5",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View File

@ -1,6 +1,6 @@
{ {
"name": "wled", "name": "wled",
"version": "0.13.0-b4", "version": "0.13.0-b5",
"description": "Tools for WLED project", "description": "Tools for WLED project",
"main": "tools/cdata.js", "main": "tools/cdata.js",
"directories": { "directories": {

View File

@ -207,6 +207,8 @@ build_flags = -g
-DCONFIG_LITTLEFS_FOR_IDF_3_2 -DCONFIG_LITTLEFS_FOR_IDF_3_2
-D CONFIG_ASYNC_TCP_USE_WDT=0 -D CONFIG_ASYNC_TCP_USE_WDT=0
default_partitions = tools/WLED_ESP32_4MB_1MB_FS.csv
lib_deps = lib_deps =
${env.lib_deps} ${env.lib_deps}
makuna/NeoPixelBus @ 2.6.7 makuna/NeoPixelBus @ 2.6.7
@ -292,6 +294,7 @@ platform = espressif32@2.0
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32 #-D WLED_DISABLE_BROWNOUT_DET build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32 #-D WLED_DISABLE_BROWNOUT_DET
lib_deps = ${esp32.lib_deps} lib_deps = ${esp32.lib_deps}
board_build.partitions = ${esp32.default_partitions}
[env:esp32_eth] [env:esp32_eth]
board = esp32-poe board = esp32-poe
@ -300,6 +303,7 @@ upload_speed = 921600
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32_Ethernet -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1 build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32_Ethernet -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1
lib_deps = ${esp32.lib_deps} lib_deps = ${esp32.lib_deps}
board_build.partitions = ${esp32.default_partitions}
[env:esp32s2_saola] [env:esp32s2_saola]
board = esp32dev board = esp32dev
@ -406,6 +410,7 @@ build_flags = ${common.build_flags_esp32}
lib_deps = ${esp32.lib_deps} lib_deps = ${esp32.lib_deps}
OneWire@~2.3.5 OneWire@~2.3.5
olikraus/U8g2 @ ^2.28.8 olikraus/U8g2 @ ^2.28.8
board_build.partitions = ${esp32.default_partitions}
[env:m5atom] [env:m5atom]
board = esp32dev board = esp32dev
@ -413,6 +418,7 @@ build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp32} -D LEDPIN=27 -D BTNPIN=39 build_flags = ${common.build_flags_esp32} -D LEDPIN=27 -D BTNPIN=39
lib_deps = ${esp32.lib_deps} lib_deps = ${esp32.lib_deps}
platform = espressif32@3.2 platform = espressif32@3.2
board_build.partitions = ${esp32.default_partitions}
[env:sp501e] [env:sp501e]
board = esp_wroom_02 board = esp_wroom_02
@ -498,3 +504,4 @@ monitor_filters = esp32_exception_decoder
lib_deps = lib_deps =
${esp32.lib_deps} ${esp32.lib_deps}
TFT_eSPI @ ^2.3.70 TFT_eSPI @ ^2.3.70
board_build.partitions = ${esp32.default_partitions}

View File

@ -299,8 +299,11 @@ void handleIO()
#ifdef ESP8266 #ifdef ESP8266
// turn off built-in LED if strip is turned off // turn off built-in LED if strip is turned off
// this will break digital bus so will need to be reinitialised on On // this will break digital bus so will need to be reinitialised on On
PinOwner ledPinOwner = pinManager.getPinOwner(LED_BUILTIN);
if (!strip.isOffRefreshRequred && (ledPinOwner == PinOwner::None || ledPinOwner == PinOwner::BusDigital)) {
pinMode(LED_BUILTIN, OUTPUT); pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH); digitalWrite(LED_BUILTIN, HIGH);
}
#endif #endif
if (rlyPin>=0) { if (rlyPin>=0) {
pinMode(rlyPin, OUTPUT); pinMode(rlyPin, OUTPUT);

View File

@ -397,11 +397,9 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
CJSON(DMXStartLED,dmx[F("start-led")]); CJSON(DMXStartLED,dmx[F("start-led")]);
JsonArray dmx_fixmap = dmx[F("fixmap")]; JsonArray dmx_fixmap = dmx[F("fixmap")];
it = 0; for (int i = 0; i < dmx_fixmap.size(); i++) {
for (int i : dmx_fixmap) { if (i > 14) break;
if (it > 14) break;
CJSON(DMXFixtureMap[i],dmx_fixmap[i]); CJSON(DMXFixtureMap[i],dmx_fixmap[i]);
it++;
} }
#endif #endif

View File

@ -265,12 +265,20 @@
#endif #endif
// string temp buffer (now stored in stack locally) // string temp buffer (now stored in stack locally)
#define OMAX 2048 #ifdef ESP8266
#define SETTINGS_STACK_BUF_SIZE 2048
#else
#define SETTINGS_STACK_BUF_SIZE 3096
#endif
#ifdef WLED_USE_ETHERNET #ifdef WLED_USE_ETHERNET
#define E131_MAX_UNIVERSE_COUNT 20 #define E131_MAX_UNIVERSE_COUNT 20
#else #else
#define E131_MAX_UNIVERSE_COUNT 10 #ifdef ESP8266
#define E131_MAX_UNIVERSE_COUNT 9
#else
#define E131_MAX_UNIVERSE_COUNT 12
#endif
#endif #endif
#define ABL_MILLIAMPS_DEFAULT 850 // auto lower brightness to stay close to milliampere limit #define ABL_MILLIAMPS_DEFAULT 850 // auto lower brightness to stay close to milliampere limit

View File

@ -55,7 +55,7 @@
if (n2.substring(0,1)==="L") { if (n2.substring(0,1)==="L") {
var m = LCs[j].name.substring(2); var m = LCs[j].name.substring(2);
var t2 = parseInt(d.getElementsByName("LT"+m)[0].value, 10); var t2 = parseInt(d.getElementsByName("LT"+m)[0].value, 10);
if (t2<16) continue; if (t2>=80) continue;
} }
if (LCs[j].value!="" && LCs[i].value==LCs[j].value) {alert(`Pin conflict between ${LCs[i].name}/${LCs[j].name}!`);LCs[j].value="";LCs[j].focus();return false;} if (LCs[j].value!="" && LCs[i].value==LCs[j].value) {alert(`Pin conflict between ${LCs[i].name}/${LCs[j].name}!`);LCs[j].value="";LCs[j].focus();return false;}
} }

View File

@ -95,6 +95,12 @@ void onHueConnect(void* arg, AsyncClient* client);
void sendHuePoll(); void sendHuePoll();
void onHueData(void* arg, AsyncClient* client, void *data, size_t len); void onHueData(void* arg, AsyncClient* client, void *data, size_t len);
//improv.cpp
void handleImprovPacket();
void sendImprovStateResponse(uint8_t state, bool error = false);
void sendImprovInfoResponse();
void sendImprovRPCResponse(uint8_t commandId);
//ir.cpp //ir.cpp
bool decodeIRCustom(uint32_t code); bool decodeIRCustom(uint32_t code);
void applyRepeatActions(); void applyRepeatActions();

View File

@ -42,7 +42,7 @@ function B(){window.history.back()}function U(){document.getElementById("uf").st
.bt{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}input[type=file]{font-size:16px}body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%}#msg{display:none} .bt{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}input[type=file]{font-size:16px}body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%}#msg{display:none}
</style></head><body><h2>WLED Software Update</h2><form method="POST" </style></head><body><h2>WLED Software Update</h2><form method="POST"
action="/update" id="uf" enctype="multipart/form-data" onsubmit="U()"> action="/update" id="uf" enctype="multipart/form-data" onsubmit="U()">
Installed version: 0.13.0-b4<br>Download the latest binary: <a Installed version: 0.13.0-b5<br>Download the latest binary: <a
href="https://github.com/Aircoookie/WLED/releases" target="_blank"><img href="https://github.com/Aircoookie/WLED/releases" target="_blank"><img
src="https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square"> src="https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square">
</a><br><input type="file" class="bt" name="update" required><br><input </a><br><input type="file" class="bt" name="update" required><br><input

View File

@ -353,30 +353,29 @@ North Korea</option><option value="14">IST (India)</option><option value="15">
CA-Saskatchewan</option><option value="16">ACST</option><option value="17"> CA-Saskatchewan</option><option value="16">ACST</option><option value="17">
ACST/ACDT</option><option value="18">HST (Hawaii)</option><option value="19"> ACST/ACDT</option><option value="18">HST (Hawaii)</option><option value="19">
NOVT (Novosibirsk)</option><option value="20">AKST/AKDT (Anchorage)</option> NOVT (Novosibirsk)</option><option value="20">AKST/AKDT (Anchorage)</option>
<option value="21">MX-CST/CDT</option> <option value="21">MX-CST/CDT</option></select><br>UTC offset: <input name="UO"
</select><br>UTC offset: <input name="UO" type="number" min="-65500" type="number" min="-65500" max="65500" required> seconds (max. 18 hours)<br>
max="65500" required> seconds (max. 18 hours)<br>Current local time is <span Current local time is <span class="times">unknown</span>.<br>Latitude (N):
class="times">unknown</span>.<br>Latitude (N): <input name="LT" type="number" <input name="LT" type="number" min="-66.6" max="66.6" step="0.01">
min="-66.6" max="66.6" step="0.01"> Longitude (E): <input name="LN" Longitude (E): <input name="LN" type="number" min="-180" max="180" step="0.01">
type="number" min="-180" max="180" step="0.01"><div id="sun" class="times"> <div id="sun" class="times"></div><h3>Clock</h3>Clock Overlay: <select
</div><h3>Clock</h3>Clock Overlay: <select name="OL" onchange="Cs()"><option name="OL" onchange="Cs()"><option value="0" id="cn" selected="selected">None
value="0" id="cn" selected="selected">None</option><option value="1" id="ca"> </option><option value="1" id="ca">Analog Clock</option><option value="2">
Analog Clock</option><option value="2">Single Digit Clock</option><option Single Digit Clock</option><option value="3" id="cc">Cronixie Clock</option>
value="3" id="cc">Cronixie Clock</option></select><br><div id="coc">First LED: </select><br><div id="coc">First LED: <input name="O1" type="number" min="0"
<input name="O1" type="number" min="0" max="255" required> Last LED: <input max="255" required> Last LED: <input name="O2" type="number" min="0" max="255"
name="O2" type="number" min="0" max="255" required><br><div id="cac">12h LED: required><br><div id="cac">12h LED: <input name="OM" type="number" min="0"
<input name="OM" type="number" min="0" max="255" required><br>Show 5min marks: max="255" required><br>Show 5min marks: <input type="checkbox" name="O5"><br>
<input type="checkbox" name="O5"><br></div>Seconds (as trail): <input </div>Seconds (as trail): <input type="checkbox" name="OS"><br></div><div
type="checkbox" name="OS"><br></div><div id="ccc">Cronixie Display: <input id="ccc">Cronixie Display: <input name="CX" maxlength="6"><br>
name="CX" maxlength="6"><br>Cronixie Backlight: <input type="checkbox" Cronixie Backlight: <input type="checkbox" name="CB"><br></div>Countdown Mode:
name="CB"><br></div>Countdown Mode: <input type="checkbox" name="CE"><br> <input type="checkbox" name="CE"><br>Countdown Goal:<br>Year: 20 <input
Countdown Goal:<br>Year: 20 <input name="CY" type="number" min="0" max="99" name="CY" type="number" min="0" max="99" required> Month: <input name="CI"
required> Month: <input name="CI" type="number" min="1" max="12" required> Day: type="number" min="1" max="12" required> Day: <input name="CD" type="number"
<input name="CD" type="number" min="1" max="31" required><br>Hour: <input min="1" max="31" required><br>Hour: <input name="CH" type="number" min="0"
name="CH" type="number" min="0" max="23" required> Minute: <input name="CM" max="23" required> Minute: <input name="CM" type="number" min="0" max="59"
type="number" min="0" max="59" required> Second: <input name="CS" type="number" required> Second: <input name="CS" type="number" min="0" max="59" required><br>
min="0" max="59" required><br><h3>Macro presets</h3><b>Macros have moved!</b> <h3>Macro presets</h3><b>Macros have moved!</b><br><i>
<br><i>
Presets now also can be used as macros to save both JSON and HTTP API commands. Presets now also can be used as macros to save both JSON and HTTP API commands.
<br>Just enter the preset id below!</i> <i> <br>Just enter the preset id below!</i> <i>
Use 0 for the default action instead of a preset</i><br>Alexa On/Off Preset: Use 0 for the default action instead of a preset</i><br>Alexa On/Off Preset:
@ -428,7 +427,7 @@ onclick='uploadFile(d.Sf.data2,"/cfg.json")'><br></div><div style="color:#fa0">
Incorrect configuration may require a factory reset or re-flashing of your ESP. Incorrect configuration may require a factory reset or re-flashing of your ESP.
</div>For security reasons, passwords are not backed up.<h3>About</h3><a </div>For security reasons, passwords are not backed up.<h3>About</h3><a
href="https://github.com/Aircoookie/WLED/" target="_blank">WLED</a> href="https://github.com/Aircoookie/WLED/" target="_blank">WLED</a>
version 0.13.0-b4<br><br><a version 0.13.0-b5<br><br><a
href="https://github.com/Aircoookie/WLED/wiki/Contributors-and-credits" href="https://github.com/Aircoookie/WLED/wiki/Contributors-and-credits"
target="_blank">Contributors, dependencies and special thanks</a><br> target="_blank">Contributors, dependencies and special thanks</a><br>
A huge thank you to everyone who helped me create WLED!<br><br> A huge thank you to everyone who helped me create WLED!<br><br>

244
wled00/improv.cpp Normal file
View File

@ -0,0 +1,244 @@
#include "wled.h"
#ifdef WLED_DEBUG_IMPROV
#define DIMPROV_PRINT(x) Serial.print(x)
#define DIMPROV_PRINTLN(x) Serial.println(x)
#define DIMPROV_PRINTF(x...) Serial.printf(x)
#else
#define DIMPROV_PRINT(x)
#define DIMPROV_PRINTLN(x)
#define DIMPROV_PRINTF(x...)
#endif
#define IMPROV_VERSION 1
void parseWiFiCommand(char *rpcData);
enum ImprovPacketType {
Current_State = 0x01,
Error_State = 0x02,
RPC_Command = 0x03,
RPC_Response = 0x04
};
enum ImprovPacketByte {
Version = 6,
PacketType = 7,
Length = 8,
RPC_CommandType = 9
};
enum ImprovRPCType {
Command_Wifi = 0x01,
Request_State = 0x02,
Request_Info = 0x03
};
//File dbgf;
//blocking function to parse an Improv Serial packet
void handleImprovPacket() {
uint8_t header[6] = {'I','M','P','R','O','V'};
//dbgf = WLED_FS.open("/improv.log","a");
bool timeout = false;
uint8_t waitTime = 25;
uint16_t packetByte = 0;
uint8_t packetLen = 9;
uint8_t checksum = 0;
uint8_t rpcCommandType = 0;
char rpcData[128];
rpcData[0] = 0;
while (!timeout) {
if (Serial.available() < 1) {
delay(1);
waitTime--;
if (!waitTime) timeout = true;
continue;
}
byte next = Serial.read();
DIMPROV_PRINT("Received improv byte: "); DIMPROV_PRINTF("%x\r\n",next);
//f.write(next);
switch (packetByte) {
case ImprovPacketByte::Version: {
if (next != IMPROV_VERSION) {
DIMPROV_PRINTLN(F("Invalid version"));
//dbgf.close();
return;
}
break;
}
case ImprovPacketByte::PacketType: {
if (next != ImprovPacketType::RPC_Command) {
DIMPROV_PRINTF("Non RPC-command improv packet type %i\n",next);
//dbgf.close();
return;
}
if (!improvActive) improvActive = 1;
break;
}
case ImprovPacketByte::Length: packetLen = 9 + next; break;
case ImprovPacketByte::RPC_CommandType: rpcCommandType = next; break;
default: {
if (packetByte >= packetLen) { //end of packet, check checksum match
if (checksum != next) {
DIMPROV_PRINTF("Got RPC checksum %i, expected %i",next,checksum);
sendImprovStateResponse(0x01, true);
//dbgf.close();
return;
}
switch (rpcCommandType) {
case ImprovRPCType::Command_Wifi: parseWiFiCommand(rpcData); break;
case ImprovRPCType::Request_State: {
uint8_t improvState = 0x02; //authorized
if (WLED_WIFI_CONFIGURED) improvState = 0x03; //provisioning
if (Network.isConnected()) improvState = 0x04; //provisioned
sendImprovStateResponse(improvState, false);
if (improvState == 0x04) sendImprovRPCResponse(ImprovRPCType::Request_State);
break;
}
case ImprovRPCType::Request_Info: sendImprovInfoResponse(); break;
default: {
DIMPROV_PRINTF("Unknown RPC command %i\n",next);
sendImprovStateResponse(0x02, true);
}
}
//dbgf.close();
return;
}
if (packetByte < 6) { //check header
if (next != header[packetByte]) {
DIMPROV_PRINTLN(F("Invalid improv header"));
//dbgf.close();
return;
}
} else if (packetByte > 9) { //RPC data
rpcData[packetByte - 10] = next;
if (packetByte > 137) return; //prevent buffer overflow
}
}
}
checksum += next;
packetByte++;
}
//dbgf.close();
}
void sendImprovStateResponse(uint8_t state, bool error) {
if (!error && improvError > 0 && improvError < 3) sendImprovStateResponse(0x00, true);
if (error) improvError = state;
char out[11] = {'I','M','P','R','O','V'};
out[6] = IMPROV_VERSION;
out[7] = error? ImprovPacketType::Error_State : ImprovPacketType::Current_State;
out[8] = 1;
out[9] = state;
uint8_t checksum = 0;
for (uint8_t i = 0; i < 10; i++) checksum += out[i];
out[10] = checksum;
Serial.write((uint8_t*)out, 11);
Serial.write('\n');
}
void sendImprovRPCResponse(byte commandId) {
if (improvError > 0 && improvError < 3) sendImprovStateResponse(0x00, true);
uint8_t packetLen = 12;
char out[64] = {'I','M','P','R','O','V'};
out[6] = IMPROV_VERSION;
out[7] = ImprovPacketType::RPC_Response;
out[8] = 2; //Length (set below)
out[9] = commandId;
out[10] = 0; //Data len (set below)
out[11] = '\0'; //URL len (set below)
if (Network.isConnected())
{
IPAddress localIP = Network.localIP();
uint8_t len = sprintf(out+12, "http://%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
if (len > 24) return; //sprintf fail?
out[11] = len;
out[10] = 1 + len;
out[8] = 3 + len; //RPC command type + data len + url len + url
packetLen = 13 + len;
}
uint8_t checksum = 0;
for (uint8_t i = 0; i < packetLen -1; i++) checksum += out[i];
out[packetLen -1] = checksum;
Serial.write((uint8_t*)out, packetLen);
Serial.write('\n');
improvActive = 1; //no longer provisioning
}
void sendImprovInfoResponse() {
if (improvError > 0 && improvError < 3) sendImprovStateResponse(0x00, true);
uint8_t packetLen = 12;
char out[128] = {'I','M','P','R','O','V'};
out[6] = IMPROV_VERSION;
out[7] = ImprovPacketType::RPC_Response;
//out[8] = 2; //Length (set below)
out[9] = ImprovRPCType::Request_Info;
//out[10] = 0; //Data len (set below)
out[11] = 4; //Firmware len ("WLED")
out[12] = 'W'; out[13] = 'L'; out[14] = 'E'; out[15] = 'D';
uint8_t lengthSum = 17;
uint8_t vlen = sprintf_P(out+lengthSum,PSTR("0.13.0-b5/%i"),VERSION);
out[16] = vlen; lengthSum += vlen;
uint8_t hlen = 7;
#ifdef ESP8266
strcpy(out+lengthSum+1,"esp8266");
#else
hlen = 5;
strcpy(out+lengthSum+1,"esp32");
#endif
out[lengthSum] = hlen;
lengthSum += hlen + 1;
//Use serverDescription if it has been changed from the default "WLED", else mDNS name
bool useMdnsName = (strcmp(serverDescription, "WLED") == 0 && strlen(cmDNS) > 0);
strcpy(out+lengthSum+1,useMdnsName ? cmDNS : serverDescription);
uint8_t nlen = strlen(useMdnsName ? cmDNS : serverDescription);
out[lengthSum] = nlen;
lengthSum += nlen + 1;
packetLen = lengthSum +1;
out[8] = lengthSum -9;
out[10] = lengthSum -11;
uint8_t checksum = 0;
for (uint8_t i = 0; i < packetLen -1; i++) checksum += out[i];
out[packetLen -1] = checksum;
Serial.write((uint8_t*)out, packetLen);
Serial.write('\n');
DIMPROV_PRINT("Info checksum");
DIMPROV_PRINTLN(checksum);
}
void parseWiFiCommand(char* rpcData) {
uint8_t len = rpcData[0];
if (!len || len > 126) return;
uint8_t ssidLen = rpcData[1];
if (ssidLen > len -1 || ssidLen > 32) return;
memset(clientSSID, 0, 32);
memcpy(clientSSID, rpcData+2, ssidLen);
memset(clientPass, 0, 64);
if (len > ssidLen +1) {
uint8_t passLen = rpcData[2+ssidLen];
memset(clientPass, 0, 64);
memcpy(clientPass, rpcData+3+ssidLen, passLen);
}
sendImprovStateResponse(0x03); //provisioning
improvActive = 2;
forceReconnect = true;
serializeConfig();
}

View File

@ -205,8 +205,12 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
if (set < 2) stop = start + 1; if (set < 2) stop = start + 1;
for (uint16_t i = start; i < stop; i++) { for (uint16_t i = start; i < stop; i++) {
if (strip.gammaCorrectCol) {
strip.setPixelColor(i, strip.gamma8(rgbw[0]), strip.gamma8(rgbw[1]), strip.gamma8(rgbw[2]), strip.gamma8(rgbw[3]));
} else {
strip.setPixelColor(i, rgbw[0], rgbw[1], rgbw[2], rgbw[3]); strip.setPixelColor(i, rgbw[0], rgbw[1], rgbw[2], rgbw[3]);
} }
}
if (!set) start++; if (!set) start++;
set = 0; set = 0;
} }
@ -522,7 +526,7 @@ void serializeInfo(JsonObject root)
leds[F("fps")] = strip.getFps(); leds[F("fps")] = strip.getFps();
leds[F("maxpwr")] = (strip.currentMilliamps)? strip.ablMilliampsMax : 0; leds[F("maxpwr")] = (strip.currentMilliamps)? strip.ablMilliampsMax : 0;
leds[F("maxseg")] = strip.getMaxSegments(); leds[F("maxseg")] = strip.getMaxSegments();
leds[F("seglock")] = false; //will be used in the future to prevent modifications to segment config //leds[F("seglock")] = false; //might be used in the future to prevent modifications to segment config
root[F("str")] = syncToggleReceive; root[F("str")] = syncToggleReceive;
@ -584,7 +588,7 @@ void serializeInfo(JsonObject root)
root[F("resetReason0")] = (int)rtc_get_reset_reason(0); root[F("resetReason0")] = (int)rtc_get_reset_reason(0);
root[F("resetReason1")] = (int)rtc_get_reset_reason(1); root[F("resetReason1")] = (int)rtc_get_reset_reason(1);
#endif #endif
root[F("lwip")] = 0; root[F("lwip")] = 0; //deprecated
#else #else
root[F("arch")] = "esp8266"; root[F("arch")] = "esp8266";
root[F("core")] = ESP.getCoreVersion(); root[F("core")] = ESP.getCoreVersion();

View File

@ -125,6 +125,11 @@ bool PinManagerClass::isPinOk(byte gpio, bool output)
return false; return false;
} }
PinOwner PinManagerClass::getPinOwner(byte gpio) {
if (!isPinOk(gpio, false)) return PinOwner::None;
return ownerTag[gpio];
}
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
byte PinManagerClass::allocateLedc(byte channels) byte PinManagerClass::allocateLedc(byte channels)
{ {

View File

@ -92,6 +92,8 @@ class PinManagerClass {
bool isPinAllocated(byte gpio, PinOwner tag = PinOwner::None); bool isPinAllocated(byte gpio, PinOwner tag = PinOwner::None);
bool isPinOk(byte gpio, bool output = true); bool isPinOk(byte gpio, bool output = true);
PinOwner getPinOwner(byte gpio);
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
byte allocateLedc(byte channels); byte allocateLedc(byte channels);
void deallocateLedc(byte pos, byte channels); void deallocateLedc(byte pos, byte channels);

View File

@ -42,7 +42,7 @@ bool oappendi(int i)
bool oappend(const char* txt) bool oappend(const char* txt)
{ {
uint16_t len = strlen(txt); uint16_t len = strlen(txt);
if (olen + len >= OMAX) if (olen + len >= SETTINGS_STACK_BUF_SIZE)
return false; // buffer full return false; // buffer full
strcpy(obuf + olen, txt); strcpy(obuf + olen, txt);
olen += len; olen += len;
@ -303,7 +303,7 @@ void WLED::setup()
#ifdef WLED_DEBUG #ifdef WLED_DEBUG
pinManager.allocatePin(1, true, PinOwner::DebugOut); // GPIO1 reserved for debug output pinManager.allocatePin(1, true, PinOwner::DebugOut); // GPIO1 reserved for debug output
#endif #endif
#ifdef WLED_USE_DMX //reserve GPIO2 as hardcoded DMX pin #ifdef WLED_ENABLE_DMX //reserve GPIO2 as hardcoded DMX pin
pinManager.allocatePin(2, true, PinOwner::DMX); pinManager.allocatePin(2, true, PinOwner::DMX);
#endif #endif
@ -374,6 +374,8 @@ void WLED::setup()
sprintf(mqttClientID + 5, "%*s", 6, escapedMac.c_str() + 6); sprintf(mqttClientID + 5, "%*s", 6, escapedMac.c_str() + 6);
} }
if (Serial.available() > 0 && Serial.peek() == 'I') handleImprovPacket();
strip.service(); strip.service();
#ifndef WLED_DISABLE_OTA #ifndef WLED_DISABLE_OTA
@ -391,6 +393,8 @@ void WLED::setup()
#ifdef WLED_ENABLE_DMX #ifdef WLED_ENABLE_DMX
initDMX(); initDMX();
#endif #endif
if (Serial.available() > 0 && Serial.peek() == 'I') handleImprovPacket();
// HTTP server page init // HTTP server page init
initServer(); initServer();
@ -720,14 +724,26 @@ void WLED::handleConnection()
interfacesInited = false; interfacesInited = false;
initConnection(); initConnection();
} }
if (now - lastReconnectAttempt > ((stac) ? 300000 : 20000) && WLED_WIFI_CONFIGURED) //send improv failed 6 seconds after second init attempt (24 sec. after provisioning)
if (improvActive > 2 && now - lastReconnectAttempt > 6000) {
sendImprovStateResponse(0x03, true);
improvActive = 2;
}
if (now - lastReconnectAttempt > ((stac) ? 300000 : 18000) && WLED_WIFI_CONFIGURED) {
if (improvActive == 2) improvActive = 3;
initConnection(); initConnection();
}
if (!apActive && now - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == AP_BEHAVIOR_NO_CONN)) if (!apActive && now - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == AP_BEHAVIOR_NO_CONN))
initAP(); initAP();
} else if (!interfacesInited) { //newly connected } else if (!interfacesInited) { //newly connected
DEBUG_PRINTLN(""); DEBUG_PRINTLN("");
DEBUG_PRINT(F("Connected! IP address: ")); DEBUG_PRINT(F("Connected! IP address: "));
DEBUG_PRINTLN(Network.localIP()); DEBUG_PRINTLN(Network.localIP());
if (improvActive) {
if (improvError == 3) sendImprovStateResponse(0x00, true);
sendImprovStateResponse(0x04);
if (improvActive > 1) sendImprovRPCResponse(0x01);
}
initInterfaces(); initInterfaces();
userConnected(); userConnected();
usermods.connected(); usermods.connected();

View File

@ -3,12 +3,12 @@
/* /*
Main sketch, global variable declarations Main sketch, global variable declarations
@title WLED project sketch @title WLED project sketch
@version 0.13.0-b4 @version 0.13.0-b5
@author Christian Schwinne @author Christian Schwinne
*/ */
// version code in format yymmddb (b = daily build) // version code in format yymmddb (b = daily build)
#define VERSION 2110110 #define VERSION 2111170
//uncomment this if you have a "my_config.h" file you'd like to use //uncomment this if you have a "my_config.h" file you'd like to use
//#define WLED_USE_MY_CONFIG //#define WLED_USE_MY_CONFIG
@ -507,6 +507,10 @@ WLED_GLOBAL byte timerWeekday[] _INIT_N(({ 255, 255, 255, 255, 255, 255, 255, 25
// blynk // blynk
WLED_GLOBAL bool blynkEnabled _INIT(false); WLED_GLOBAL bool blynkEnabled _INIT(false);
//improv
WLED_GLOBAL byte improvActive _INIT(0); //0: no improv packet received, 1: improv active, 2: provisioning
WLED_GLOBAL byte improvError _INIT(0);
//playlists //playlists
WLED_GLOBAL int16_t currentPlaylist _INIT(-1); WLED_GLOBAL int16_t currentPlaylist _INIT(-1);
//still used for "PL=~" HTTP API command //still used for "PL=~" HTTP API command

View File

@ -16,7 +16,7 @@ enum class AdaState {
Data_Blue, Data_Blue,
TPM2_Header_Type, TPM2_Header_Type,
TPM2_Header_CountHi, TPM2_Header_CountHi,
TPM2_Header_CountLo TPM2_Header_CountLo,
}; };
void handleSerial() void handleSerial()
@ -41,7 +41,12 @@ void handleSerial()
else if (next == 0xC9) { //TPM2 start byte else if (next == 0xC9) { //TPM2 start byte
state = AdaState::TPM2_Header_Type; state = AdaState::TPM2_Header_Type;
} }
else if (next == '{') { //JSON API else if (next == 'I') {
handleImprovPacket();
return;
} else if (next == 'v') {
Serial.print("WLED"); Serial.write(' '); Serial.println(VERSION);
} else if (next == '{') { //JSON API
bool verboseResponse = false; bool verboseResponse = false;
{ {
DynamicJsonDocument doc(JSON_BUFFER_SIZE); DynamicJsonDocument doc(JSON_BUFFER_SIZE);
@ -61,6 +66,7 @@ void handleSerial()
serializeInfo(info); serializeInfo(info);
serializeJson(doc, Serial); serializeJson(doc, Serial);
Serial.println();
} }
} }
break; break;

View File

@ -362,9 +362,10 @@ void serveMessage(AsyncWebServerRequest* request, uint16_t code, const String& h
String settingsProcessor(const String& var) String settingsProcessor(const String& var)
{ {
if (var == "CSS") { if (var == "CSS") {
char buf[2048]; char buf[SETTINGS_STACK_BUF_SIZE];
buf[0] = 0; buf[0] = 0;
getSettingsJS(optionType, buf); getSettingsJS(optionType, buf);
//Serial.println(uxTaskGetStackHighWaterMark(NULL));
return String(buf); return String(buf);
} }