Merge branch 'master' into dev
This commit is contained in:
commit
b58efa3df0
@ -2,6 +2,14 @@
|
|||||||
|
|
||||||
### Builds after release 0.12.0
|
### Builds after release 0.12.0
|
||||||
|
|
||||||
|
#### Build 2106302
|
||||||
|
|
||||||
|
- Fixed settings page broken by using "%" in input fields
|
||||||
|
|
||||||
|
#### Build 2106301
|
||||||
|
|
||||||
|
- Fixed a problem with disabled buttons reverting to pin 0 causing conflict
|
||||||
|
|
||||||
#### Build 2106300
|
#### Build 2106300
|
||||||
|
|
||||||
- Version bump to 0.13.0-b0 "Toki"
|
- Version bump to 0.13.0-b0 "Toki"
|
||||||
|
@ -267,7 +267,7 @@ build_flags = ${common.build_flags_esp8266} -D LEDPIN=1 -D WLED_DISABLE_INFRARED
|
|||||||
|
|
||||||
[env:esp32dev]
|
[env:esp32dev]
|
||||||
board = esp32dev
|
board = esp32dev
|
||||||
platform = espressif32@3.2
|
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
|
build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
@ -276,7 +276,7 @@ lib_ignore =
|
|||||||
|
|
||||||
[env:esp32_eth]
|
[env:esp32_eth]
|
||||||
board = esp32-poe
|
board = esp32-poe
|
||||||
platform = espressif32@3.2
|
platform = espressif32@2.0
|
||||||
upload_speed = 921600
|
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
|
||||||
@ -354,19 +354,22 @@ build_flags = ${common.build_flags_esp8266} -D LEDPIN=12 -D IRPIN=-1 -D RLYPIN=2
|
|||||||
|
|
||||||
[env:wemos_shield_esp32]
|
[env:wemos_shield_esp32]
|
||||||
board = esp32dev
|
board = esp32dev
|
||||||
platform = espressif32@^3.2
|
platform = espressif32@3.2
|
||||||
upload_port = /dev/cu.SLAB_USBtoUART
|
|
||||||
monitor_port = /dev/cu.SLAB_USBtoUART
|
|
||||||
upload_speed = 460800
|
upload_speed = 460800
|
||||||
build_unflags = ${common.build_unflags}
|
build_unflags = ${common.build_unflags}
|
||||||
build_flags = ${common.build_flags_esp32} -D LEDPIN=16 -D RLYPIN=19 -D BTNPIN=17 -D IRPIN=18
|
build_flags = ${common.build_flags_esp32}
|
||||||
-D USERMOD_DALLASTEMPERATURE
|
-D LEDPIN=16
|
||||||
-D TEMPERATURE_PIN=23
|
-D RLYPIN=19
|
||||||
-D USERMOD_FOUR_LINE_DISPLAY
|
-D BTNPIN=17
|
||||||
|
-D UWLED_USE_MY_CONFIG
|
||||||
|
; -D USERMOD_DALLASTEMPERATURE
|
||||||
|
; -D USERMOD_DALLASTEMPERATURE_CELCIUS
|
||||||
|
; -D USERMOD_FOUR_LINE_DISPLAY
|
||||||
|
; -D TEMPERATURE_PIN=21
|
||||||
lib_deps = ${env.lib_deps}
|
lib_deps = ${env.lib_deps}
|
||||||
OneWire@~2.3.5
|
; OneWire@~2.3.5
|
||||||
U8g2@~2.28.8
|
; milesburton/DallasTemperature@^3.9.0
|
||||||
Wire
|
; U8g2@~2.27.2
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
ESPAsyncTCP
|
ESPAsyncTCP
|
||||||
ESPAsyncUDP
|
ESPAsyncUDP
|
||||||
@ -456,3 +459,4 @@ monitor_filters = esp32_exception_decoder
|
|||||||
lib_ignore =
|
lib_ignore =
|
||||||
ESPAsyncTCP
|
ESPAsyncTCP
|
||||||
ESPAsyncUDP
|
ESPAsyncUDP
|
||||||
|
|
@ -9,7 +9,6 @@
|
|||||||
<a href="https://gitpod.io/#https://github.com/Aircoookie/WLED"><img src="https://img.shields.io/badge/Gitpod-ready--to--code-blue?style=flat-square&logo=gitpod"></a>
|
<a href="https://gitpod.io/#https://github.com/Aircoookie/WLED"><img src="https://img.shields.io/badge/Gitpod-ready--to--code-blue?style=flat-square&logo=gitpod"></a>
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
# Welcome to my project WLED! ✨
|
# Welcome to my project WLED! ✨
|
||||||
|
|
||||||
A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B, WS2811, SK6812) LEDs or also SPI based chipsets like the WS2801 and APA102!
|
A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B, WS2811, SK6812) LEDs or also SPI based chipsets like the WS2801 and APA102!
|
||||||
|
72
usermods/ST7789_display/README.md
Normal file
72
usermods/ST7789_display/README.md
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
# ST7789 TFT IPS Color display 240x240pxwith ESP32 boards
|
||||||
|
|
||||||
|
This usermod allow to use 240x240 display to display following:
|
||||||
|
|
||||||
|
* Network SSID;
|
||||||
|
* IP address;
|
||||||
|
* Brightness;
|
||||||
|
* Chosen effect;
|
||||||
|
* Chosen palette;
|
||||||
|
* Estimated current in mA;
|
||||||
|
|
||||||
|
## Hardware
|
||||||
|
|
||||||
|
***
|
||||||
|
![Hardware](images/ST7789_guide.jpg)
|
||||||
|
|
||||||
|
## Library used
|
||||||
|
|
||||||
|
[Bodmer/TFT_eSPI](https://github.com/Bodmer/TFT_eSPI)
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
### Platformio.ini changes
|
||||||
|
|
||||||
|
In the `platformio.ini` file, uncomment the `TFT_eSPI` line within the [common] section, under `lib_deps`:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
# platformio.ini
|
||||||
|
...
|
||||||
|
[common]
|
||||||
|
...
|
||||||
|
lib_deps =
|
||||||
|
...
|
||||||
|
#For use of the TTGO T-Display ESP32 Module with integrated TFT display uncomment the following line
|
||||||
|
#TFT_eSPI
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
Also, while in the `platformio.ini` file, you must change the environment setup to build for just the esp32dev platform as follows:
|
||||||
|
|
||||||
|
Add lines to section:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
default_envs = esp32dev
|
||||||
|
build_flags = ${common.build_flags_esp32}
|
||||||
|
-D USERMOD_ST7789_DISPLAY
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Save the `platformio.ini` file. Once this is saved, the required library files should be automatically downloaded for modifications in a later step.
|
||||||
|
|
||||||
|
### TFT_eSPI Library Adjustments
|
||||||
|
|
||||||
|
We need to modify a file in the `TFT_eSPI` library. If you followed the directions to modify and save the `platformio.ini` file above, the `User_Setup_Select.h` file can be found in the `/.pio/libdeps/esp32dev/TFT_eSPI` folder.
|
||||||
|
|
||||||
|
Modify the `User_Setup_Select.h` file as follows:
|
||||||
|
|
||||||
|
* Comment out the following line (which is the 'default' setup file):
|
||||||
|
|
||||||
|
```ini
|
||||||
|
//#include <User_Setup.h> // Default setup is root library folder
|
||||||
|
```
|
||||||
|
|
||||||
|
* Add following line:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
#include <User_Setups/Setup_ST7789_Display.h> // Setup file for ESP32 ST7789V SPI bus TFT
|
||||||
|
```
|
||||||
|
|
||||||
|
* Copy file `"Setup_ST7789_Display.h"` from usermod folder to `/.pio/libdeps/esp32dev/TFT_eSPI/User_Setups`
|
350
usermods/ST7789_display/ST7789_display.h
Normal file
350
usermods/ST7789_display/ST7789_display.h
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
// Credits to @mrVanboy, @gwaland and my dearest friend @westward
|
||||||
|
// Also for @spiff72 for usermod TTGO-T-Display
|
||||||
|
// 210217
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "wled.h"
|
||||||
|
#include <TFT_eSPI.h>
|
||||||
|
#include <SPI.h>
|
||||||
|
|
||||||
|
#define USERMOD_ST7789_DISPLAY 97
|
||||||
|
|
||||||
|
#ifndef TFT_DISPOFF
|
||||||
|
#define TFT_DISPOFF 0x28
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TFT_SLPIN
|
||||||
|
#define TFT_SLPIN 0x10
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TFT_MOSI 21
|
||||||
|
#define TFT_SCLK 22
|
||||||
|
#define TFT_DC 18
|
||||||
|
#define TFT_RST 5
|
||||||
|
#define TFT_BL 26 // Display backlight control pin
|
||||||
|
|
||||||
|
TFT_eSPI tft = TFT_eSPI(240, 240); // Invoke custom library
|
||||||
|
|
||||||
|
// How often we are redrawing screen
|
||||||
|
#define USER_LOOP_REFRESH_RATE_MS 1000
|
||||||
|
|
||||||
|
|
||||||
|
//class name. Use something descriptive and leave the ": public Usermod" part :)
|
||||||
|
class St7789DisplayUsermod : public Usermod {
|
||||||
|
private:
|
||||||
|
//Private class members. You can declare variables and functions only accessible to your usermod here
|
||||||
|
unsigned long lastTime = 0;
|
||||||
|
|
||||||
|
bool displayTurnedOff = false;
|
||||||
|
long lastRedraw = 0;
|
||||||
|
// needRedraw marks if redraw is required to prevent often redrawing.
|
||||||
|
bool needRedraw = true;
|
||||||
|
// Next variables hold the previous known values to determine if redraw is required.
|
||||||
|
String knownSsid = "";
|
||||||
|
IPAddress knownIp;
|
||||||
|
uint8_t knownBrightness = 0;
|
||||||
|
uint8_t knownMode = 0;
|
||||||
|
uint8_t knownPalette = 0;
|
||||||
|
uint8_t tftcharwidth = 19; // Number of chars that fit on screen with text size set to 2
|
||||||
|
long lastUpdate = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
//Functions called by WLED
|
||||||
|
|
||||||
|
/*
|
||||||
|
* setup() is called once at boot. WiFi is not yet connected at this point.
|
||||||
|
* You can use it to initialize variables, sensors or similar.
|
||||||
|
*/
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
tft.init();
|
||||||
|
tft.setRotation(0); //Rotation here is set up for the text to be readable with the port on the left. Use 1 to flip.
|
||||||
|
tft.fillScreen(TFT_BLACK);
|
||||||
|
tft.setTextColor(TFT_RED);
|
||||||
|
tft.setCursor(60, 100);
|
||||||
|
tft.setTextDatum(MC_DATUM);
|
||||||
|
tft.setTextSize(2);
|
||||||
|
tft.print("Loading...");
|
||||||
|
if (TFT_BL > 0)
|
||||||
|
{ // TFT_BL has been set in the TFT_eSPI library
|
||||||
|
pinMode(TFT_BL, OUTPUT); // Set backlight pin to output mode
|
||||||
|
digitalWrite(TFT_BL, HIGH); // Turn backlight on.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* connected() is called every time the WiFi is (re)connected
|
||||||
|
* Use it to initialize network interfaces
|
||||||
|
*/
|
||||||
|
void connected() {
|
||||||
|
//Serial.println("Connected to WiFi!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* loop() is called continuously. Here you can check for events, read sensors, etc.
|
||||||
|
*
|
||||||
|
* Tips:
|
||||||
|
* 1. You can use "if (WLED_CONNECTED)" to check for a successful network connection.
|
||||||
|
* Additionally, "if (WLED_MQTT_CONNECTED)" is available to check for a connection to an MQTT broker.
|
||||||
|
*
|
||||||
|
* 2. Try to avoid using the delay() function. NEVER use delays longer than 10 milliseconds.
|
||||||
|
* Instead, use a timer check as shown here.
|
||||||
|
*/
|
||||||
|
void loop() {
|
||||||
|
// Check if we time interval for redrawing passes.
|
||||||
|
if (millis() - lastUpdate < USER_LOOP_REFRESH_RATE_MS)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lastUpdate = millis();
|
||||||
|
|
||||||
|
// Turn off display after 5 minutes with no change.
|
||||||
|
if(!displayTurnedOff && millis() - lastRedraw > 5*60*1000)
|
||||||
|
{
|
||||||
|
digitalWrite(TFT_BL, LOW); // Turn backlight off.
|
||||||
|
displayTurnedOff = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if values which are shown on display changed from the last time.
|
||||||
|
if (((apActive) ? String(apSSID) : WiFi.SSID()) != knownSsid)
|
||||||
|
{
|
||||||
|
needRedraw = true;
|
||||||
|
}
|
||||||
|
else if (knownIp != (apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP()))
|
||||||
|
{
|
||||||
|
needRedraw = true;
|
||||||
|
}
|
||||||
|
else if (knownBrightness != bri)
|
||||||
|
{
|
||||||
|
needRedraw = true;
|
||||||
|
}
|
||||||
|
else if (knownMode != strip.getMode())
|
||||||
|
{
|
||||||
|
needRedraw = true;
|
||||||
|
}
|
||||||
|
else if (knownPalette != strip.getSegment(0).palette)
|
||||||
|
{
|
||||||
|
needRedraw = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!needRedraw)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
needRedraw = false;
|
||||||
|
|
||||||
|
if (displayTurnedOff)
|
||||||
|
{
|
||||||
|
digitalWrite(TFT_BL, TFT_BACKLIGHT_ON); // Turn backlight on.
|
||||||
|
displayTurnedOff = false;
|
||||||
|
}
|
||||||
|
lastRedraw = millis();
|
||||||
|
|
||||||
|
// Update last known values.
|
||||||
|
#if defined(ESP8266)
|
||||||
|
knownSsid = apActive ? WiFi.softAPSSID() : WiFi.SSID();
|
||||||
|
#else
|
||||||
|
knownSsid = WiFi.SSID();
|
||||||
|
#endif
|
||||||
|
knownIp = apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP();
|
||||||
|
knownBrightness = bri;
|
||||||
|
knownMode = strip.getMode();
|
||||||
|
knownPalette = strip.getSegment(0).palette;
|
||||||
|
|
||||||
|
tft.fillScreen(TFT_BLACK);
|
||||||
|
tft.setTextSize(2);
|
||||||
|
// First row with Wifi name
|
||||||
|
tft.setTextColor(TFT_SILVER);
|
||||||
|
tft.setCursor(3, 40);
|
||||||
|
tft.print(knownSsid.substring(0, tftcharwidth > 1 ? tftcharwidth - 1 : 0));
|
||||||
|
// Print `~` char to indicate that SSID is longer, than our dicplay
|
||||||
|
if (knownSsid.length() > tftcharwidth)
|
||||||
|
tft.print("~");
|
||||||
|
|
||||||
|
// Second row with AP IP and Password or IP
|
||||||
|
tft.setTextColor(TFT_GREEN);
|
||||||
|
tft.setTextSize(2);
|
||||||
|
tft.setCursor(3, 64);
|
||||||
|
// Print AP IP and password in AP mode or knownIP if AP not active.
|
||||||
|
|
||||||
|
if (apActive)
|
||||||
|
{
|
||||||
|
tft.setTextColor(TFT_YELLOW);
|
||||||
|
tft.print("AP IP: ");
|
||||||
|
tft.print(knownIp);
|
||||||
|
tft.setCursor(3,86);
|
||||||
|
tft.setTextColor(TFT_YELLOW);
|
||||||
|
tft.print("AP Pass:");
|
||||||
|
tft.print(apPass);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tft.setTextColor(TFT_GREEN);
|
||||||
|
tft.print("IP: ");
|
||||||
|
tft.print(knownIp);
|
||||||
|
tft.setCursor(3,86);
|
||||||
|
//tft.print("Signal Strength: ");
|
||||||
|
//tft.print(i.wifi.signal);
|
||||||
|
tft.setTextColor(TFT_WHITE);
|
||||||
|
tft.print("Bri: ");
|
||||||
|
tft.print(((float(bri)/255)*100),0);
|
||||||
|
tft.print("%");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Third row with mode name
|
||||||
|
tft.setCursor(3, 108);
|
||||||
|
uint8_t qComma = 0;
|
||||||
|
bool insideQuotes = false;
|
||||||
|
uint8_t printedChars = 0;
|
||||||
|
char singleJsonSymbol;
|
||||||
|
// Find the mode name in JSON
|
||||||
|
for (size_t i = 0; i < strlen_P(JSON_mode_names); i++)
|
||||||
|
{
|
||||||
|
singleJsonSymbol = pgm_read_byte_near(JSON_mode_names + i);
|
||||||
|
switch (singleJsonSymbol)
|
||||||
|
{
|
||||||
|
case '"':
|
||||||
|
insideQuotes = !insideQuotes;
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
case ']':
|
||||||
|
break;
|
||||||
|
case ',':
|
||||||
|
qComma++;
|
||||||
|
default:
|
||||||
|
if (!insideQuotes || (qComma != knownMode))
|
||||||
|
break;
|
||||||
|
tft.setTextColor(TFT_MAGENTA);
|
||||||
|
tft.print(singleJsonSymbol);
|
||||||
|
printedChars++;
|
||||||
|
}
|
||||||
|
if ((qComma > knownMode) || (printedChars > tftcharwidth - 1))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Fourth row with palette name
|
||||||
|
tft.setTextColor(TFT_YELLOW);
|
||||||
|
tft.setCursor(3, 130);
|
||||||
|
qComma = 0;
|
||||||
|
insideQuotes = false;
|
||||||
|
printedChars = 0;
|
||||||
|
// Looking for palette name in JSON.
|
||||||
|
for (size_t i = 0; i < strlen_P(JSON_palette_names); i++)
|
||||||
|
{
|
||||||
|
singleJsonSymbol = pgm_read_byte_near(JSON_palette_names + i);
|
||||||
|
switch (singleJsonSymbol)
|
||||||
|
{
|
||||||
|
case '"':
|
||||||
|
insideQuotes = !insideQuotes;
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
case ']':
|
||||||
|
break;
|
||||||
|
case ',':
|
||||||
|
qComma++;
|
||||||
|
default:
|
||||||
|
if (!insideQuotes || (qComma != knownPalette))
|
||||||
|
break;
|
||||||
|
tft.print(singleJsonSymbol);
|
||||||
|
printedChars++;
|
||||||
|
}
|
||||||
|
// The following is modified from the code from the u8g2/u8g8 based code (knownPalette was knownMode)
|
||||||
|
if ((qComma > knownPalette) || (printedChars > tftcharwidth - 1))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Fifth row with estimated mA usage
|
||||||
|
tft.setTextColor(TFT_SILVER);
|
||||||
|
tft.setCursor(3, 152);
|
||||||
|
// Print estimated milliamp usage (must specify the LED type in LED prefs for this to be a reasonable estimate).
|
||||||
|
tft.print("Current: ");
|
||||||
|
tft.print(strip.currentMilliamps);
|
||||||
|
tft.print("mA");
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API.
|
||||||
|
* Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI.
|
||||||
|
* Below it is shown how this could be used for e.g. a light sensor
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
void addToJsonInfo(JsonObject& root)
|
||||||
|
{
|
||||||
|
int reading = 20;
|
||||||
|
//this code adds "u":{"Light":[20," lux"]} to the info object
|
||||||
|
JsonObject user = root["u"];
|
||||||
|
if (user.isNull()) user = root.createNestedObject("u");
|
||||||
|
|
||||||
|
JsonArray lightArr = user.createNestedArray("Light"); //name
|
||||||
|
lightArr.add(reading); //value
|
||||||
|
lightArr.add(" lux"); //unit
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
|
||||||
|
* Values in the state object may be modified by connected clients
|
||||||
|
*/
|
||||||
|
void addToJsonState(JsonObject& root)
|
||||||
|
{
|
||||||
|
//root["user0"] = userVar0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
|
||||||
|
* Values in the state object may be modified by connected clients
|
||||||
|
*/
|
||||||
|
void readFromJsonState(JsonObject& root)
|
||||||
|
{
|
||||||
|
userVar0 = root["user0"] | userVar0; //if "user0" key exists in JSON, update, else keep old value
|
||||||
|
//if (root["bri"] == 255) Serial.println(F("Don't burn down your garage!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object.
|
||||||
|
* It will be called by WLED when settings are actually saved (for example, LED settings are saved)
|
||||||
|
* If you want to force saving the current state, use serializeConfig() in your loop().
|
||||||
|
*
|
||||||
|
* CAUTION: serializeConfig() will initiate a filesystem write operation.
|
||||||
|
* It might cause the LEDs to stutter and will cause flash wear if called too often.
|
||||||
|
* Use it sparingly and always in the loop, never in network callbacks!
|
||||||
|
*
|
||||||
|
* addToConfig() will also not yet add your setting to one of the settings pages automatically.
|
||||||
|
* To make that work you still have to add the setting to the HTML, xml.cpp and set.cpp manually.
|
||||||
|
*
|
||||||
|
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
||||||
|
*/
|
||||||
|
void addToConfig(JsonObject& root)
|
||||||
|
{
|
||||||
|
JsonObject top = root.createNestedObject("exampleUsermod");
|
||||||
|
top["great"] = userVar0; //save this var persistently whenever settings are saved
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* readFromConfig() can be used to read back the custom settings you added with addToConfig().
|
||||||
|
* This is called by WLED when settings are loaded (currently this only happens once immediately after boot)
|
||||||
|
*
|
||||||
|
* readFromConfig() is called BEFORE setup(). This means you can use your persistent values in setup() (e.g. pin assignments, buffer sizes),
|
||||||
|
* but also that if you want to write persistent values to a dynamic buffer, you'd need to allocate it here instead of in setup.
|
||||||
|
* If you don't know what that is, don't fret. It most likely doesn't affect your use case :)
|
||||||
|
*/
|
||||||
|
void readFromConfig(JsonObject& root)
|
||||||
|
{
|
||||||
|
JsonObject top = root["top"];
|
||||||
|
userVar0 = top["great"] | 42; //The value right of the pipe "|" is the default value in case your setting was not present in cfg.json (e.g. first boot)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
|
||||||
|
* This could be used in the future for the system to determine whether your usermod is installed.
|
||||||
|
*/
|
||||||
|
uint16_t getId()
|
||||||
|
{
|
||||||
|
return USERMOD_ST7789_DISPLAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
//More methods can be added in the future, this example will then be extended.
|
||||||
|
//Your usermod will remain compatible as it does not need to implement all methods from the Usermod base class!
|
||||||
|
};
|
39
usermods/ST7789_display/Setup_ST7789_Display.h
Normal file
39
usermods/ST7789_display/Setup_ST7789_Display.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Setup for the ESP32 board with 1.5" 240x240 display
|
||||||
|
|
||||||
|
// See SetupX_Template.h for all options available
|
||||||
|
|
||||||
|
#define ST7789_DRIVER
|
||||||
|
#define TFT_SDA_READ // Display has a bidirectionsl SDA pin
|
||||||
|
|
||||||
|
#define TFT_WIDTH 240
|
||||||
|
#define TFT_HEIGHT 240
|
||||||
|
|
||||||
|
#define CGRAM_OFFSET // Library will add offsets required
|
||||||
|
|
||||||
|
//#define TFT_MISO -1
|
||||||
|
|
||||||
|
#define TFT_MOSI 21
|
||||||
|
#define TFT_SCLK 22
|
||||||
|
//#define TFT_CS 5
|
||||||
|
#define TFT_DC 18
|
||||||
|
#define TFT_RST 5
|
||||||
|
|
||||||
|
#define TFT_BL 26 // Display backlight control pin
|
||||||
|
|
||||||
|
#define TFT_BACKLIGHT_ON HIGH // HIGH or LOW are options
|
||||||
|
|
||||||
|
#define LOAD_GLCD
|
||||||
|
#define LOAD_FONT2
|
||||||
|
#define LOAD_FONT4
|
||||||
|
#define LOAD_FONT6
|
||||||
|
#define LOAD_FONT7
|
||||||
|
#define LOAD_FONT8
|
||||||
|
#define LOAD_GFXFF
|
||||||
|
|
||||||
|
//#define SMOOTH_FONT
|
||||||
|
|
||||||
|
//#define SPI_FREQUENCY 27000000
|
||||||
|
#define SPI_FREQUENCY 40000000 // Maximum for ILI9341
|
||||||
|
|
||||||
|
|
||||||
|
#define SPI_READ_FREQUENCY 6000000 // 6 MHz is the maximum SPI read speed for the ST7789V
|
BIN
usermods/ST7789_display/images/ST7789_Guide.jpg
Normal file
BIN
usermods/ST7789_display/images/ST7789_Guide.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 175 KiB |
@ -23,7 +23,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
getStringFromJson(serverDescription, id[F("name")], 33);
|
getStringFromJson(serverDescription, id[F("name")], 33);
|
||||||
getStringFromJson(alexaInvocationName, id[F("inv")], 33);
|
getStringFromJson(alexaInvocationName, id[F("inv")], 33);
|
||||||
|
|
||||||
JsonObject nw_ins_0 = doc["nw"][F("ins")][0];
|
JsonObject nw_ins_0 = doc["nw"]["ins"][0];
|
||||||
getStringFromJson(clientSSID, nw_ins_0[F("ssid")], 33);
|
getStringFromJson(clientSSID, nw_ins_0[F("ssid")], 33);
|
||||||
//int nw_ins_0_pskl = nw_ins_0[F("pskl")];
|
//int nw_ins_0_pskl = nw_ins_0[F("pskl")];
|
||||||
//The WiFi PSK is normally not contained in the regular file for security reasons.
|
//The WiFi PSK is normally not contained in the regular file for security reasons.
|
||||||
@ -126,7 +126,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
uint8_t s = 0;
|
uint8_t s = 0;
|
||||||
for (JsonObject btn : hw_btn_ins) {
|
for (JsonObject btn : hw_btn_ins) {
|
||||||
CJSON(buttonType[s], btn["type"]);
|
CJSON(buttonType[s], btn["type"]);
|
||||||
int8_t pin = btn[F("pin")][0] | -1;
|
int8_t pin = btn["pin"][0] | -1;
|
||||||
if (pin > -1 && pinManager.allocatePin(pin,false)) {
|
if (pin > -1 && pinManager.allocatePin(pin,false)) {
|
||||||
btnPin[s] = pin;
|
btnPin[s] = pin;
|
||||||
pinMode(btnPin[s], INPUT_PULLUP);
|
pinMode(btnPin[s], INPUT_PULLUP);
|
||||||
@ -731,7 +731,7 @@ bool deserializeConfigSec() {
|
|||||||
bool success = readObjectFromFile("/wsec.json", nullptr, &doc);
|
bool success = readObjectFromFile("/wsec.json", nullptr, &doc);
|
||||||
if (!success) return false;
|
if (!success) return false;
|
||||||
|
|
||||||
JsonObject nw_ins_0 = doc["nw"][F("ins")][0];
|
JsonObject nw_ins_0 = doc["nw"]["ins"][0];
|
||||||
getStringFromJson(clientPass, nw_ins_0["psk"], 65);
|
getStringFromJson(clientPass, nw_ins_0["psk"], 65);
|
||||||
|
|
||||||
JsonObject ap = doc["ap"];
|
JsonObject ap = doc["ap"];
|
||||||
|
@ -282,11 +282,11 @@ Color Order:
|
|||||||
<option value="4">BGR</option>
|
<option value="4">BGR</option>
|
||||||
<option value="5">GBR</option>
|
<option value="5">GBR</option>
|
||||||
</select><br>
|
</select><br>
|
||||||
<span id="p0d${i}">GPIO:</span><input type="number" name="L0${i}" min="0" max="33" required class="sml" onchange="UI()"/>
|
<span id="p0d${i}">GPIO:</span><input type="number" name="L0${i}" min="0" max="33" required class="s" onchange="UI()"/>
|
||||||
<span id="p1d${i}"></span><input type="number" name="L1${i}" min="0" max="33" class="sml" onchange="UI()"/>
|
<span id="p1d${i}"></span><input type="number" name="L1${i}" min="0" max="33" class="s" onchange="UI()"/>
|
||||||
<span id="p2d${i}"></span><input type="number" name="L2${i}" min="0" max="33" class="sml" onchange="UI()"/>
|
<span id="p2d${i}"></span><input type="number" name="L2${i}" min="0" max="33" class="s" onchange="UI()"/>
|
||||||
<span id="p3d${i}"></span><input type="number" name="L3${i}" min="0" max="33" class="sml" onchange="UI()"/>
|
<span id="p3d${i}"></span><input type="number" name="L3${i}" min="0" max="33" class="s" onchange="UI()"/>
|
||||||
<span id="p4d${i}"></span><input type="number" name="L4${i}" min="0" max="33" class="sml" onchange="UI()"/>
|
<span id="p4d${i}"></span><input type="number" name="L4${i}" min="0" max="33" class="s" onchange="UI()"/>
|
||||||
<br>
|
<br>
|
||||||
<span id="psd${i}">Start:</span> <input type="number" name="LS${i}" id="ls${i}" min="0" max="8191" value="${lastEnd(i)}" readonly required />
|
<span id="psd${i}">Start:</span> <input type="number" name="LS${i}" id="ls${i}" min="0" max="8191" value="${lastEnd(i)}" readonly required />
|
||||||
<div id="dig${i}" style="display:inline">
|
<div id="dig${i}" style="display:inline">
|
||||||
@ -310,7 +310,7 @@ Reverse (rotated 180°): <input type="checkbox" name="CV${i}">
|
|||||||
var c = gId("btns").innerHTML;
|
var c = gId("btns").innerHTML;
|
||||||
var bt = "BT" + i;
|
var bt = "BT" + i;
|
||||||
var be = "BE" + i;
|
var be = "BE" + i;
|
||||||
c += `Button ${i} GPIO: <input type="number" min="-1" max="40" name="${bt}" onchange="UI()" class="sml" value="${p}">`;
|
c += `Button ${i} GPIO: <input type="number" min="-1" max="40" name="${bt}" onchange="UI()" class="s" value="${p}">`;
|
||||||
c += `<select name="${be}">`
|
c += `<select name="${be}">`
|
||||||
c += `<option value="0" ${t==0?"selected":""}>Disabled</option>`;
|
c += `<option value="0" ${t==0?"selected":""}>Disabled</option>`;
|
||||||
c += `<option value="2" ${t==2?"selected":""}>Pushbutton</option>`;
|
c += `<option value="2" ${t==2?"selected":""}>Pushbutton</option>`;
|
||||||
@ -392,7 +392,7 @@ Reverse (rotated 180°): <input type="checkbox" name="CV${i}">
|
|||||||
</div><hr style="width:260px">
|
</div><hr style="width:260px">
|
||||||
<div id="btns"></div>
|
<div id="btns"></div>
|
||||||
Touch threshold: <input type="number" min="0" max="100" name="TT" required><br>
|
Touch threshold: <input type="number" min="0" max="100" name="TT" required><br>
|
||||||
IR GPIO: <input type="number" min="-1" max="40" name="IR" onchange="UI()" class="sml"><select name="IT" onchange="UI()">
|
IR GPIO: <input type="number" min="-1" max="40" name="IR" onchange="UI()" class="s"><select name="IT" onchange="UI()">
|
||||||
<option value="0">Remote disabled</option>
|
<option value="0">Remote disabled</option>
|
||||||
<option value="1">24-key RGB</option>
|
<option value="1">24-key RGB</option>
|
||||||
<option value="2">24-key with CT</option>
|
<option value="2">24-key with CT</option>
|
||||||
@ -406,7 +406,7 @@ Reverse (rotated 180°): <input type="checkbox" name="CV${i}">
|
|||||||
<div id="json" style="display:none;">JSON file: <input type="file" name="data" accept=".json"> <input type="button" value="Upload" onclick="uploadFile('/ir.json');"><br></div>
|
<div id="json" style="display:none;">JSON file: <input type="file" name="data" accept=".json"> <input type="button" value="Upload" onclick="uploadFile('/ir.json');"><br></div>
|
||||||
<div id="toast"></div>
|
<div id="toast"></div>
|
||||||
<a href="https://github.com/Aircoookie/WLED/wiki/Infrared-Control" target="_blank">IR info</a><br>
|
<a href="https://github.com/Aircoookie/WLED/wiki/Infrared-Control" target="_blank">IR info</a><br>
|
||||||
Relay pin: <input type="number" min="-1" max="40" name="RL" onchange="UI()" class="sml"> invert <input type="checkbox" name="RM"><span style="cursor: pointer;" onclick="off('RL')"> ×</span><br>
|
Relay pin: <input type="number" min="-1" max="40" name="RL" onchange="UI()" class="s"> invert <input type="checkbox" name="RM"><span style="cursor: pointer;" onclick="off('RL')"> ×</span><br>
|
||||||
<hr style="width:260px">
|
<hr style="width:260px">
|
||||||
<h3>Defaults</h3>
|
<h3>Defaults</h3>
|
||||||
Turn LEDs on after power up/reset: <input type="checkbox" name="BO"><br>
|
Turn LEDs on after power up/reset: <input type="checkbox" name="BO"><br>
|
||||||
|
@ -86,11 +86,11 @@
|
|||||||
td = tr.insertCell(0);
|
td = tr.insertCell(0);
|
||||||
td.innerHTML = `Button ${i}:`;
|
td.innerHTML = `Button ${i}:`;
|
||||||
td = tr.insertCell(1);
|
td = tr.insertCell(1);
|
||||||
td.innerHTML = `<input name="MP${i}" type="number" class="med" min="0" max="250" value="${p}" required>`;
|
td.innerHTML = `<input name="MP${i}" type="number" class="m" min="0" max="250" value="${p}" required>`;
|
||||||
td = tr.insertCell(2);
|
td = tr.insertCell(2);
|
||||||
td.innerHTML = `<input name="ML${i}" type="number" class="med" min="0" max="250" value="${l}" required>`;
|
td.innerHTML = `<input name="ML${i}" type="number" class="m" min="0" max="250" value="${l}" required>`;
|
||||||
td = tr.insertCell(3);
|
td = tr.insertCell(3);
|
||||||
td.innerHTML = `<input name="MD${i}" type="number" class="med" min="0" max="250" value="${d}" required>`;
|
td.innerHTML = `<input name="MD${i}" type="number" class="m" min="0" max="250" value="${d}" required>`;
|
||||||
}
|
}
|
||||||
function GetV()
|
function GetV()
|
||||||
{
|
{
|
||||||
@ -134,8 +134,8 @@
|
|||||||
</select><br>
|
</select><br>
|
||||||
UTC offset: <input name="UO" type="number" min="-65500" max="65500" required> seconds (max. 18 hours)<br>
|
UTC offset: <input name="UO" type="number" min="-65500" max="65500" required> seconds (max. 18 hours)<br>
|
||||||
Current local time is <span class="times">unknown</span>.<br>
|
Current local time is <span class="times">unknown</span>.<br>
|
||||||
Latitude (N): <input name="LT" type="number" class="big" min="-66.6" max="66.6" step="0.01">
|
Latitude (N): <input name="LT" type="number" class="xl" min="-66.6" max="66.6" step="0.01">
|
||||||
Longitude (E): <input name="LN" type="number" class="big" min="-180" max="180" step="0.01">
|
Longitude (E): <input name="LN" type="number" class="xl" min="-180" max="180" step="0.01">
|
||||||
<div id="sun" class="times"></div>
|
<div id="sun" class="times"></div>
|
||||||
<h3>Clock</h3>
|
<h3>Clock</h3>
|
||||||
Clock Overlay:
|
Clock Overlay:
|
||||||
|
@ -81,7 +81,7 @@
|
|||||||
case "number":
|
case "number":
|
||||||
c = `value="${o}"`;
|
c = `value="${o}"`;
|
||||||
if (f.substr(-3)==="pin") {
|
if (f.substr(-3)==="pin") {
|
||||||
c += ' max="39" min="-1" class="sml"';
|
c += ' max="39" min="-1" class="s"';
|
||||||
t = "int";
|
t = "int";
|
||||||
} else {
|
} else {
|
||||||
c += ' step="0.00001" class="xxl"';
|
c += ' step="0.00001" class="xxl"';
|
||||||
|
@ -32,20 +32,20 @@
|
|||||||
Network name (SSID, empty to not connect): <br><input name="CS" maxlength="32"><br>
|
Network name (SSID, empty to not connect): <br><input name="CS" maxlength="32"><br>
|
||||||
Network password: <br> <input type="password" name="CP" maxlength="63"><br>
|
Network password: <br> <input type="password" name="CP" maxlength="63"><br>
|
||||||
Static IP (leave at 0.0.0.0 for DHCP):<br>
|
Static IP (leave at 0.0.0.0 for DHCP):<br>
|
||||||
<input name="I0" type="number" min="0" max="255" required> .
|
<input name="I0" type="number" class="s" min="0" max="255" required> .
|
||||||
<input name="I1" type="number" min="0" max="255" required> .
|
<input name="I1" type="number" class="s" min="0" max="255" required> .
|
||||||
<input name="I2" type="number" min="0" max="255" required> .
|
<input name="I2" type="number" class="s" min="0" max="255" required> .
|
||||||
<input name="I3" type="number" min="0" max="255" required><br>
|
<input name="I3" type="number" class="s" min="0" max="255" required><br>
|
||||||
Static gateway:<br>
|
Static gateway:<br>
|
||||||
<input name="G0" type="number" min="0" max="255" required> .
|
<input name="G0" type="number" class="s" min="0" max="255" required> .
|
||||||
<input name="G1" type="number" min="0" max="255" required> .
|
<input name="G1" type="number" class="s" min="0" max="255" required> .
|
||||||
<input name="G2" type="number" min="0" max="255" required> .
|
<input name="G2" type="number" class="s" min="0" max="255" required> .
|
||||||
<input name="G3" type="number" min="0" max="255" required><br>
|
<input name="G3" type="number" class="s" min="0" max="255" required><br>
|
||||||
Static subnet mask:<br>
|
Static subnet mask:<br>
|
||||||
<input name="S0" type="number" min="0" max="255" required> .
|
<input name="S0" type="number" class="s" min="0" max="255" required> .
|
||||||
<input name="S1" type="number" min="0" max="255" required> .
|
<input name="S1" type="number" class="s" min="0" max="255" required> .
|
||||||
<input name="S2" type="number" min="0" max="255" required> .
|
<input name="S2" type="number" class="s" min="0" max="255" required> .
|
||||||
<input name="S3" type="number" min="0" max="255" required><br>
|
<input name="S3" type="number" class="s" min="0" max="255" required><br>
|
||||||
mDNS address (leave empty for no mDNS):<br/>
|
mDNS address (leave empty for no mDNS):<br/>
|
||||||
http:// <input name="CM" maxlength="32"> .local<br>
|
http:// <input name="CM" maxlength="32"> .local<br>
|
||||||
Client IP: <span class="sip"> Not connected </span> <br>
|
Client IP: <span class="sip"> Not connected </span> <br>
|
||||||
@ -53,7 +53,7 @@
|
|||||||
AP SSID (leave empty for no AP):<br> <input name="AS" maxlength="32"><br>
|
AP SSID (leave empty for no AP):<br> <input name="AS" maxlength="32"><br>
|
||||||
Hide AP name: <input type="checkbox" name="AH"><br>
|
Hide AP name: <input type="checkbox" name="AH"><br>
|
||||||
AP password (leave empty for open):<br> <input type="password" name="AP" maxlength="63" pattern="(.{8,63})|()" title="Empty or min. 8 characters"><br>
|
AP password (leave empty for open):<br> <input type="password" name="AP" maxlength="63" pattern="(.{8,63})|()" title="Empty or min. 8 characters"><br>
|
||||||
Access Point WiFi channel: <input name="AC" type="number" min="1" max="13" required><br>
|
Access Point WiFi channel: <input name="AC" type="number" class="xs" min="1" max="13" required><br>
|
||||||
AP opens:
|
AP opens:
|
||||||
<select name="AB">
|
<select name="AB">
|
||||||
<option value="0">No connection after boot</option>
|
<option value="0">No connection after boot</option>
|
||||||
|
@ -50,14 +50,20 @@ input[type="number"] {
|
|||||||
input[type="number"].xxl {
|
input[type="number"].xxl {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
input[type="number"].big {
|
input[type="number"].xl {
|
||||||
width: 85px;
|
width: 85px;
|
||||||
}
|
}
|
||||||
input[type="number"].med {
|
input[type="number"].l {
|
||||||
|
width: 60px;
|
||||||
|
}
|
||||||
|
input[type="number"].m {
|
||||||
width: 55px;
|
width: 55px;
|
||||||
}
|
}
|
||||||
input[type="number"].sml {
|
input[type="number"].s {
|
||||||
width: 40px;
|
width: 42px;
|
||||||
|
}
|
||||||
|
input[type="number"].xs {
|
||||||
|
width: 35px;
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
margin: 2px;
|
margin: 2px;
|
||||||
|
File diff suppressed because one or more lines are too long
3587
wled00/html_ui.h
3587
wled00/html_ui.h
File diff suppressed because it is too large
Load Diff
@ -167,22 +167,22 @@ void decodeIR(uint32_t code)
|
|||||||
// if (decodeIRCustom(code)) return;
|
// if (decodeIRCustom(code)) return;
|
||||||
if (code > 0xFFFFFF) return; //invalid code
|
if (code > 0xFFFFFF) return; //invalid code
|
||||||
switch (irEnabled) {
|
switch (irEnabled) {
|
||||||
case 1:
|
case 1:
|
||||||
if (code > 0xF80000) {
|
if (code > 0xF80000) {
|
||||||
decodeIR24OLD(code); // white 24-key remote (old) - it sends 0xFF0000 values
|
decodeIR24OLD(code); // white 24-key remote (old) - it sends 0xFF0000 values
|
||||||
} else {
|
} else {
|
||||||
decodeIR24(code); //is in 24-key remote range
|
decodeIR24(code); // 24-key remote - 0xF70000 to 0xF80000
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: decodeIR24CT(code); break; // white 24-key remote with CW, WW, CT+ and CT- keys
|
case 2: decodeIR24CT(code); break; // white 24-key remote with CW, WW, CT+ and CT- keys
|
||||||
case 3: decodeIR40(code); break; // blue 40-key remote with 25%, 50%, 75% and 100% keys
|
case 3: decodeIR40(code); break; // blue 40-key remote with 25%, 50%, 75% and 100% keys
|
||||||
case 4: decodeIR44(code); break; // white 44-key remote with color-up/down keys and DIY1 to 6 keys
|
case 4: decodeIR44(code); break; // white 44-key remote with color-up/down keys and DIY1 to 6 keys
|
||||||
case 5: decodeIR21(code); break; // white 21-key remote
|
case 5: decodeIR21(code); break; // white 21-key remote
|
||||||
case 6: decodeIR6(code); break; // black 6-key learning remote defaults: "CH" controls brightness,
|
case 6: decodeIR6(code); break; // black 6-key learning remote defaults: "CH" controls brightness,
|
||||||
// "VOL +" controls effect, "VOL -" controls colour/palette, "MUTE"
|
// "VOL +" controls effect, "VOL -" controls colour/palette, "MUTE"
|
||||||
// sets bright plain white
|
// sets bright plain white
|
||||||
case 7: decodeIR9(code); break;
|
case 7: decodeIR9(code); break;
|
||||||
case 8: decodeIRJson(code); break; // any remote configurable with ir.json file
|
case 8: decodeIRJson(code); break; // any remote configurable with ir.json file
|
||||||
default: return;
|
default: return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -537,8 +537,8 @@ void decodeIR9(uint32_t code)
|
|||||||
lastValidCode = code;
|
lastValidCode = code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Code by Scott R Bailey @ https://github.com/scottrbailey
|
|
||||||
This allows users to customize IR actions without the need to edit C code and compile.
|
This allows users to customize IR actions without the need to edit C code and compile.
|
||||||
From the https://github.com/Aircoookie/WLED/wiki/Infrared-Control page, download the starter
|
From the https://github.com/Aircoookie/WLED/wiki/Infrared-Control page, download the starter
|
||||||
ir.json file that corresponds to the number of buttons on your remote.
|
ir.json file that corresponds to the number of buttons on your remote.
|
||||||
|
@ -455,11 +455,8 @@ void WLED::beginStrip()
|
|||||||
colorUpdated(NOTIFIER_CALL_MODE_INIT);
|
colorUpdated(NOTIFIER_CALL_MODE_INIT);
|
||||||
|
|
||||||
// init relay pin
|
// init relay pin
|
||||||
if (rlyPin>=0) digitalWrite(rlyPin, (bri ? rlyMde : !rlyMde));
|
if (rlyPin>=0)
|
||||||
|
digitalWrite(rlyPin, (rlyMde ? bri : !bri));
|
||||||
// disable button if it is "pressed" unintentionally
|
|
||||||
//if (btnPin>=0 && buttonType == BTN_TYPE_PUSH && isButtonPressed())
|
|
||||||
// buttonType = BTN_TYPE_NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WLED::initAP(bool resetAP)
|
void WLED::initAP(bool resetAP)
|
||||||
|
@ -159,13 +159,24 @@ void sappends(char stype, const char* key, char* val)
|
|||||||
{
|
{
|
||||||
switch(stype)
|
switch(stype)
|
||||||
{
|
{
|
||||||
case 's': //string (we can interpret val as char*)
|
case 's': { //string (we can interpret val as char*)
|
||||||
oappend("d.Sf.");
|
oappend("d.Sf.");
|
||||||
oappend(key);
|
oappend(key);
|
||||||
oappend(".value=\"");
|
oappend(".value=\"");
|
||||||
oappend(val);
|
//convert "%" to "%%" to make EspAsyncWebServer happy
|
||||||
|
char buf[130];
|
||||||
|
uint8_t len = strlen(val) +1;
|
||||||
|
uint8_t s = 0;
|
||||||
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
|
buf[i+s] = val[i];
|
||||||
|
if (val[i] == '%') {
|
||||||
|
s++; buf[i+s] = '%';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
oappend(buf);
|
||||||
oappend("\";");
|
oappend("\";");
|
||||||
break;
|
break; }
|
||||||
case 'm': //message
|
case 'm': //message
|
||||||
oappend(SET_F("d.getElementsByClassName"));
|
oappend(SET_F("d.getElementsByClassName"));
|
||||||
oappend(key);
|
oappend(key);
|
||||||
|
Loading…
Reference in New Issue
Block a user