Merge pull request #1807 from Aircoookie/dev
Pull dev branch into master. 0.12 release soon!
This commit is contained in:
commit
30df67721d
1
.gitignore
vendored
1
.gitignore
vendored
@ -13,3 +13,4 @@
|
|||||||
.gitignore
|
.gitignore
|
||||||
.clang-format
|
.clang-format
|
||||||
node_modules
|
node_modules
|
||||||
|
.idea
|
||||||
|
46
CHANGELOG.md
46
CHANGELOG.md
@ -2,6 +2,52 @@
|
|||||||
|
|
||||||
### Development versions after 0.11.1 release
|
### Development versions after 0.11.1 release
|
||||||
|
|
||||||
|
#### Build 2103130
|
||||||
|
|
||||||
|
- Added options for Auto Node discovery
|
||||||
|
- Optimized strings (no string both F() and raw)
|
||||||
|
|
||||||
|
#### Build 2103090
|
||||||
|
|
||||||
|
- Added Auto Node discovery (PR #1683)
|
||||||
|
- Added tooltips to quick color selectors for accessibility
|
||||||
|
|
||||||
|
#### Build 2103060
|
||||||
|
|
||||||
|
- Auto start field population in bus config
|
||||||
|
|
||||||
|
#### Build 2103050
|
||||||
|
|
||||||
|
- Fixed incorrect over-memory indication in LED settings on ESP32
|
||||||
|
|
||||||
|
#### Build 2103041
|
||||||
|
|
||||||
|
- Added destructor for BusPwm (fixes #1789)
|
||||||
|
|
||||||
|
#### Build 2103040
|
||||||
|
|
||||||
|
- Fixed relay mode inverted when upgrading from 0.11.0
|
||||||
|
- Fixed no more than 2 pins per bus configurable in UI
|
||||||
|
- Changed to non-linear IR brightness steps (PR #1742)
|
||||||
|
- Fixed various warnings (PR #1744)
|
||||||
|
- Added UDP DNRGBW Mode (PR #1704)
|
||||||
|
- Added dynamic LED mapping with ledmap.json file (PR #1738)
|
||||||
|
- Added support for QuinLED-ESP32-Ethernet board
|
||||||
|
- Added support for WESP32 ethernet board (PR #1764)
|
||||||
|
- Added Caching for main UI (PR #1704)
|
||||||
|
- Added Tetrix mode (PR #1729)
|
||||||
|
- Added memory check on Bus creation
|
||||||
|
|
||||||
|
#### Build 2102050
|
||||||
|
|
||||||
|
- Version bump to 0.12.0-a0 "Hikari"
|
||||||
|
- Added FPS indication in info
|
||||||
|
- Bumped max outputs from 7 to 10 busses for ESP32
|
||||||
|
|
||||||
|
#### Build 2101310
|
||||||
|
|
||||||
|
- First alpha configurable multipin
|
||||||
|
|
||||||
#### Build 2101130
|
#### Build 2101130
|
||||||
|
|
||||||
- Added color transitions for all segments and slots and for segment brightness
|
- Added color transitions for all segments and slots and for segment brightness
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "wled",
|
"name": "wled",
|
||||||
"version": "0.11.1",
|
"version": "0.12.0-a0",
|
||||||
"description": "Tools for WLED project",
|
"description": "Tools for WLED project",
|
||||||
"main": "tools/cdata.js",
|
"main": "tools/cdata.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
default_envs = travis_esp8266, travis_esp32
|
default_envs = travis_esp8266, travis_esp32
|
||||||
|
|
||||||
# Release binaries
|
# Release binaries
|
||||||
; default_envs = nodemcuv2, esp01_1m_full, esp32dev, custom_WS2801, custom_APA102, custom_LEDPIN_16, custom_LEDPIN_4, custom_LEDPIN_3, custom32_LEDPIN_16, custom32_APA102
|
; default_envs = nodemcuv2, esp01_1m_full, esp32dev
|
||||||
|
|
||||||
# Single binaries (uncomment your board)
|
# Single binaries (uncomment your board)
|
||||||
; default_envs = nodemcuv2
|
; default_envs = nodemcuv2
|
||||||
@ -95,16 +95,6 @@ debug_flags = -D DEBUG=1 -D WLED_DEBUG -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_CLIENT
|
|||||||
# This reduces the OTA size with ~45KB, so it's especially useful on low memory boards (512k/1m).
|
# This reduces the OTA size with ~45KB, so it's especially useful on low memory boards (512k/1m).
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
build_flags =
|
build_flags =
|
||||||
-Wno-switch
|
|
||||||
-Wno-deprecated-declarations
|
|
||||||
-Wno-write-strings
|
|
||||||
-Wno-unused-variable
|
|
||||||
-Wno-unused-value
|
|
||||||
-Wno-sign-compare
|
|
||||||
-Wno-unused-but-set-variable
|
|
||||||
-Wno-return-type
|
|
||||||
-Wno-sequence-point
|
|
||||||
-Wno-narrowing
|
|
||||||
-DMQTT_MAX_PACKET_SIZE=1024
|
-DMQTT_MAX_PACKET_SIZE=1024
|
||||||
-DSECURE_CLIENT=SECURE_CLIENT_BEARSSL
|
-DSECURE_CLIENT=SECURE_CLIENT_BEARSSL
|
||||||
-DBEARSSL_SSL_BASIC
|
-DBEARSSL_SSL_BASIC
|
||||||
@ -121,9 +111,6 @@ build_flags =
|
|||||||
; -D USERMOD_SENSORSTOMQTT
|
; -D USERMOD_SENSORSTOMQTT
|
||||||
|
|
||||||
build_unflags =
|
build_unflags =
|
||||||
-Wall
|
|
||||||
-Wreorder
|
|
||||||
-Wdeprecated-declarations
|
|
||||||
|
|
||||||
# enables all features for travis CI
|
# enables all features for travis CI
|
||||||
build_flags_all_features =
|
build_flags_all_features =
|
||||||
@ -159,15 +146,15 @@ build_flags =
|
|||||||
-DMIMETYPE_MINIMAL
|
-DMIMETYPE_MINIMAL
|
||||||
|
|
||||||
[esp32]
|
[esp32]
|
||||||
build_flags = -w -g
|
build_flags = -g
|
||||||
-DARDUINO_ARCH_ESP32
|
-DARDUINO_ARCH_ESP32
|
||||||
-DCONFIG_LITTLEFS_FOR_IDF_3_2
|
-DCONFIG_LITTLEFS_FOR_IDF_3_2
|
||||||
|
|
||||||
[scripts_defaults]
|
[scripts_defaults]
|
||||||
extra_scripts = pio/name-firmware.py
|
extra_scripts = pio-scripts/name-firmware.py
|
||||||
pio/gzip-firmware.py
|
pio-scripts/gzip-firmware.py
|
||||||
pio/strip-floats.py
|
pio-scripts/strip-floats.py
|
||||||
pio/user_config_copy.py
|
pio-scripts/user_config_copy.py
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# COMMON SETTINGS:
|
# COMMON SETTINGS:
|
||||||
@ -197,7 +184,7 @@ lib_deps =
|
|||||||
AsyncTCP @ 1.0.3
|
AsyncTCP @ 1.0.3
|
||||||
IRremoteESP8266 @ 2.7.3
|
IRremoteESP8266 @ 2.7.3
|
||||||
https://github.com/lorol/LITTLEFS.git
|
https://github.com/lorol/LITTLEFS.git
|
||||||
https://github.com/Aircoookie/ESPAsyncWebServer.git @ ~2.0.0
|
https://github.com/Aircoookie/ESPAsyncWebServer.git @ ~2.0.2
|
||||||
#For use of the TTGO T-Display ESP32 Module with integrated TFT display uncomment the following line
|
#For use of the TTGO T-Display ESP32 Module with integrated TFT display uncomment the following line
|
||||||
#TFT_eSPI
|
#TFT_eSPI
|
||||||
#For use SSD1306 OLED display uncomment following
|
#For use SSD1306 OLED display uncomment following
|
||||||
|
@ -398,6 +398,14 @@ const char PAGE_dmxmap[] PROGMEM = R"=====()=====";
|
|||||||
method: "plaintext",
|
method: "plaintext",
|
||||||
filter: "html-minify",
|
filter: "html-minify",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
file: "liveviewws.htm",
|
||||||
|
name: "PAGE_liveviewws",
|
||||||
|
prepend: "=====(",
|
||||||
|
append: ")=====",
|
||||||
|
method: "plaintext",
|
||||||
|
filter: "html-minify",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
file: "404.htm",
|
file: "404.htm",
|
||||||
name: "PAGE_404",
|
name: "PAGE_404",
|
||||||
|
427
usermods/Animated_Staircase/Animated_Staircase.h
Normal file
427
usermods/Animated_Staircase/Animated_Staircase.h
Normal file
@ -0,0 +1,427 @@
|
|||||||
|
/*
|
||||||
|
* Usermod for detecting people entering/leaving a staircase and switching the
|
||||||
|
* staircase on/off.
|
||||||
|
*
|
||||||
|
* Edit the Animated_Staircase_config.h file to compile this usermod for your
|
||||||
|
* specific configuration.
|
||||||
|
*
|
||||||
|
* See the accompanying README.md file for more info.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include "wled.h"
|
||||||
|
#include "Animated_Staircase_config.h"
|
||||||
|
#define USERMOD_ID_ANIMATED_STAIRCASE 1011
|
||||||
|
|
||||||
|
/* Initial configuration (available in API and stored in flash) */
|
||||||
|
bool enabled = true; // Enable this usermod
|
||||||
|
unsigned long segment_delay_ms = 150; // Time between switching each segment
|
||||||
|
unsigned long on_time_ms = 5 * 1000; // The time for the light to stay on
|
||||||
|
#ifndef TOP_PIR_PIN
|
||||||
|
unsigned int topMaxTimeUs = 1749; // default echo timout, top
|
||||||
|
#endif
|
||||||
|
#ifndef BOTTOM_PIR_PIN
|
||||||
|
unsigned int bottomMaxTimeUs = 1749; // default echo timout, bottom
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Time between checking of the sensors
|
||||||
|
const int scanDelay = 50;
|
||||||
|
|
||||||
|
class Animated_Staircase : public Usermod {
|
||||||
|
private:
|
||||||
|
// Lights on or off.
|
||||||
|
// Flipping this will start a transition.
|
||||||
|
bool on = false;
|
||||||
|
|
||||||
|
// Swipe direction for current transition
|
||||||
|
#define SWIPE_UP true
|
||||||
|
#define SWIPE_DOWN false
|
||||||
|
bool swipe = SWIPE_UP;
|
||||||
|
|
||||||
|
// Indicates which Sensor was seen last (to determine
|
||||||
|
// the direction when swiping off)
|
||||||
|
#define LOWER false
|
||||||
|
#define UPPER true
|
||||||
|
bool lastSensor = LOWER;
|
||||||
|
|
||||||
|
// Time of the last transition action
|
||||||
|
unsigned long lastTime = 0;
|
||||||
|
|
||||||
|
// Time of the last sensor check
|
||||||
|
unsigned long lastScanTime = 0;
|
||||||
|
|
||||||
|
// Last time the lights were switched on or off
|
||||||
|
unsigned long lastSwitchTime = 0;
|
||||||
|
|
||||||
|
// segment id between onIndex and offIndex are on.
|
||||||
|
// controll the swipe by setting/moving these indices around.
|
||||||
|
// onIndex must be less than or equal to offIndex
|
||||||
|
byte onIndex = 0;
|
||||||
|
byte offIndex = 0;
|
||||||
|
|
||||||
|
// The maximum number of configured segments.
|
||||||
|
// Dynamically updated based on user configuration.
|
||||||
|
byte maxSegmentId = 1;
|
||||||
|
byte mainSegmentId = 0;
|
||||||
|
|
||||||
|
bool saveState = false;
|
||||||
|
|
||||||
|
// These values are used by the API to read the
|
||||||
|
// last sensor state, or trigger a sensor
|
||||||
|
// through the API
|
||||||
|
bool topSensorRead = false;
|
||||||
|
bool topSensorWrite = false;
|
||||||
|
bool bottomSensorRead = false;
|
||||||
|
bool bottomSensorWrite = false;
|
||||||
|
|
||||||
|
void updateSegments() {
|
||||||
|
mainSegmentId = strip.getMainSegmentId();
|
||||||
|
WS2812FX::Segment mainsegment = strip.getSegment(mainSegmentId);
|
||||||
|
WS2812FX::Segment* segments = strip.getSegments();
|
||||||
|
for (int i = 0; i < MAX_NUM_SEGMENTS; i++, segments++) {
|
||||||
|
if (!segments->isActive()) {
|
||||||
|
maxSegmentId = i - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i >= onIndex && i < offIndex) {
|
||||||
|
segments->setOption(SEG_OPTION_ON, 1, 1);
|
||||||
|
|
||||||
|
// We may need to copy mode and colors from segment 0 to make sure
|
||||||
|
// changes are propagated even when the config is changed during a wipe
|
||||||
|
// segments->mode = mainsegment.mode;
|
||||||
|
// segments->colors[0] = mainsegment.colors[0];
|
||||||
|
} else {
|
||||||
|
segments->setOption(SEG_OPTION_ON, 0, 1);
|
||||||
|
}
|
||||||
|
// Always mark segments as "transitional", we are animating the staircase
|
||||||
|
segments->setOption(SEG_OPTION_TRANSITIONAL, 1, 1);
|
||||||
|
}
|
||||||
|
colorUpdated(NOTIFIER_CALL_MODE_DIRECT_CHANGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Detects if an object is within ultrasound range.
|
||||||
|
* signalPin: The pin where the pulse is sent
|
||||||
|
* echoPin: The pin where the echo is received
|
||||||
|
* maxTimeUs: Detection timeout in microseconds. If an echo is
|
||||||
|
* received within this time, an object is detected
|
||||||
|
* and the function will return true.
|
||||||
|
*
|
||||||
|
* The speed of sound is 343 meters per second at 20 degress Celcius.
|
||||||
|
* Since the sound has to travel back and forth, the detection
|
||||||
|
* distance for the sensor in cm is (0.0343 * maxTimeUs) / 2.
|
||||||
|
*
|
||||||
|
* For practical reasons, here are some useful distances:
|
||||||
|
*
|
||||||
|
* Distance = maxtime
|
||||||
|
* 5 cm = 292 uS
|
||||||
|
* 10 cm = 583 uS
|
||||||
|
* 20 cm = 1166 uS
|
||||||
|
* 30 cm = 1749 uS
|
||||||
|
* 50 cm = 2915 uS
|
||||||
|
* 100 cm = 5831 uS
|
||||||
|
*/
|
||||||
|
bool ultrasoundRead(uint8_t signalPin,
|
||||||
|
uint8_t echoPin,
|
||||||
|
unsigned int maxTimeUs) {
|
||||||
|
digitalWrite(signalPin, HIGH);
|
||||||
|
delayMicroseconds(10);
|
||||||
|
digitalWrite(signalPin, LOW);
|
||||||
|
return pulseIn(echoPin, HIGH, maxTimeUs) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkSensors() {
|
||||||
|
if ((millis() - lastScanTime) > scanDelay) {
|
||||||
|
lastScanTime = millis();
|
||||||
|
|
||||||
|
#ifdef BOTTOM_PIR_PIN
|
||||||
|
bottomSensorRead = bottomSensorWrite || (digitalRead(BOTTOM_PIR_PIN) == HIGH);
|
||||||
|
#else
|
||||||
|
bottomSensorRead = bottomSensorWrite || ultrasoundRead(BOTTOM_TRIGGER_PIN, BOTTOM_ECHO_PIN, bottomMaxTimeUs);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TOP_PIR_PIN
|
||||||
|
topSensorRead = topSensorWrite || (digitalRead(TOP_PIR_PIN) == HIGH);
|
||||||
|
#else
|
||||||
|
topSensorRead = topSensorWrite || ultrasoundRead(TOP_TRIGGER_PIN, TOP_ECHO_PIN, topMaxTimeUs);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Values read, reset the flags for next API call
|
||||||
|
topSensorWrite = false;
|
||||||
|
bottomSensorWrite = false;
|
||||||
|
|
||||||
|
if (topSensorRead != bottomSensorRead) {
|
||||||
|
lastSwitchTime = millis();
|
||||||
|
|
||||||
|
if (on) {
|
||||||
|
lastSensor = topSensorRead;
|
||||||
|
} else {
|
||||||
|
// If the bottom sensor triggered, we need to swipe up, ON
|
||||||
|
swipe = bottomSensorRead;
|
||||||
|
|
||||||
|
if (swipe) {
|
||||||
|
Serial.println("ON -> Swipe up.");
|
||||||
|
} else {
|
||||||
|
Serial.println("ON -> Swipe down.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onIndex == offIndex) {
|
||||||
|
// Position the indices for a correct on-swipe
|
||||||
|
if (swipe == SWIPE_UP) {
|
||||||
|
onIndex = mainSegmentId;
|
||||||
|
} else {
|
||||||
|
onIndex = maxSegmentId+1;
|
||||||
|
}
|
||||||
|
offIndex = onIndex;
|
||||||
|
}
|
||||||
|
on = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void autoPowerOff() {
|
||||||
|
if (on && ((millis() - lastSwitchTime) > on_time_ms)) {
|
||||||
|
// Swipe OFF in the direction of the last sensor detection
|
||||||
|
swipe = lastSensor;
|
||||||
|
on = false;
|
||||||
|
|
||||||
|
if (swipe) {
|
||||||
|
Serial.println("OFF -> Swipe up.");
|
||||||
|
} else {
|
||||||
|
Serial.println("OFF -> Swipe down.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateSwipe() {
|
||||||
|
if ((millis() - lastTime) > segment_delay_ms) {
|
||||||
|
lastTime = millis();
|
||||||
|
|
||||||
|
byte oldOnIndex = onIndex;
|
||||||
|
byte oldOffIndex = offIndex;
|
||||||
|
|
||||||
|
if (on) {
|
||||||
|
// Turn on all segments
|
||||||
|
onIndex = MAX(mainSegmentId, onIndex - 1);
|
||||||
|
offIndex = MIN(maxSegmentId + 1, offIndex + 1);
|
||||||
|
} else {
|
||||||
|
if (swipe == SWIPE_UP) {
|
||||||
|
onIndex = MIN(offIndex, onIndex + 1);
|
||||||
|
} else {
|
||||||
|
offIndex = MAX(onIndex, offIndex - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSegments();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeSettingsToJson(JsonObject& root) {
|
||||||
|
JsonObject staircase = root["staircase"];
|
||||||
|
if (staircase.isNull()) {
|
||||||
|
staircase = root.createNestedObject("staircase");
|
||||||
|
}
|
||||||
|
staircase["enabled"] = enabled;
|
||||||
|
staircase["segment-delay-ms"] = segment_delay_ms;
|
||||||
|
staircase["on-time-s"] = on_time_ms / 1000;
|
||||||
|
|
||||||
|
#ifdef TOP_TRIGGER_PIN
|
||||||
|
staircase["top-echo-us"] = topMaxTimeUs;
|
||||||
|
#endif
|
||||||
|
#ifdef BOTTOM_TRIGGER_PIN
|
||||||
|
staircase["bottom-echo-us"] = bottomMaxTimeUs;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeSensorsToJson(JsonObject& root) {
|
||||||
|
JsonObject staircase = root["staircase"];
|
||||||
|
if (staircase.isNull()) {
|
||||||
|
staircase = root.createNestedObject("staircase");
|
||||||
|
}
|
||||||
|
staircase["top-sensor"] = topSensorRead;
|
||||||
|
staircase["bottom-sensor"] = bottomSensorRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool readSettingsFromJson(JsonObject& root) {
|
||||||
|
JsonObject staircase = root["staircase"];
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
bool shouldEnable = staircase["enabled"] | enabled;
|
||||||
|
if (shouldEnable != enabled) {
|
||||||
|
enable(shouldEnable);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long c_segment_delay_ms = staircase["segment-delay-ms"] | segment_delay_ms;
|
||||||
|
if (c_segment_delay_ms != segment_delay_ms) {
|
||||||
|
segment_delay_ms = c_segment_delay_ms;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long c_on_time_ms = (staircase["on-time-s"] | (on_time_ms / 1000)) * 1000;
|
||||||
|
if (c_on_time_ms != on_time_ms) {
|
||||||
|
on_time_ms = c_on_time_ms;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TOP_TRIGGER_PIN
|
||||||
|
unsigned int c_topMaxTimeUs = staircase["top-echo-us"] | topMaxTimeUs;
|
||||||
|
if (c_topMaxTimeUs != topMaxTimeUs) {
|
||||||
|
topMaxTimeUs = c_topMaxTimeUs;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef BOTTOM_TRIGGER_PIN
|
||||||
|
unsigned int c_bottomMaxTimeUs = staircase["bottom-echo-us"] | bottomMaxTimeUs;
|
||||||
|
if (c_bottomMaxTimeUs != bottomMaxTimeUs) {
|
||||||
|
bottomMaxTimeUs = c_bottomMaxTimeUs;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void readSensorsFromJson(JsonObject& root) {
|
||||||
|
JsonObject staircase = root["staircase"];
|
||||||
|
bottomSensorWrite = bottomSensorRead || (staircase["bottom-sensor"].as<bool>());
|
||||||
|
topSensorWrite = topSensorRead || (staircase["top-sensor"].as<bool>());
|
||||||
|
}
|
||||||
|
|
||||||
|
void enable(bool enable) {
|
||||||
|
if (enable) {
|
||||||
|
Serial.println("Animated Staircase enabled.");
|
||||||
|
Serial.print("Delay between steps: ");
|
||||||
|
Serial.print(segment_delay_ms, DEC);
|
||||||
|
Serial.print(" milliseconds.\nStairs switch off after: ");
|
||||||
|
Serial.print(on_time_ms / 1000, DEC);
|
||||||
|
Serial.println(" seconds.");
|
||||||
|
|
||||||
|
#ifdef BOTTOM_PIR_PIN
|
||||||
|
pinMode(BOTTOM_PIR_PIN, INPUT);
|
||||||
|
#else
|
||||||
|
pinMode(BOTTOM_TRIGGER_PIN, OUTPUT);
|
||||||
|
pinMode(BOTTOM_ECHO_PIN, INPUT);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TOP_PIR_PIN
|
||||||
|
pinMode(TOP_PIR_PIN, INPUT);
|
||||||
|
#else
|
||||||
|
pinMode(TOP_TRIGGER_PIN, OUTPUT);
|
||||||
|
pinMode(TOP_ECHO_PIN, INPUT);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
// Restore segment options
|
||||||
|
WS2812FX::Segment mainsegment = strip.getSegment(mainSegmentId);
|
||||||
|
WS2812FX::Segment* segments = strip.getSegments();
|
||||||
|
for (int i = 0; i < MAX_NUM_SEGMENTS; i++, segments++) {
|
||||||
|
if (!segments->isActive()) {
|
||||||
|
maxSegmentId = i - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
segments->setOption(SEG_OPTION_ON, 1, 1);
|
||||||
|
}
|
||||||
|
colorUpdated(NOTIFIER_CALL_MODE_DIRECT_CHANGE);
|
||||||
|
Serial.println("Animated Staircase disabled.");
|
||||||
|
}
|
||||||
|
enabled = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
void setup() { enable(enabled); }
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// Write changed settings from to flash (see readFromJsonState())
|
||||||
|
if (saveState) {
|
||||||
|
serializeConfig();
|
||||||
|
saveState = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkSensors();
|
||||||
|
autoPowerOff();
|
||||||
|
updateSwipe();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t getId() { return USERMOD_ID_ANIMATED_STAIRCASE; }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shows configuration settings to the json API. This object looks like:
|
||||||
|
*
|
||||||
|
* "staircase" : {
|
||||||
|
* "enabled" : true
|
||||||
|
* "segment-delay-ms" : 150,
|
||||||
|
* "on-time-s" : 5
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void addToJsonState(JsonObject& root) {
|
||||||
|
writeSettingsToJson(root);
|
||||||
|
writeSensorsToJson(root);
|
||||||
|
Serial.println("Staircase config exposed in API.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reads configuration settings from the json API.
|
||||||
|
* See void addToJsonState(JsonObject& root)
|
||||||
|
*/
|
||||||
|
void readFromJsonState(JsonObject& root) {
|
||||||
|
// The call to serializeConfig() must be done in the main loop,
|
||||||
|
// so we set a flag to signal the main loop to save state.
|
||||||
|
saveState = readSettingsFromJson(root);
|
||||||
|
readSensorsFromJson(root);
|
||||||
|
Serial.println("Staircase config read from API.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Writes the configuration to internal flash memory.
|
||||||
|
*/
|
||||||
|
void addToConfig(JsonObject& root) {
|
||||||
|
writeSettingsToJson(root);
|
||||||
|
Serial.println("Staircase config saved.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reads the configuration to internal flash memory before setup() is called.
|
||||||
|
*/
|
||||||
|
void readFromConfig(JsonObject& root) {
|
||||||
|
readSettingsFromJson(root);
|
||||||
|
Serial.println("Staircase config loaded.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shows the delay between steps and power-off time in the "info"
|
||||||
|
* tab of the web-UI.
|
||||||
|
*/
|
||||||
|
void addToJsonInfo(JsonObject& root) {
|
||||||
|
JsonObject staircase = root["u"];
|
||||||
|
if (staircase.isNull()) {
|
||||||
|
staircase = root.createNestedObject("u");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enabled) {
|
||||||
|
JsonArray usermodEnabled =
|
||||||
|
staircase.createNestedArray("Staircase enabled"); // name
|
||||||
|
usermodEnabled.add("yes"); // value
|
||||||
|
|
||||||
|
JsonArray segmentDelay =
|
||||||
|
staircase.createNestedArray("Delay between stairs"); // name
|
||||||
|
segmentDelay.add(segment_delay_ms); // value
|
||||||
|
segmentDelay.add(" milliseconds"); // unit
|
||||||
|
|
||||||
|
JsonArray onTime =
|
||||||
|
staircase.createNestedArray("Power-off stairs after"); // name
|
||||||
|
onTime.add(on_time_ms / 1000); // value
|
||||||
|
onTime.add(" seconds"); // unit
|
||||||
|
} else {
|
||||||
|
JsonArray usermodEnabled =
|
||||||
|
staircase.createNestedArray("Staircase enabled"); // name
|
||||||
|
usermodEnabled.add("no"); // value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
21
usermods/Animated_Staircase/Animated_Staircase_config.h
Normal file
21
usermods/Animated_Staircase/Animated_Staircase_config.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Animated_Staircase compiletime confguration.
|
||||||
|
*
|
||||||
|
* Please see README.md on how to change this file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Please change the pin numbering below to match your board.
|
||||||
|
#define TOP_PIR_PIN D5
|
||||||
|
#define BOTTOM_PIR_PIN D6
|
||||||
|
|
||||||
|
// Or uncumment and a pir and use an ultrasound HC-SR04 sensor,
|
||||||
|
// see README.md for details
|
||||||
|
#ifndef TOP_PIR_PIN
|
||||||
|
#define TOP_TRIGGER_PIN D2
|
||||||
|
#define TOP_ECHO_PIN D3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BOTTOM_PIR_PIN
|
||||||
|
#define BOTTOM_TRIGGER_PIN D4
|
||||||
|
#define BOTTOM_ECHO_PIN D5
|
||||||
|
#endif
|
203
usermods/Animated_Staircase/README.md
Normal file
203
usermods/Animated_Staircase/README.md
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
# Usermod Animated Staircase
|
||||||
|
This usermod makes your staircase look cool by switching it on with an animation. It uses
|
||||||
|
PIR or ultrasonic sensors at the top and bottom of your stairs to:
|
||||||
|
|
||||||
|
- Light up the steps in your walking direction, leading the way.
|
||||||
|
- Switch off the steps after you, in the direction of the last detected movement.
|
||||||
|
- Always switch on when one of the sensors detects movement, even if an effect
|
||||||
|
is still running. It can therewith handle multiple people on the stairs gracefully.
|
||||||
|
|
||||||
|
The Animated Staircase can be controlled by the WLED API. Change settings such as
|
||||||
|
speed, on/off time and distance settings by sending an HTTP request, see below.
|
||||||
|
|
||||||
|
## WLED integration
|
||||||
|
To include this usermod in your WLED setup, you have to be able to [compile WLED from source](https://github.com/Aircoookie/WLED/wiki/Compiling-WLED).
|
||||||
|
|
||||||
|
Before compiling, you have to make the following modifications:
|
||||||
|
|
||||||
|
Edit `usermods_list.cpp`:
|
||||||
|
1. Open `wled00/usermods_list.cpp`
|
||||||
|
2. add `#include "../usermods/Animated_Staircase/Animated_Staircase.h"` to the top of the file
|
||||||
|
3. add `usermods.add(new Animated_Staircase());` to the end of the `void registerUsermods()` function.
|
||||||
|
|
||||||
|
Edit `Animated_Staircase_config.h`:
|
||||||
|
1. Open `usermods/Animated_Staircase/Animated_Staircase_config.h`
|
||||||
|
2. To use PIR sensors, change these lines to match your setup:
|
||||||
|
Using D7 and D6 pin notation as used on several boards:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#define TOP_PIR_PIN D7
|
||||||
|
#define BOTTOM_PIR_PIN D6
|
||||||
|
```
|
||||||
|
|
||||||
|
Or using GPIO numbering for pins 25 and 26:
|
||||||
|
```cpp
|
||||||
|
#define TOP_PIR_PIN 26
|
||||||
|
#define BOTTOM_PIR_PIN 25
|
||||||
|
```
|
||||||
|
|
||||||
|
To use Ultrasonic HC-SR04 sensors instead of (one of the) PIR sensors,
|
||||||
|
uncomment one of the PIR sensor lines and adjust the pin numbers for the
|
||||||
|
connected Ultrasonic sensor. In the example below we use an Ultrasonic
|
||||||
|
sensor at the bottom of the stairs:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#define TOP_PIR_PIN 32
|
||||||
|
//#define BOTTOM_PIR_PIN D6 /* This PIR sensor is disabled */
|
||||||
|
|
||||||
|
#ifndef TOP_PIR_PIN
|
||||||
|
#define TOP_SIGNAL_PIN D2
|
||||||
|
#define TOP_ECHO_PIN D3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BOTTOM_PIR_PIN /* If the bottom PIR is disabled, */
|
||||||
|
#define BOTTOM_SIGNAL_PIN 25 /* This Ultrasonic sensor is used */
|
||||||
|
#define BOTTOM_ECHO_PIN 26
|
||||||
|
#endif
|
||||||
|
```
|
||||||
|
|
||||||
|
After these modifications, compile and upload your WLED binary to your board
|
||||||
|
and check the WLED info page to see if this usermod is enabled.
|
||||||
|
|
||||||
|
## Hardware installation
|
||||||
|
1. Stick the LED strip under each step of the stairs.
|
||||||
|
2. Connect the ESP8266 pin D4 or ESP32 pin D2 to the first LED data pin at the bottom step
|
||||||
|
of your stairs.
|
||||||
|
3. Connect the data-out pin at the end of each strip per step to the data-in pin on the
|
||||||
|
other end of the next step, creating one large virtual LED strip.
|
||||||
|
4. Mount sensors of choice at the bottom and top of the stairs and connect them to the ESP.
|
||||||
|
5. To make sure all LEDs get enough power and have your staircase lighted evenly, power each
|
||||||
|
step from one side, using at least AWG14 or 2.5mm^2 cable. Don't connect them serial as you
|
||||||
|
do for the datacable!
|
||||||
|
|
||||||
|
You _may_ need to use 10k pull-down resistors on the selected PIR pins, depending on the sensor.
|
||||||
|
|
||||||
|
## WLED configuration
|
||||||
|
1. In the WLED UI, confgure a segment for each step. The lowest step of the stairs is the
|
||||||
|
lowest segment id.
|
||||||
|
2. Save your segments into a preset.
|
||||||
|
3. Ideally, add the preset in the config > LED setup menu to the "apply
|
||||||
|
preset **n** at boot" setting.
|
||||||
|
|
||||||
|
## Changing behavior through API
|
||||||
|
The Staircase settings can be changed through the WLED JSON api.
|
||||||
|
|
||||||
|
**NOTE:** We are using [curl](https://curl.se/) to send HTTP POSTs to the WLED API.
|
||||||
|
If you're using Windows and want to use the curl commands, replace the `\` with a `^`
|
||||||
|
or remove them and put everything on one line.
|
||||||
|
|
||||||
|
|
||||||
|
| Setting | Description | Default |
|
||||||
|
|------------------|---------------------------------------------------------------|---------|
|
||||||
|
| enabled | Enable or disable the usermod | true |
|
||||||
|
| segment-delay-ms | Delay (milliseconds) between switching on/off each step | 150 |
|
||||||
|
| on-time-s | Time (seconds) the stairs stay lit after last detection | 5 |
|
||||||
|
| bottom-echo-us | Detection range of ultrasonic sensor | 1749 |
|
||||||
|
| bottomsensor | Manually trigger a down to up animation via API | false |
|
||||||
|
| topsensor | Manually trigger an up to down animation via API | false |
|
||||||
|
|
||||||
|
|
||||||
|
To read the current settings, open a browser to `http://xxx.xxx.xxx.xxx/json/state` (use your WLED
|
||||||
|
device IP address). The device will respond with a json object containing all WLED settings.
|
||||||
|
The staircase settings and sensor states are inside the WLED status element:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"state": {
|
||||||
|
"staircase": {
|
||||||
|
"enabled": true,
|
||||||
|
"segment-delay-ms": 150,
|
||||||
|
"on-time-s": 5,
|
||||||
|
"bottomsensor": false,
|
||||||
|
"topsensor": false
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Enable/disable the usermod
|
||||||
|
By disabling the usermod you will be able to keep the LED's on, independent from the sensor
|
||||||
|
activity. This enables to play with the lights without the usermod switching them on or off.
|
||||||
|
|
||||||
|
To disable the usermod:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST -H "Content-Type: application/json" \
|
||||||
|
-d {"staircase":{"enabled":false}} \
|
||||||
|
xxx.xxx.xxx.xxx/json/state
|
||||||
|
```
|
||||||
|
|
||||||
|
To enable the usermod again, use `"enabled":true`.
|
||||||
|
|
||||||
|
### Changing animation parameters
|
||||||
|
To change the delay between the steps to (for example) 100 milliseconds and the on-time to
|
||||||
|
10 seconds:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST -H "Content-Type: application/json" \
|
||||||
|
-d '{"staircase":{"segment-delay-ms":100,"on-time-s":10}}' \
|
||||||
|
xxx.xxx.xxx.xxx/json/state
|
||||||
|
```
|
||||||
|
|
||||||
|
### Changing detection range of the ultrasonic HC-SR04 sensor
|
||||||
|
When an ultrasonic sensor is enabled in `Animated_Staircase_config.h`, you'll see a
|
||||||
|
`bottom-echo-us` setting appear in the json api:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"state": {
|
||||||
|
"staircase": {
|
||||||
|
"enabled": true,
|
||||||
|
"segment-delay-ms": 150,
|
||||||
|
"on-time-s": 5,
|
||||||
|
"bottom-echo-us": 1749
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If the HC-SR04 sensor detects an echo within 1749 microseconds (corresponding to ~30 cm
|
||||||
|
detection range from the sensor), it will trigger switching on the staircase. This setting
|
||||||
|
can be changed through the API with an HTTP POST:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST -H "Content-Type: application/json" \
|
||||||
|
-d '{"staircase":{"bottom-echo-us":1166}}' \
|
||||||
|
xxx.xxx.xxx.xxx/json/state
|
||||||
|
```
|
||||||
|
|
||||||
|
Calculating the detection range can be performed as follows: The speed of sound is 343m/s at 20
|
||||||
|
degrees Centigrade. Since the sound has to travel back and forth, the detection range for the
|
||||||
|
sensor in cm is (0.0343 * maxTimeUs) / 2. To get you started, please find delays and distances below:
|
||||||
|
|
||||||
|
| Distance | Detection time |
|
||||||
|
|---------:|----------------:|
|
||||||
|
| 5 cm | 292 uS |
|
||||||
|
| 10 cm | 583 uS |
|
||||||
|
| 20 cm | 1166 uS |
|
||||||
|
| 30 cm | 1749 uS |
|
||||||
|
| 50 cm | 2915 uS |
|
||||||
|
| 100 cm | 5831 uS |
|
||||||
|
|
||||||
|
**Please note:** that using an HC-SR04 sensor, particularly when detecting echos at longer
|
||||||
|
distances creates delays in the WLED software, and _might_ introduce timing hickups in your animations or
|
||||||
|
a less responsive web interface. It is therefore advised to keep the detection time as short as possible.
|
||||||
|
|
||||||
|
### Animation triggering through the API
|
||||||
|
Instead of stairs activation by one of the sensors, you can also trigger the animation through
|
||||||
|
the API. To simulate triggering the bottom sensor, use:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST -H "Content-Type: application/json" \
|
||||||
|
-d '{"staircase":{"bottomsensor":true}}' \
|
||||||
|
xxx.xxx.xxx.xxx/json/state
|
||||||
|
```
|
||||||
|
|
||||||
|
Likewise, to trigger the top sensor, use:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST -H "Content-Type: application/json" \
|
||||||
|
-d '{"staircase":{"topsensor":true}}' \
|
||||||
|
xxx.xxx.xxx.xxx/json/state
|
||||||
|
```
|
||||||
|
|
||||||
|
Have fun with this usermod.<br/>
|
||||||
|
www.rolfje.com
|
40
usermods/BME280_v2/README.md
Normal file
40
usermods/BME280_v2/README.md
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
Hello! I have written a v2 usermod for the BME280/BMP280 sensor based on the [existing v1 usermod](https://github.com/Aircoookie/WLED/blob/master/usermods/Wemos_D1_mini%2BWemos32_mini_shield/usermod_bme280.cpp). It is not just a refactor, there are many changes which I made to fit my use case, and I hope they will fit the use cases of others as well! Most notably, this usermod is *just* for the BME280 and does not control a display like in the v1 usermod designed for the WeMos shield.
|
||||||
|
|
||||||
|
- Requires libraries `BME280@~3.0.0` (by [finitespace](https://github.com/finitespace/BME280)) and `Wire`. Please add these under `lib_deps` in your `platform.ini` (or `platform_override.ini`).
|
||||||
|
- Data is published over MQTT so make sure you've enabled the MQTT sync interface.
|
||||||
|
- This usermod also writes to serial (GPIO1 on ESP8266). Please make sure nothing else listening on the serial TX pin of your board will get confused by log messages!
|
||||||
|
|
||||||
|
To enable, compile with `USERMOD_BME280` defined (i.e. `platformio_override.ini`)
|
||||||
|
```ini
|
||||||
|
build_flags =
|
||||||
|
${common.build_flags_esp8266}
|
||||||
|
-D USERMOD_BME280
|
||||||
|
```
|
||||||
|
or define `USERMOD_BME280` in `my_config.h`
|
||||||
|
```c++
|
||||||
|
#define USERMOD_BME280
|
||||||
|
```
|
||||||
|
|
||||||
|
Changes include:
|
||||||
|
- Adjustable measure intervals
|
||||||
|
- Temperature and pressure have separate intervals due to pressure not frequently changing at any constant altitude
|
||||||
|
- Adjustment of number of decimal places in published sensor values
|
||||||
|
- Separate adjustment for temperature, humidity and pressure values
|
||||||
|
- Values are rounded to the specified number of decimal places
|
||||||
|
- Pressure measured in units of hPa instead of Pa
|
||||||
|
- Calculation of heat index (apparent temperature) and dew point
|
||||||
|
- These, along with humidity measurements, are disabled if the sensor is a BMP280
|
||||||
|
- 16x oversampling of sensor during measurement
|
||||||
|
- Values are only published if they are different from the previous value
|
||||||
|
- Values are published on startup (continually until the MQTT broker acknowledges a successful publication)
|
||||||
|
|
||||||
|
Adjustments are made through preprocessor definitions at the start of the class definition.
|
||||||
|
|
||||||
|
MQTT topics are as follows:
|
||||||
|
Measurement type | MQTT topic
|
||||||
|
--- | ---
|
||||||
|
Temperature | `<deviceTopic>/temperature`
|
||||||
|
Humidity | `<deviceTopic>/humidity`
|
||||||
|
Pressure | `<deviceTopic>/pressure`
|
||||||
|
Heat index | `<deviceTopic>/heat_index`
|
||||||
|
Dew point | `<deviceTopic>/dew_point`
|
212
usermods/BME280_v2/usermod_bme280.h
Normal file
212
usermods/BME280_v2/usermod_bme280.h
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "wled.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <Wire.h>
|
||||||
|
#include <BME280I2C.h> // BME280 sensor
|
||||||
|
#include <EnvironmentCalculations.h> // BME280 extended measurements
|
||||||
|
|
||||||
|
class UsermodBME280 : public Usermod
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// User-defined configuration
|
||||||
|
#define Celsius // Show temperature mesaurement in Celcius. Comment out for Fahrenheit
|
||||||
|
#define TemperatureDecimals 1 // Number of decimal places in published temperaure values
|
||||||
|
#define HumidityDecimals 0 // Number of decimal places in published humidity values
|
||||||
|
#define PressureDecimals 2 // Number of decimal places in published pressure values
|
||||||
|
#define TemperatureInterval 5 // Interval to measure temperature (and humidity, dew point if available) in seconds
|
||||||
|
#define PressureInterval 300 // Interval to measure pressure in seconds
|
||||||
|
|
||||||
|
// Sanity checks
|
||||||
|
#if !defined(TemperatureDecimals) || TemperatureDecimals < 0
|
||||||
|
#define TemperatureDecimals 0
|
||||||
|
#endif
|
||||||
|
#if !defined(HumidityDecimals) || HumidityDecimals < 0
|
||||||
|
#define HumidityDecimals 0
|
||||||
|
#endif
|
||||||
|
#if !defined(PressureDecimals) || PressureDecimals < 0
|
||||||
|
#define PressureDecimals 0
|
||||||
|
#endif
|
||||||
|
#if !defined(TemperatureInterval) || TemperatureInterval < 0
|
||||||
|
#define TemperatureInterval 1
|
||||||
|
#endif
|
||||||
|
#if !defined(PressureInterval) || PressureInterval < 0
|
||||||
|
#define PressureInterval TemperatureInterval
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32 // ESP32 boards
|
||||||
|
uint8_t SCL_PIN = 22;
|
||||||
|
uint8_t SDA_PIN = 21;
|
||||||
|
#else // ESP8266 boards
|
||||||
|
uint8_t SCL_PIN = 5;
|
||||||
|
uint8_t SDA_PIN = 4;
|
||||||
|
//uint8_t RST_PIN = 16; // Uncoment for Heltec WiFi-Kit-8
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// BME280 sensor settings
|
||||||
|
BME280I2C::Settings settings{
|
||||||
|
BME280::OSR_X16, // Temperature oversampling x16
|
||||||
|
BME280::OSR_X16, // Humidity oversampling x16
|
||||||
|
BME280::OSR_X16, // Pressure oversampling x16
|
||||||
|
// Defaults
|
||||||
|
BME280::Mode_Forced,
|
||||||
|
BME280::StandbyTime_1000ms,
|
||||||
|
BME280::Filter_Off,
|
||||||
|
BME280::SpiEnable_False,
|
||||||
|
BME280I2C::I2CAddr_0x76 // I2C address. I2C specific. Default 0x76
|
||||||
|
};
|
||||||
|
|
||||||
|
BME280I2C bme{settings};
|
||||||
|
|
||||||
|
uint8_t SensorType;
|
||||||
|
|
||||||
|
// Measurement timers
|
||||||
|
long timer;
|
||||||
|
long lastTemperatureMeasure = 0;
|
||||||
|
long lastPressureMeasure = 0;
|
||||||
|
|
||||||
|
// Current sensor values
|
||||||
|
float SensorTemperature;
|
||||||
|
float SensorHumidity;
|
||||||
|
float SensorHeatIndex;
|
||||||
|
float SensorDewPoint;
|
||||||
|
float SensorPressure;
|
||||||
|
// Track previous sensor values
|
||||||
|
float lastTemperature;
|
||||||
|
float lastHumidity;
|
||||||
|
float lastHeatIndex;
|
||||||
|
float lastDewPoint;
|
||||||
|
float lastPressure;
|
||||||
|
|
||||||
|
// Store packet IDs of MQTT publications
|
||||||
|
uint16_t mqttTemperaturePub = 0;
|
||||||
|
uint16_t mqttPressurePub = 0;
|
||||||
|
|
||||||
|
void UpdateBME280Data(int SensorType)
|
||||||
|
{
|
||||||
|
float _temperature, _humidity, _pressure;
|
||||||
|
#ifdef Celsius
|
||||||
|
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
|
||||||
|
EnvironmentCalculations::TempUnit envTempUnit(EnvironmentCalculations::TempUnit_Celsius);
|
||||||
|
#else
|
||||||
|
BME280::TempUnit tempUnit(BME280::TempUnit_Fahrenheit);
|
||||||
|
EnvironmentCalculations::TempUnit envTempUnit(EnvironmentCalculations::TempUnit_Fahrenheit);
|
||||||
|
#endif
|
||||||
|
BME280::PresUnit presUnit(BME280::PresUnit_hPa);
|
||||||
|
|
||||||
|
bme.read(_pressure, _temperature, _humidity, tempUnit, presUnit);
|
||||||
|
|
||||||
|
SensorTemperature = _temperature;
|
||||||
|
SensorHumidity = _humidity;
|
||||||
|
SensorPressure = _pressure;
|
||||||
|
if (SensorType == 1)
|
||||||
|
{
|
||||||
|
SensorHeatIndex = EnvironmentCalculations::HeatIndex(_temperature, _humidity, envTempUnit);
|
||||||
|
SensorDewPoint = EnvironmentCalculations::DewPoint(_temperature, _humidity, envTempUnit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Wire.begin(SDA_PIN, SCL_PIN);
|
||||||
|
|
||||||
|
if (!bme.begin())
|
||||||
|
{
|
||||||
|
SensorType = 0;
|
||||||
|
Serial.println("Could not find BME280I2C sensor!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (bme.chipModel())
|
||||||
|
{
|
||||||
|
case BME280::ChipModel_BME280:
|
||||||
|
SensorType = 1;
|
||||||
|
Serial.println("Found BME280 sensor! Success.");
|
||||||
|
break;
|
||||||
|
case BME280::ChipModel_BMP280:
|
||||||
|
SensorType = 2;
|
||||||
|
Serial.println("Found BMP280 sensor! No Humidity available.");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SensorType = 0;
|
||||||
|
Serial.println("Found UNKNOWN sensor! Error!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
// BME280 sensor MQTT publishing
|
||||||
|
// Check if sensor present and MQTT Connected, otherwise it will crash the MCU
|
||||||
|
if (SensorType != 0 && mqtt != nullptr)
|
||||||
|
{
|
||||||
|
// Timer to fetch new temperature, humidity and pressure data at intervals
|
||||||
|
timer = millis();
|
||||||
|
|
||||||
|
if (timer - lastTemperatureMeasure >= TemperatureInterval * 1000 || mqttTemperaturePub == 0)
|
||||||
|
{
|
||||||
|
lastTemperatureMeasure = timer;
|
||||||
|
|
||||||
|
UpdateBME280Data(SensorType);
|
||||||
|
|
||||||
|
float Temperature = roundf(SensorTemperature * pow(10, TemperatureDecimals)) / pow(10, TemperatureDecimals);
|
||||||
|
float Humidity, HeatIndex, DewPoint;
|
||||||
|
|
||||||
|
// If temperature has changed since last measure, create string populated with device topic
|
||||||
|
// from the UI and values read from sensor, then publish to broker
|
||||||
|
if (Temperature != lastTemperature)
|
||||||
|
{
|
||||||
|
String topic = String(mqttDeviceTopic) + "/temperature";
|
||||||
|
mqttTemperaturePub = mqtt->publish(topic.c_str(), 0, false, String(Temperature, TemperatureDecimals).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
lastTemperature = Temperature; // Update last sensor temperature for next loop
|
||||||
|
|
||||||
|
if (SensorType == 1) // Only if sensor is a BME280
|
||||||
|
{
|
||||||
|
Humidity = roundf(SensorHumidity * pow(10, HumidityDecimals)) / pow(10, HumidityDecimals);
|
||||||
|
HeatIndex = roundf(SensorHeatIndex * pow(10, TemperatureDecimals)) / pow(10, TemperatureDecimals);
|
||||||
|
DewPoint = roundf(SensorDewPoint * pow(10, TemperatureDecimals)) / pow(10, TemperatureDecimals);
|
||||||
|
|
||||||
|
if (Humidity != lastHumidity)
|
||||||
|
{
|
||||||
|
String topic = String(mqttDeviceTopic) + "/humidity";
|
||||||
|
mqtt->publish(topic.c_str(), 0, false, String(Humidity, HumidityDecimals).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HeatIndex != lastHeatIndex)
|
||||||
|
{
|
||||||
|
String topic = String(mqttDeviceTopic) + "/heat_index";
|
||||||
|
mqtt->publish(topic.c_str(), 0, false, String(HeatIndex, TemperatureDecimals).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DewPoint != lastDewPoint)
|
||||||
|
{
|
||||||
|
String topic = String(mqttDeviceTopic) + "/dew_point";
|
||||||
|
mqtt->publish(topic.c_str(), 0, false, String(DewPoint, TemperatureDecimals).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
lastHumidity = Humidity;
|
||||||
|
lastHeatIndex = HeatIndex;
|
||||||
|
lastDewPoint = DewPoint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timer - lastPressureMeasure >= PressureInterval * 1000 || mqttPressurePub == 0)
|
||||||
|
{
|
||||||
|
lastPressureMeasure = timer;
|
||||||
|
|
||||||
|
float Pressure = roundf(SensorPressure * pow(10, PressureDecimals)) / pow(10, PressureDecimals);
|
||||||
|
|
||||||
|
if (Pressure != lastPressure)
|
||||||
|
{
|
||||||
|
String topic = String(mqttDeviceTopic) + "/pressure";
|
||||||
|
mqttPressurePub = mqtt->publish(topic.c_str(), 0, true, String(Pressure, PressureDecimals).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
lastPressure = Pressure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
@ -5,11 +5,13 @@
|
|||||||
#include <DallasTemperature.h> //DS18B20
|
#include <DallasTemperature.h> //DS18B20
|
||||||
|
|
||||||
//Pin defaults for QuinLed Dig-Uno
|
//Pin defaults for QuinLed Dig-Uno
|
||||||
|
#ifndef TEMPERATURE_PIN
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
#define TEMPERATURE_PIN 18
|
#define TEMPERATURE_PIN 18
|
||||||
#else //ESP8266 boards
|
#else //ESP8266 boards
|
||||||
#define TEMPERATURE_PIN 14
|
#define TEMPERATURE_PIN 14
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// the frequency to check temperature, 1 minute
|
// the frequency to check temperature, 1 minute
|
||||||
#ifndef USERMOD_DALLASTEMPERATURE_MEASUREMENT_INTERVAL
|
#ifndef USERMOD_DALLASTEMPERATURE_MEASUREMENT_INTERVAL
|
||||||
@ -58,6 +60,7 @@ class UsermodTemperature : public Usermod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void getTemperature() {
|
void getTemperature() {
|
||||||
|
if (strip.isUpdating()) return;
|
||||||
#ifdef USERMOD_DALLASTEMPERATURE_CELSIUS
|
#ifdef USERMOD_DALLASTEMPERATURE_CELSIUS
|
||||||
temperature = sensor.getTempC(sensorDeviceAddress);
|
temperature = sensor.getTempC(sensorDeviceAddress);
|
||||||
#else
|
#else
|
||||||
@ -80,30 +83,28 @@ class UsermodTemperature : public Usermod {
|
|||||||
disabled = !sensor.getAddress(sensorDeviceAddress, 0);
|
disabled = !sensor.getAddress(sensorDeviceAddress, 0);
|
||||||
|
|
||||||
if (!disabled) {
|
if (!disabled) {
|
||||||
DEBUG_PRINTLN("Dallas Temperature found");
|
DEBUG_PRINTLN(F("Dallas Temperature found"));
|
||||||
// set the resolution for this specific device
|
// set the resolution for this specific device
|
||||||
sensor.setResolution(sensorDeviceAddress, 9, true);
|
sensor.setResolution(sensorDeviceAddress, 9, true);
|
||||||
// do not block waiting for reading
|
// do not block waiting for reading
|
||||||
sensor.setWaitForConversion(false);
|
sensor.setWaitForConversion(false);
|
||||||
|
// allocate pin & prevent other use
|
||||||
|
if (!pinManager.allocatePin(TEMPERATURE_PIN,false))
|
||||||
|
disabled = true;
|
||||||
} else {
|
} else {
|
||||||
DEBUG_PRINTLN("Dallas Temperature not found");
|
DEBUG_PRINTLN(F("Dallas Temperature not found"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
if (disabled) {
|
if (disabled || strip.isUpdating()) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long now = millis();
|
unsigned long now = millis();
|
||||||
|
|
||||||
// check to see if we are due for taking a measurement
|
// check to see if we are due for taking a measurement
|
||||||
// lastMeasurement will not be updated until the conversion
|
// lastMeasurement will not be updated until the conversion
|
||||||
// is complete the the reading is finished
|
// is complete the the reading is finished
|
||||||
if (now - lastMeasurement < USERMOD_DALLASTEMPERATURE_MEASUREMENT_INTERVAL)
|
if (now - lastMeasurement < USERMOD_DALLASTEMPERATURE_MEASUREMENT_INTERVAL) return;
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we are due for a measurement, if we are not already waiting
|
// we are due for a measurement, if we are not already waiting
|
||||||
// for a conversion to complete, then make a new request for temps
|
// for a conversion to complete, then make a new request for temps
|
||||||
@ -125,7 +126,7 @@ class UsermodTemperature : public Usermod {
|
|||||||
// dont publish super low temperature as the graph will get messed up
|
// dont publish super low temperature as the graph will get messed up
|
||||||
// the DallasTemperature library returns -127C or -196.6F when problem
|
// the DallasTemperature library returns -127C or -196.6F when problem
|
||||||
// reading the sensor
|
// reading the sensor
|
||||||
strcat(subuf, "/temperature");
|
strcat_P(subuf, PSTR("/temperature"));
|
||||||
mqtt->publish(subuf, 0, true, String(temperature).c_str());
|
mqtt->publish(subuf, 0, true, String(temperature).c_str());
|
||||||
} else {
|
} else {
|
||||||
// publish something else to indicate status?
|
// publish something else to indicate status?
|
||||||
@ -136,34 +137,32 @@ class UsermodTemperature : public Usermod {
|
|||||||
|
|
||||||
void addToJsonInfo(JsonObject& root) {
|
void addToJsonInfo(JsonObject& root) {
|
||||||
// dont add temperature to info if we are disabled
|
// dont add temperature to info if we are disabled
|
||||||
if (disabled) {
|
if (disabled) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonObject user = root["u"];
|
JsonObject user = root[F("u")];
|
||||||
if (user.isNull()) user = root.createNestedObject("u");
|
if (user.isNull()) user = root.createNestedObject(F("u"));
|
||||||
|
|
||||||
JsonArray temp = user.createNestedArray("Temperature");
|
JsonArray temp = user.createNestedArray(F("Temperature"));
|
||||||
|
|
||||||
if (!getTemperatureComplete) {
|
if (!getTemperatureComplete) {
|
||||||
// if we haven't read the sensor yet, let the user know
|
// if we haven't read the sensor yet, let the user know
|
||||||
// that we are still waiting for the first measurement
|
// that we are still waiting for the first measurement
|
||||||
temp.add((USERMOD_DALLASTEMPERATURE_FIRST_MEASUREMENT_AT - millis()) / 1000);
|
temp.add((USERMOD_DALLASTEMPERATURE_FIRST_MEASUREMENT_AT - millis()) / 1000);
|
||||||
temp.add(" sec until read");
|
temp.add(F(" sec until read"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (temperature <= -100) {
|
if (temperature <= -100) {
|
||||||
temp.add(0);
|
temp.add(0);
|
||||||
temp.add(" Sensor Error!");
|
temp.add(F(" Sensor Error!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
temp.add(temperature);
|
temp.add(temperature);
|
||||||
#ifdef USERMOD_DALLASTEMPERATURE_CELSIUS
|
#ifdef USERMOD_DALLASTEMPERATURE_CELSIUS
|
||||||
temp.add("°C");
|
temp.add(F("°C"));
|
||||||
#else
|
#else
|
||||||
temp.add("°F");
|
temp.add(F("°F"));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,7 +545,7 @@ uint16_t WS2812FX::dissolve(uint32_t color) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SEGENV.call > (255 - SEGMENT.speed) + 15)
|
if (SEGENV.call > (255 - SEGMENT.speed) + 15U)
|
||||||
{
|
{
|
||||||
SEGENV.aux0 = !SEGENV.aux0;
|
SEGENV.aux0 = !SEGENV.aux0;
|
||||||
SEGENV.call = 0;
|
SEGENV.call = 0;
|
||||||
@ -1034,7 +1034,7 @@ uint16_t WS2812FX::mode_running_random(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SEGENV.step++;
|
SEGENV.step++;
|
||||||
if (SEGENV.step > ((255-SEGMENT.intensity) >> 4))
|
if (SEGENV.step > (uint8_t)((255-SEGMENT.intensity) >> 4))
|
||||||
{
|
{
|
||||||
SEGENV.step = 0;
|
SEGENV.step = 0;
|
||||||
}
|
}
|
||||||
@ -1257,7 +1257,7 @@ uint16_t WS2812FX::police_base(uint32_t color1, uint32_t color2, bool all)
|
|||||||
for (uint16_t i = idexB; i < idexR; i++) setPixelColor(i, color2);
|
for (uint16_t i = idexB; i < idexR; i++) setPixelColor(i, color2);
|
||||||
}
|
}
|
||||||
} else { //regular dot-only mode
|
} else { //regular dot-only mode
|
||||||
uint8_t size = 1 + SEGMENT.intensity >> 3;
|
uint8_t size = 1 + (SEGMENT.intensity >> 3);
|
||||||
if (size > SEGLEN/2) size = 1+ SEGLEN/2;
|
if (size > SEGLEN/2) size = 1+ SEGLEN/2;
|
||||||
for (uint8_t i=0; i <= size; i++) {
|
for (uint8_t i=0; i <= size; i++) {
|
||||||
setPixelColor(idexR+i, color1);
|
setPixelColor(idexR+i, color1);
|
||||||
@ -1568,9 +1568,9 @@ uint16_t WS2812FX::mode_oscillate(void)
|
|||||||
|
|
||||||
if (SEGENV.call == 0)
|
if (SEGENV.call == 0)
|
||||||
{
|
{
|
||||||
oscillators[0] = {SEGLEN/4, SEGLEN/8, 1, 1};
|
oscillators[0] = {(int16_t)(SEGLEN/4), (int8_t)(SEGLEN/8), 1, 1};
|
||||||
oscillators[1] = {SEGLEN/4*3, SEGLEN/8, 1, 2};
|
oscillators[1] = {(int16_t)(SEGLEN/4*3), (int8_t)(SEGLEN/8), 1, 2};
|
||||||
oscillators[2] = {SEGLEN/4*2, SEGLEN/8, -1, 1};
|
oscillators[2] = {(int16_t)(SEGLEN/4*2), (int8_t)(SEGLEN/8), -1, 1};
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t cycleTime = 20 + (2 * (uint32_t)(255 - SEGMENT.speed));
|
uint32_t cycleTime = 20 + (2 * (uint32_t)(255 - SEGMENT.speed));
|
||||||
@ -1919,7 +1919,6 @@ uint16_t WS2812FX::mode_noise16_2()
|
|||||||
for (uint16_t i = 0; i < SEGLEN; i++) {
|
for (uint16_t i = 0; i < SEGLEN; i++) {
|
||||||
|
|
||||||
uint16_t shift_x = SEGENV.step >> 6; // x as a function of time
|
uint16_t shift_x = SEGENV.step >> 6; // x as a function of time
|
||||||
uint16_t shift_y = SEGENV.step/42;
|
|
||||||
|
|
||||||
uint32_t real_x = (i + shift_x) * scale; // calculate the coordinates within the noise field
|
uint32_t real_x = (i + shift_x) * scale; // calculate the coordinates within the noise field
|
||||||
|
|
||||||
@ -3198,8 +3197,8 @@ uint16_t WS2812FX::mode_plasma(void) {
|
|||||||
uint8_t thatPhase = beatsin8(7,-64,64);
|
uint8_t thatPhase = beatsin8(7,-64,64);
|
||||||
|
|
||||||
for (int i = 0; i < SEGLEN; i++) { // For each of the LED's in the strand, set color & brightness based on a wave as follows:
|
for (int i = 0; i < SEGLEN; i++) { // For each of the LED's in the strand, set color & brightness based on a wave as follows:
|
||||||
uint8_t colorIndex = cubicwave8((i*(1+ 3*(SEGMENT.speed >> 5)))+(thisPhase) & 0xFF)/2 // factor=23 // Create a wave and add a phase change and add another wave with its own phase change.
|
uint8_t colorIndex = cubicwave8(((i*(1+ 3*(SEGMENT.speed >> 5)))+(thisPhase)) & 0xFF)/2 // factor=23 // Create a wave and add a phase change and add another wave with its own phase change.
|
||||||
+ cos8((i*(1+ 2*(SEGMENT.speed >> 5)))+(thatPhase) & 0xFF)/2; // factor=15 // Hey, you can even change the frequencies if you wish.
|
+ cos8(((i*(1+ 2*(SEGMENT.speed >> 5)))+(thatPhase)) & 0xFF)/2; // factor=15 // Hey, you can even change the frequencies if you wish.
|
||||||
uint8_t thisBright = qsub8(colorIndex, beatsin8(6,0, (255 - SEGMENT.intensity)|0x01 ));
|
uint8_t thisBright = qsub8(colorIndex, beatsin8(6,0, (255 - SEGMENT.intensity)|0x01 ));
|
||||||
CRGB color = ColorFromPalette(currentPalette, colorIndex, thisBright, LINEARBLEND);
|
CRGB color = ColorFromPalette(currentPalette, colorIndex, thisBright, LINEARBLEND);
|
||||||
setPixelColor(i, color.red, color.green, color.blue);
|
setPixelColor(i, color.red, color.green, color.blue);
|
||||||
|
31
wled00/FX.h
31
wled00/FX.h
@ -29,12 +29,6 @@
|
|||||||
#ifndef WS2812FX_h
|
#ifndef WS2812FX_h
|
||||||
#define WS2812FX_h
|
#define WS2812FX_h
|
||||||
|
|
||||||
#ifdef ESP32_MULTISTRIP
|
|
||||||
#include "../usermods/esp32_multistrip/NpbWrapper.h"
|
|
||||||
#else
|
|
||||||
#include "NpbWrapper.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "const.h"
|
#include "const.h"
|
||||||
|
|
||||||
#define FASTLED_INTERNAL //remove annoying pragma messages
|
#define FASTLED_INTERNAL //remove annoying pragma messages
|
||||||
@ -586,12 +580,11 @@ class WS2812FX {
|
|||||||
ablMilliampsMax = 850;
|
ablMilliampsMax = 850;
|
||||||
currentMilliamps = 0;
|
currentMilliamps = 0;
|
||||||
timebase = 0;
|
timebase = 0;
|
||||||
bus = new NeoPixelWrapper();
|
|
||||||
resetSegments();
|
resetSegments();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
init(bool supportWhite, uint16_t countPixels, bool skipFirst),
|
finalizeInit(bool supportWhite, uint16_t countPixels, bool skipFirst),
|
||||||
service(void),
|
service(void),
|
||||||
blur(uint8_t),
|
blur(uint8_t),
|
||||||
fill(uint32_t),
|
fill(uint32_t),
|
||||||
@ -631,6 +624,8 @@ class WS2812FX {
|
|||||||
paletteFade = 0,
|
paletteFade = 0,
|
||||||
paletteBlend = 0,
|
paletteBlend = 0,
|
||||||
milliampsPerLed = 55,
|
milliampsPerLed = 55,
|
||||||
|
// getStripType(uint8_t strip=0),
|
||||||
|
// setStripType(uint8_t type, uint8_t strip=0),
|
||||||
getBrightness(void),
|
getBrightness(void),
|
||||||
getMode(void),
|
getMode(void),
|
||||||
getSpeed(void),
|
getSpeed(void),
|
||||||
@ -645,12 +640,19 @@ class WS2812FX {
|
|||||||
get_random_wheel_index(uint8_t);
|
get_random_wheel_index(uint8_t);
|
||||||
|
|
||||||
int8_t
|
int8_t
|
||||||
|
// setStripPin(uint8_t strip, int8_t pin),
|
||||||
|
// getStripPin(uint8_t strip=0),
|
||||||
|
// setStripPinClk(uint8_t strip, int8_t pin),
|
||||||
|
// getStripPinClk(uint8_t strip=0),
|
||||||
tristate_square8(uint8_t x, uint8_t pulsewidth, uint8_t attdec);
|
tristate_square8(uint8_t x, uint8_t pulsewidth, uint8_t attdec);
|
||||||
|
|
||||||
uint16_t
|
uint16_t
|
||||||
ablMilliampsMax,
|
ablMilliampsMax,
|
||||||
currentMilliamps,
|
currentMilliamps,
|
||||||
triwave16(uint16_t);
|
// setStripLen(uint8_t strip, uint16_t len),
|
||||||
|
// getStripLen(uint8_t strip=0),
|
||||||
|
triwave16(uint16_t),
|
||||||
|
getFps();
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
now,
|
now,
|
||||||
@ -796,8 +798,6 @@ class WS2812FX {
|
|||||||
mode_dynamic_smooth(void);
|
mode_dynamic_smooth(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NeoPixelWrapper *bus;
|
|
||||||
|
|
||||||
uint32_t crgb_to_col(CRGB fastled);
|
uint32_t crgb_to_col(CRGB fastled);
|
||||||
CRGB col_to_crgb(uint32_t);
|
CRGB col_to_crgb(uint32_t);
|
||||||
CRGBPalette16 currentPalette;
|
CRGBPalette16 currentPalette;
|
||||||
@ -809,11 +809,12 @@ class WS2812FX {
|
|||||||
uint16_t _usedSegmentData = 0;
|
uint16_t _usedSegmentData = 0;
|
||||||
uint16_t _transitionDur = 750;
|
uint16_t _transitionDur = 750;
|
||||||
|
|
||||||
|
uint16_t _cumulativeFps = 2;
|
||||||
|
|
||||||
void load_gradient_palette(uint8_t);
|
void load_gradient_palette(uint8_t);
|
||||||
void handle_palette(void);
|
void handle_palette(void);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
shouldStartBus = false,
|
|
||||||
_useRgbw = false,
|
_useRgbw = false,
|
||||||
_skipFirstMode,
|
_skipFirstMode,
|
||||||
_triggered;
|
_triggered;
|
||||||
@ -861,12 +862,6 @@ class WS2812FX {
|
|||||||
uint32_t _colors_t[3];
|
uint32_t _colors_t[3];
|
||||||
uint8_t _bri_t;
|
uint8_t _bri_t;
|
||||||
|
|
||||||
#ifdef WLED_USE_ANALOG_LEDS
|
|
||||||
uint32_t _analogLastShow = 0;
|
|
||||||
RgbwColor _analogLastColor = 0;
|
|
||||||
uint8_t _analogLastBri = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint8_t _segment_index = 0;
|
uint8_t _segment_index = 0;
|
||||||
uint8_t _segment_index_palette_last = 99;
|
uint8_t _segment_index_palette_last = 99;
|
||||||
segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 24 bytes per element
|
segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 24 bytes per element
|
||||||
|
@ -47,7 +47,8 @@
|
|||||||
19, 18, 17, 16, 15, 20, 21, 22, 23, 24, 29, 28, 27, 26, 25]
|
19, 18, 17, 16, 15, 20, 21, 22, 23, 24, 29, 28, 27, 26, 25]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst)
|
//do not call this method from system context (network callback)
|
||||||
|
void WS2812FX::finalizeInit(bool supportWhite, uint16_t countPixels, bool skipFirst)
|
||||||
{
|
{
|
||||||
if (supportWhite == _useRgbw && countPixels == _length && _skipFirstMode == skipFirst) return;
|
if (supportWhite == _useRgbw && countPixels == _length && _skipFirstMode == skipFirst) return;
|
||||||
RESET_RUNTIME;
|
RESET_RUNTIME;
|
||||||
@ -55,21 +56,36 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst)
|
|||||||
_length = countPixels;
|
_length = countPixels;
|
||||||
_skipFirstMode = skipFirst;
|
_skipFirstMode = skipFirst;
|
||||||
|
|
||||||
uint8_t ty = 1;
|
|
||||||
if (supportWhite) ty = 2;
|
|
||||||
_lengthRaw = _length;
|
_lengthRaw = _length;
|
||||||
if (_skipFirstMode) {
|
if (_skipFirstMode) {
|
||||||
_lengthRaw += LED_SKIP_AMOUNT;
|
_lengthRaw += LED_SKIP_AMOUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if busses failed to load, add default (FS issue...)
|
||||||
|
if (busses.getNumBusses() == 0) {
|
||||||
|
uint8_t defPin[] = {LEDPIN};
|
||||||
|
BusConfig defCfg = BusConfig(TYPE_WS2812_RGB, defPin, 0, _lengthRaw, COL_ORDER_GRB);
|
||||||
|
busses.add(defCfg);
|
||||||
|
}
|
||||||
|
|
||||||
deserializeMap();
|
deserializeMap();
|
||||||
|
|
||||||
bus->Begin((NeoPixelType)ty, _lengthRaw);
|
//make segment 0 cover the entire strip
|
||||||
|
|
||||||
_segments[0].start = 0;
|
_segments[0].start = 0;
|
||||||
_segments[0].stop = _length;
|
_segments[0].stop = _length;
|
||||||
|
|
||||||
setBrightness(_brightness);
|
setBrightness(_brightness);
|
||||||
|
|
||||||
|
#ifdef ESP8266
|
||||||
|
for (uint8_t i = 0; i < busses.getNumBusses(); i++) {
|
||||||
|
Bus* b = busses.getBus(i);
|
||||||
|
if ((!IS_DIGITAL(b->getType()) || IS_2PIN(b->getType()))) continue;
|
||||||
|
uint8_t pins[5];
|
||||||
|
b->getPins(pins);
|
||||||
|
BusDigital* bd = static_cast<BusDigital*>(b);
|
||||||
|
if (pins[0] == 3) bd->reinit();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void WS2812FX::service() {
|
void WS2812FX::service() {
|
||||||
@ -168,19 +184,17 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RgbwColor col;
|
|
||||||
col.R = r; col.G = g; col.B = b; col.W = w;
|
|
||||||
|
|
||||||
uint16_t skip = _skipFirstMode ? LED_SKIP_AMOUNT : 0;
|
uint16_t skip = _skipFirstMode ? LED_SKIP_AMOUNT : 0;
|
||||||
if (SEGLEN) {//from segment
|
if (SEGLEN) {//from segment
|
||||||
|
|
||||||
//color_blend(getpixel, col, _bri_t); (pseudocode for future blending of segments)
|
//color_blend(getpixel, col, _bri_t); (pseudocode for future blending of segments)
|
||||||
if (_bri_t < 255) {
|
if (_bri_t < 255) {
|
||||||
col.R = scale8(col.R, _bri_t);
|
r = scale8(r, _bri_t);
|
||||||
col.G = scale8(col.G, _bri_t);
|
g = scale8(g, _bri_t);
|
||||||
col.B = scale8(col.B, _bri_t);
|
b = scale8(b, _bri_t);
|
||||||
col.W = scale8(col.W, _bri_t);
|
w = scale8(w, _bri_t);
|
||||||
}
|
}
|
||||||
|
uint32_t col = ((w << 24) | (r << 16) | (g << 8) | (b));
|
||||||
|
|
||||||
/* Set all the pixels in the group, ensuring _skipFirstMode is honored */
|
/* Set all the pixels in the group, ensuring _skipFirstMode is honored */
|
||||||
bool reversed = reverseMode ^ IS_REVERSE;
|
bool reversed = reverseMode ^ IS_REVERSE;
|
||||||
@ -192,12 +206,12 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
|||||||
if (reverseMode) indexSetRev = REV(indexSet);
|
if (reverseMode) indexSetRev = REV(indexSet);
|
||||||
if (indexSet < customMappingSize) indexSet = customMappingTable[indexSet];
|
if (indexSet < customMappingSize) indexSet = customMappingTable[indexSet];
|
||||||
if (indexSetRev >= SEGMENT.start && indexSetRev < SEGMENT.stop) {
|
if (indexSetRev >= SEGMENT.start && indexSetRev < SEGMENT.stop) {
|
||||||
bus->SetPixelColor(indexSet + skip, col);
|
busses.setPixelColor(indexSet + skip, col);
|
||||||
if (IS_MIRROR) { //set the corresponding mirrored pixel
|
if (IS_MIRROR) { //set the corresponding mirrored pixel
|
||||||
if (reverseMode) {
|
if (reverseMode) {
|
||||||
bus->SetPixelColor(REV(SEGMENT.start) - indexSet + skip + REV(SEGMENT.stop) + 1, col);
|
busses.setPixelColor(REV(SEGMENT.start) - indexSet + skip + REV(SEGMENT.stop) + 1, col);
|
||||||
} else {
|
} else {
|
||||||
bus->SetPixelColor(SEGMENT.stop - indexSet + skip + SEGMENT.start - 1, col);
|
busses.setPixelColor(SEGMENT.stop - indexSet + skip + SEGMENT.start - 1, col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -205,11 +219,13 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
|||||||
} else { //live data, etc.
|
} else { //live data, etc.
|
||||||
if (reverseMode) i = REV(i);
|
if (reverseMode) i = REV(i);
|
||||||
if (i < customMappingSize) i = customMappingTable[i];
|
if (i < customMappingSize) i = customMappingTable[i];
|
||||||
bus->SetPixelColor(i + skip, col);
|
|
||||||
|
uint32_t col = ((w << 24) | (r << 16) | (g << 8) | (b));
|
||||||
|
busses.setPixelColor(i + skip, col);
|
||||||
}
|
}
|
||||||
if (skip && i == 0) {
|
if (skip && i == 0) {
|
||||||
for (uint16_t j = 0; j < skip; j++) {
|
for (uint16_t j = 0; j < skip; j++) {
|
||||||
bus->SetPixelColor(j, RgbwColor(0, 0, 0, 0));
|
busses.setPixelColor(j, BLACK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -260,7 +276,7 @@ void WS2812FX::show(void) {
|
|||||||
|
|
||||||
for (uint16_t i = 0; i < _length; i++) //sum up the usage of each LED
|
for (uint16_t i = 0; i < _length; i++) //sum up the usage of each LED
|
||||||
{
|
{
|
||||||
RgbwColor c = bus->GetPixelColorRaw(i);
|
RgbwColor c = busses.getPixelColor(i);
|
||||||
|
|
||||||
if(useWackyWS2815PowerModel)
|
if(useWackyWS2815PowerModel)
|
||||||
{
|
{
|
||||||
@ -289,25 +305,30 @@ void WS2812FX::show(void) {
|
|||||||
uint16_t scaleI = scale * 255;
|
uint16_t scaleI = scale * 255;
|
||||||
uint8_t scaleB = (scaleI > 255) ? 255 : scaleI;
|
uint8_t scaleB = (scaleI > 255) ? 255 : scaleI;
|
||||||
uint8_t newBri = scale8(_brightness, scaleB);
|
uint8_t newBri = scale8(_brightness, scaleB);
|
||||||
bus->SetBrightness(newBri);
|
busses.setBrightness(newBri);
|
||||||
currentMilliamps = (powerSum0 * newBri) / puPerMilliamp;
|
currentMilliamps = (powerSum0 * newBri) / puPerMilliamp;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
currentMilliamps = powerSum / puPerMilliamp;
|
currentMilliamps = powerSum / puPerMilliamp;
|
||||||
bus->SetBrightness(_brightness);
|
busses.setBrightness(_brightness);
|
||||||
}
|
}
|
||||||
currentMilliamps += MA_FOR_ESP; //add power of ESP back to estimate
|
currentMilliamps += MA_FOR_ESP; //add power of ESP back to estimate
|
||||||
currentMilliamps += _length; //add standby power back to estimate
|
currentMilliamps += _length; //add standby power back to estimate
|
||||||
} else {
|
} else {
|
||||||
currentMilliamps = 0;
|
currentMilliamps = 0;
|
||||||
bus->SetBrightness(_brightness);
|
busses.setBrightness(_brightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
// some buses send asynchronously and this method will return before
|
// some buses send asynchronously and this method will return before
|
||||||
// all of the data has been sent.
|
// all of the data has been sent.
|
||||||
// See https://github.com/Makuna/NeoPixelBus/wiki/ESP32-NeoMethods#neoesp32rmt-methods
|
// See https://github.com/Makuna/NeoPixelBus/wiki/ESP32-NeoMethods#neoesp32rmt-methods
|
||||||
bus->Show();
|
busses.show();
|
||||||
_lastShow = millis();
|
unsigned long now = millis();
|
||||||
|
unsigned long diff = now - _lastShow;
|
||||||
|
uint16_t fpsCurr = 200;
|
||||||
|
if (diff > 0) fpsCurr = 1000 / diff;
|
||||||
|
_cumulativeFps = (3 * _cumulativeFps + fpsCurr) >> 2;
|
||||||
|
_lastShow = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -315,7 +336,16 @@ void WS2812FX::show(void) {
|
|||||||
* On some hardware (ESP32), strip updates are done asynchronously.
|
* On some hardware (ESP32), strip updates are done asynchronously.
|
||||||
*/
|
*/
|
||||||
bool WS2812FX::isUpdating() {
|
bool WS2812FX::isUpdating() {
|
||||||
return !bus->CanShow();
|
return !busses.canAllShow();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the refresh rate of the LED strip. Useful for finding out whether a given setup is fast enough.
|
||||||
|
* Only updates on show() or is set to 0 fps if last show is more than 2 secs ago, so accurary varies
|
||||||
|
*/
|
||||||
|
uint16_t WS2812FX::getFps() {
|
||||||
|
if (millis() - _lastShow > 2000) return 0;
|
||||||
|
return _cumulativeFps +1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -351,7 +381,6 @@ uint8_t WS2812FX::getPaletteCount()
|
|||||||
|
|
||||||
|
|
||||||
bool WS2812FX::setEffectConfig(uint8_t m, uint8_t s, uint8_t in, uint8_t p) {
|
bool WS2812FX::setEffectConfig(uint8_t m, uint8_t s, uint8_t in, uint8_t p) {
|
||||||
uint8_t mainSeg = getMainSegmentId();
|
|
||||||
Segment& seg = _segments[getMainSegmentId()];
|
Segment& seg = _segments[getMainSegmentId()];
|
||||||
uint8_t modePrev = seg.mode, speedPrev = seg.speed, intensityPrev = seg.intensity, palettePrev = seg.palette;
|
uint8_t modePrev = seg.mode, speedPrev = seg.speed, intensityPrev = seg.intensity, palettePrev = seg.palette;
|
||||||
|
|
||||||
@ -417,17 +446,6 @@ void WS2812FX::setBrightness(uint8_t b) {
|
|||||||
{
|
{
|
||||||
_segments[i].setOption(SEG_OPTION_FREEZE, false);
|
_segments[i].setOption(SEG_OPTION_FREEZE, false);
|
||||||
}
|
}
|
||||||
#if LEDPIN == LED_BUILTIN
|
|
||||||
shouldStartBus = true;
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
#if LEDPIN == LED_BUILTIN
|
|
||||||
if (shouldStartBus) {
|
|
||||||
shouldStartBus = false;
|
|
||||||
const uint8_t ty = _useRgbw ? 2 : 1;
|
|
||||||
bus->Begin((NeoPixelType)ty, _lengthRaw);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
if (SEGENV.next_time > millis() + 22 && millis() - _lastShow > MIN_SHOW_DELAY) show();//apply brightness change immediately if no refresh soon
|
if (SEGENV.next_time > millis() + 22 && millis() - _lastShow > MIN_SHOW_DELAY) show();//apply brightness change immediately if no refresh soon
|
||||||
}
|
}
|
||||||
@ -485,7 +503,7 @@ uint32_t WS2812FX::getPixelColor(uint16_t i)
|
|||||||
|
|
||||||
if (i >= _lengthRaw) return 0;
|
if (i >= _lengthRaw) return 0;
|
||||||
|
|
||||||
return bus->GetPixelColorRgbw(i);
|
return busses.getPixelColor(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
WS2812FX::Segment& WS2812FX::getSegment(uint8_t id) {
|
WS2812FX::Segment& WS2812FX::getSegment(uint8_t id) {
|
||||||
@ -505,12 +523,13 @@ uint32_t WS2812FX::getLastShow(void) {
|
|||||||
return _lastShow;
|
return _lastShow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO these need to be on a per-strip basis
|
||||||
uint8_t WS2812FX::getColorOrder(void) {
|
uint8_t WS2812FX::getColorOrder(void) {
|
||||||
return bus->GetColorOrder();
|
return COL_ORDER_GRB;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WS2812FX::setColorOrder(uint8_t co) {
|
void WS2812FX::setColorOrder(uint8_t co) {
|
||||||
bus->SetColorOrder(co);
|
//bus->SetColorOrder(co);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping, uint8_t spacing) {
|
void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping, uint8_t spacing) {
|
||||||
@ -962,44 +981,6 @@ bool WS2812FX::segmentsAreIdentical(Segment* a, Segment* b)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WLED_USE_ANALOG_LEDS
|
|
||||||
void WS2812FX::setRgbwPwm(void) {
|
|
||||||
uint32_t nowUp = millis(); // Be aware, millis() rolls over every 49 days
|
|
||||||
if (nowUp - _analogLastShow < MIN_SHOW_DELAY) return;
|
|
||||||
|
|
||||||
_analogLastShow = nowUp;
|
|
||||||
|
|
||||||
RgbwColor c;
|
|
||||||
uint32_t col = bus->GetPixelColorRgbw(PWM_INDEX);
|
|
||||||
c.R = col >> 16; c.G = col >> 8; c.B = col; c.W = col >> 24;
|
|
||||||
|
|
||||||
byte b = getBrightness();
|
|
||||||
if (c == _analogLastColor && b == _analogLastBri) return;
|
|
||||||
|
|
||||||
// check color values for Warm / Cold white mix (for RGBW) // EsplanexaDevice.cpp
|
|
||||||
#ifdef WLED_USE_5CH_LEDS
|
|
||||||
if (c.R == 255 && c.G == 255 && c.B == 255 && c.W == 255) {
|
|
||||||
bus->SetRgbwPwm(0, 0, 0, 0, c.W * b / 255);
|
|
||||||
} else if (c.R == 127 && c.G == 127 && c.B == 127 && c.W == 255) {
|
|
||||||
bus->SetRgbwPwm(0, 0, 0, c.W * b / 512, c.W * b / 255);
|
|
||||||
} else if (c.R == 0 && c.G == 0 && c.B == 0 && c.W == 255) {
|
|
||||||
bus->SetRgbwPwm(0, 0, 0, c.W * b / 255, 0);
|
|
||||||
} else if (c.R == 130 && c.G == 90 && c.B == 0 && c.W == 255) {
|
|
||||||
bus->SetRgbwPwm(0, 0, 0, c.W * b / 255, c.W * b / 512);
|
|
||||||
} else if (c.R == 255 && c.G == 153 && c.B == 0 && c.W == 255) {
|
|
||||||
bus->SetRgbwPwm(0, 0, 0, c.W * b / 255, 0);
|
|
||||||
} else { // not only white colors
|
|
||||||
bus->SetRgbwPwm(c.R * b / 255, c.G * b / 255, c.B * b / 255, c.W * b / 255);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
bus->SetRgbwPwm(c.R * b / 255, c.G * b / 255, c.B * b / 255, c.W * b / 255);
|
|
||||||
#endif
|
|
||||||
_analogLastColor = c;
|
|
||||||
_analogLastBri = b;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
void WS2812FX::setRgbwPwm() {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//load custom mapping table from JSON file
|
//load custom mapping table from JSON file
|
||||||
void WS2812FX::deserializeMap(void) {
|
void WS2812FX::deserializeMap(void) {
|
||||||
|
34
wled00/NodeStruct.h
Normal file
34
wled00/NodeStruct.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef WLED_NODESTRUCT_H
|
||||||
|
#define WLED_NODESTRUCT_H
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* NodeStruct from the ESP Easy project (https://github.com/letscontrolit/ESPEasy)
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <IPAddress.h>
|
||||||
|
|
||||||
|
#define NODE_TYPE_ID_UNDEFINED 0
|
||||||
|
#define NODE_TYPE_ID_ESP8266 82
|
||||||
|
#define NODE_TYPE_ID_ESP32 32
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* NodeStruct
|
||||||
|
\*********************************************************************************************/
|
||||||
|
struct NodeStruct
|
||||||
|
{
|
||||||
|
String nodeName;
|
||||||
|
IPAddress ip;
|
||||||
|
uint8_t unit;
|
||||||
|
uint8_t age;
|
||||||
|
uint8_t nodeType;
|
||||||
|
uint32_t build;
|
||||||
|
|
||||||
|
NodeStruct() : age(0), nodeType(0), build(0)
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < 4; ++i) { ip[i] = 0; }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
typedef std::map<uint8_t, NodeStruct> NodesMap;
|
||||||
|
|
||||||
|
#endif // WLED_NODESTRUCT_H
|
@ -1,439 +0,0 @@
|
|||||||
//this code is a modified version of https://github.com/Makuna/NeoPixelBus/issues/103
|
|
||||||
#ifndef NpbWrapper_h
|
|
||||||
#define NpbWrapper_h
|
|
||||||
|
|
||||||
//PIN CONFIGURATION
|
|
||||||
#ifndef LEDPIN
|
|
||||||
#define LEDPIN 2 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos)
|
|
||||||
#endif
|
|
||||||
//#define USE_APA102 // Uncomment for using APA102 LEDs.
|
|
||||||
//#define USE_WS2801 // Uncomment for using WS2801 LEDs (make sure you have NeoPixelBus v2.5.6 or newer)
|
|
||||||
//#define USE_LPD8806 // Uncomment for using LPD8806
|
|
||||||
//#define USE_TM1814 // Uncomment for using TM1814 LEDs (make sure you have NeoPixelBus v2.5.7 or newer)
|
|
||||||
//#define USE_P9813 // Uncomment for using P9813 LEDs (make sure you have NeoPixelBus v2.5.8 or newer)
|
|
||||||
//#define WLED_USE_ANALOG_LEDS //Uncomment for using "dumb" PWM controlled LEDs (see pins below, default R: gpio5, G: 12, B: 15, W: 13)
|
|
||||||
//#define WLED_USE_H801 //H801 controller. Please uncomment #define WLED_USE_ANALOG_LEDS as well
|
|
||||||
//#define WLED_USE_5CH_LEDS //5 Channel H801 for cold and warm white
|
|
||||||
//#define WLED_USE_BWLT11
|
|
||||||
//#define WLED_USE_SHOJO_PCB
|
|
||||||
|
|
||||||
#ifndef BTNPIN
|
|
||||||
#define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TOUCHPIN
|
|
||||||
//#define TOUCHPIN T0 //touch pin. Behaves the same as button. ESP32 only.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef IRPIN
|
|
||||||
#define IRPIN 4 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef RLYPIN
|
|
||||||
#define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,...
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef AUXPIN
|
|
||||||
#define AUXPIN -1 //debug auxiliary output pin (-1 to disable)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef RLYMDE
|
|
||||||
#define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//enable color order override for a specific range of the strip
|
|
||||||
//This can be useful if you want to chain multiple strings with incompatible color order
|
|
||||||
//#define COLOR_ORDER_OVERRIDE
|
|
||||||
#define COO_MIN 0
|
|
||||||
#define COO_MAX 35 //not inclusive, this would set the override for LEDs 0-34
|
|
||||||
#define COO_ORDER COL_ORDER_GRB
|
|
||||||
|
|
||||||
//END CONFIGURATION
|
|
||||||
|
|
||||||
#if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) || defined(USE_P9813)
|
|
||||||
#ifndef CLKPIN
|
|
||||||
#define CLKPIN 0
|
|
||||||
#endif
|
|
||||||
#ifndef DATAPIN
|
|
||||||
#define DATAPIN 2
|
|
||||||
#endif
|
|
||||||
#if BTNPIN == CLKPIN || BTNPIN == DATAPIN
|
|
||||||
#undef BTNPIN // Deactivate button pin if it conflicts with one of the APA102 pins.
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef WLED_USE_ANALOG_LEDS
|
|
||||||
//PWM pins - PINs 15,13,12,14 (W2 = 04)are used with H801 Wifi LED Controller
|
|
||||||
#ifdef WLED_USE_H801
|
|
||||||
#define RPIN 15 //R pin for analog LED strip
|
|
||||||
#define GPIN 13 //G pin for analog LED strip
|
|
||||||
#define BPIN 12 //B pin for analog LED strip
|
|
||||||
#define WPIN 14 //W pin for analog LED strip
|
|
||||||
#define W2PIN 04 //W2 pin for analog LED strip
|
|
||||||
#undef BTNPIN
|
|
||||||
#undef IRPIN
|
|
||||||
#define IRPIN 0 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0
|
|
||||||
#elif defined(WLED_USE_BWLT11)
|
|
||||||
//PWM pins - to use with BW-LT11
|
|
||||||
#define RPIN 12 //R pin for analog LED strip
|
|
||||||
#define GPIN 4 //G pin for analog LED strip
|
|
||||||
#define BPIN 14 //B pin for analog LED strip
|
|
||||||
#define WPIN 5 //W pin for analog LED strip
|
|
||||||
#elif defined(WLED_USE_SHOJO_PCB)
|
|
||||||
//PWM pins - to use with Shojo PCB (https://www.bastelbunker.de/esp-rgbww-wifi-led-controller-vbs-edition/)
|
|
||||||
#define RPIN 14 //R pin for analog LED strip
|
|
||||||
#define GPIN 4 //G pin for analog LED strip
|
|
||||||
#define BPIN 5 //B pin for analog LED strip
|
|
||||||
#define WPIN 15 //W pin for analog LED strip
|
|
||||||
#define W2PIN 12 //W2 pin for analog LED strip
|
|
||||||
#elif defined(WLED_USE_PLJAKOBS_PCB)
|
|
||||||
// PWM pins - to use with esp_rgbww_controller from patrickjahns/pljakobs (https://github.com/pljakobs/esp_rgbww_controller)
|
|
||||||
#define RPIN 12 //R pin for analog LED strip
|
|
||||||
#define GPIN 13 //G pin for analog LED strip
|
|
||||||
#define BPIN 14 //B pin for analog LED strip
|
|
||||||
#define WPIN 4 //W pin for analog LED strip
|
|
||||||
#define W2PIN 5 //W2 pin for analog LED strip
|
|
||||||
#undef IRPIN
|
|
||||||
#else
|
|
||||||
//Enable override of Pins by using the platformio_override.ini file
|
|
||||||
//PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller
|
|
||||||
#ifndef RPIN
|
|
||||||
#define RPIN 5 //R pin for analog LED strip
|
|
||||||
#endif
|
|
||||||
#ifndef GPIN
|
|
||||||
#define GPIN 12 //G pin for analog LED strip
|
|
||||||
#endif
|
|
||||||
#ifndef BPIN
|
|
||||||
#define BPIN 15 //B pin for analog LED strip
|
|
||||||
#endif
|
|
||||||
#ifndef WPIN
|
|
||||||
#define WPIN 13 //W pin for analog LED strip
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#undef RLYPIN
|
|
||||||
#define RLYPIN -1 //disable as pin 12 is used by analog LEDs
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//automatically uses the right driver method for each platform
|
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
|
||||||
#ifdef USE_APA102
|
|
||||||
#define PIXELMETHOD DotStarMethod
|
|
||||||
#elif defined(USE_WS2801)
|
|
||||||
#define PIXELMETHOD NeoWs2801Method
|
|
||||||
#elif defined(USE_LPD8806)
|
|
||||||
#define PIXELMETHOD Lpd8806Method
|
|
||||||
#elif defined(USE_TM1814)
|
|
||||||
#define PIXELMETHOD NeoTm1814Method
|
|
||||||
#elif defined(USE_P9813)
|
|
||||||
#define PIXELMETHOD P9813Method
|
|
||||||
#else
|
|
||||||
#define PIXELMETHOD NeoEsp32Rmt0Ws2812xMethod
|
|
||||||
#endif
|
|
||||||
#else //esp8266
|
|
||||||
//autoselect the right method depending on strip pin
|
|
||||||
#ifdef USE_APA102
|
|
||||||
#define PIXELMETHOD DotStarMethod
|
|
||||||
#elif defined(USE_WS2801)
|
|
||||||
#define PIXELMETHOD NeoWs2801Method
|
|
||||||
#elif defined(USE_LPD8806)
|
|
||||||
#define PIXELMETHOD Lpd8806Method
|
|
||||||
#elif defined(USE_TM1814)
|
|
||||||
#define PIXELMETHOD NeoTm1814Method
|
|
||||||
#elif defined(USE_P9813)
|
|
||||||
#define PIXELMETHOD P9813Method
|
|
||||||
#elif LEDPIN == 2
|
|
||||||
#define PIXELMETHOD NeoEsp8266Uart1Ws2813Method //if you get an error here, try to change to NeoEsp8266UartWs2813Method or update Neopixelbus
|
|
||||||
#elif LEDPIN == 3
|
|
||||||
#define PIXELMETHOD NeoEsp8266Dma800KbpsMethod
|
|
||||||
#else
|
|
||||||
#define PIXELMETHOD NeoEsp8266BitBang800KbpsMethod
|
|
||||||
#pragma message "Software BitBang will be used because of your selected LED pin. This may cause flicker. Use GPIO 2 or 3 for best results."
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
//you can now change the color order in the web settings
|
|
||||||
#ifdef USE_APA102
|
|
||||||
#define PIXELFEATURE3 DotStarBgrFeature
|
|
||||||
#define PIXELFEATURE4 DotStarLbgrFeature
|
|
||||||
#elif defined(USE_LPD8806)
|
|
||||||
#define PIXELFEATURE3 Lpd8806GrbFeature
|
|
||||||
#define PIXELFEATURE4 Lpd8806GrbFeature
|
|
||||||
#elif defined(USE_WS2801)
|
|
||||||
#define PIXELFEATURE3 NeoRbgFeature
|
|
||||||
#define PIXELFEATURE4 NeoRbgFeature
|
|
||||||
#elif defined(USE_TM1814)
|
|
||||||
#define PIXELFEATURE3 NeoWrgbTm1814Feature
|
|
||||||
#define PIXELFEATURE4 NeoWrgbTm1814Feature
|
|
||||||
#elif defined(USE_P9813)
|
|
||||||
#define PIXELFEATURE3 P9813BgrFeature
|
|
||||||
#define PIXELFEATURE4 NeoGrbwFeature
|
|
||||||
#else
|
|
||||||
#define PIXELFEATURE3 NeoGrbFeature
|
|
||||||
#define PIXELFEATURE4 NeoGrbwFeature
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include <NeoPixelBrightnessBus.h>
|
|
||||||
#include "const.h"
|
|
||||||
|
|
||||||
enum NeoPixelType
|
|
||||||
{
|
|
||||||
NeoPixelType_None = 0,
|
|
||||||
NeoPixelType_Grb = 1,
|
|
||||||
NeoPixelType_Grbw = 2,
|
|
||||||
NeoPixelType_End = 3
|
|
||||||
};
|
|
||||||
|
|
||||||
class NeoPixelWrapper
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
NeoPixelWrapper() :
|
|
||||||
// initialize each member to null
|
|
||||||
_pGrb(NULL),
|
|
||||||
_pGrbw(NULL),
|
|
||||||
_type(NeoPixelType_None)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
~NeoPixelWrapper()
|
|
||||||
{
|
|
||||||
cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Begin(NeoPixelType type, uint16_t countPixels)
|
|
||||||
{
|
|
||||||
cleanup();
|
|
||||||
_type = type;
|
|
||||||
|
|
||||||
switch (_type)
|
|
||||||
{
|
|
||||||
case NeoPixelType_Grb:
|
|
||||||
#if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) || defined(USE_P9813)
|
|
||||||
_pGrb = new NeoPixelBrightnessBus<PIXELFEATURE3,PIXELMETHOD>(countPixels, CLKPIN, DATAPIN);
|
|
||||||
#else
|
|
||||||
_pGrb = new NeoPixelBrightnessBus<PIXELFEATURE3,PIXELMETHOD>(countPixels, LEDPIN);
|
|
||||||
#endif
|
|
||||||
_pGrb->Begin();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NeoPixelType_Grbw:
|
|
||||||
#if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) || defined(USE_P9813)
|
|
||||||
_pGrbw = new NeoPixelBrightnessBus<PIXELFEATURE4,PIXELMETHOD>(countPixels, CLKPIN, DATAPIN);
|
|
||||||
#else
|
|
||||||
_pGrbw = new NeoPixelBrightnessBus<PIXELFEATURE4,PIXELMETHOD>(countPixels, LEDPIN);
|
|
||||||
#endif
|
|
||||||
_pGrbw->Begin();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef WLED_USE_ANALOG_LEDS
|
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
|
||||||
ledcSetup(0, 5000, 8);
|
|
||||||
ledcAttachPin(RPIN, 0);
|
|
||||||
ledcSetup(1, 5000, 8);
|
|
||||||
ledcAttachPin(GPIN, 1);
|
|
||||||
ledcSetup(2, 5000, 8);
|
|
||||||
ledcAttachPin(BPIN, 2);
|
|
||||||
if(_type == NeoPixelType_Grbw)
|
|
||||||
{
|
|
||||||
ledcSetup(3, 5000, 8);
|
|
||||||
ledcAttachPin(WPIN, 3);
|
|
||||||
#ifdef WLED_USE_5CH_LEDS
|
|
||||||
ledcSetup(4, 5000, 8);
|
|
||||||
ledcAttachPin(W2PIN, 4);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#else // ESP8266
|
|
||||||
//init PWM pins
|
|
||||||
pinMode(RPIN, OUTPUT);
|
|
||||||
pinMode(GPIN, OUTPUT);
|
|
||||||
pinMode(BPIN, OUTPUT);
|
|
||||||
if(_type == NeoPixelType_Grbw)
|
|
||||||
{
|
|
||||||
pinMode(WPIN, OUTPUT);
|
|
||||||
#ifdef WLED_USE_5CH_LEDS
|
|
||||||
pinMode(W2PIN, OUTPUT);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
analogWriteRange(255); //same range as one RGB channel
|
|
||||||
analogWriteFreq(880); //PWM frequency proven as good for LEDs
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef WLED_USE_ANALOG_LEDS
|
|
||||||
void SetRgbwPwm(uint8_t r, uint8_t g, uint8_t b, uint8_t w, uint8_t w2=0)
|
|
||||||
{
|
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
|
||||||
ledcWrite(0, r);
|
|
||||||
ledcWrite(1, g);
|
|
||||||
ledcWrite(2, b);
|
|
||||||
switch (_type) {
|
|
||||||
case NeoPixelType_Grb: break;
|
|
||||||
#ifdef WLED_USE_5CH_LEDS
|
|
||||||
case NeoPixelType_Grbw: ledcWrite(3, w); ledcWrite(4, w2); break;
|
|
||||||
#else
|
|
||||||
case NeoPixelType_Grbw: ledcWrite(3, w); break;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#else // ESP8266
|
|
||||||
analogWrite(RPIN, r);
|
|
||||||
analogWrite(GPIN, g);
|
|
||||||
analogWrite(BPIN, b);
|
|
||||||
switch (_type) {
|
|
||||||
case NeoPixelType_Grb: break;
|
|
||||||
#ifdef WLED_USE_5CH_LEDS
|
|
||||||
case NeoPixelType_Grbw: analogWrite(WPIN, w); analogWrite(W2PIN, w2); break;
|
|
||||||
#else
|
|
||||||
case NeoPixelType_Grbw: analogWrite(WPIN, w); break;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void Show()
|
|
||||||
{
|
|
||||||
switch (_type)
|
|
||||||
{
|
|
||||||
case NeoPixelType_Grb: _pGrb->Show(); break;
|
|
||||||
case NeoPixelType_Grbw: _pGrbw->Show(); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This will return true if enough time has passed since the last time Show() was called.
|
|
||||||
* This also means that calling Show() will not cause any undue waiting. If the method for
|
|
||||||
* the defined bus is hardware that sends asynchronously, then call CanShow() will let
|
|
||||||
* you know if it has finished sending the data from the last Show().
|
|
||||||
*/
|
|
||||||
bool CanShow()
|
|
||||||
{
|
|
||||||
switch (_type)
|
|
||||||
{
|
|
||||||
case NeoPixelType_Grb: return _pGrb->CanShow();
|
|
||||||
case NeoPixelType_Grbw: return _pGrbw->CanShow();
|
|
||||||
default: return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetPixelColor(uint16_t indexPixel, RgbwColor c)
|
|
||||||
{
|
|
||||||
RgbwColor col;
|
|
||||||
|
|
||||||
uint8_t co = _colorOrder;
|
|
||||||
#ifdef COLOR_ORDER_OVERRIDE
|
|
||||||
if (indexPixel >= COO_MIN && indexPixel < COO_MAX) co = COO_ORDER;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//reorder channels to selected order
|
|
||||||
switch (co)
|
|
||||||
{
|
|
||||||
case 0: col.G = c.G; col.R = c.R; col.B = c.B; break; //0 = GRB, default
|
|
||||||
case 1: col.G = c.R; col.R = c.G; col.B = c.B; break; //1 = RGB, common for WS2811
|
|
||||||
case 2: col.G = c.B; col.R = c.R; col.B = c.G; break; //2 = BRG
|
|
||||||
case 3: col.G = c.R; col.R = c.B; col.B = c.G; break; //3 = RBG
|
|
||||||
case 4: col.G = c.B; col.R = c.G; col.B = c.R; break; //4 = BGR
|
|
||||||
default: col.G = c.G; col.R = c.B; col.B = c.R; break; //5 = GBR
|
|
||||||
}
|
|
||||||
col.W = c.W;
|
|
||||||
|
|
||||||
switch (_type) {
|
|
||||||
case NeoPixelType_Grb: {
|
|
||||||
_pGrb->SetPixelColor(indexPixel, RgbColor(col.R,col.G,col.B));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NeoPixelType_Grbw: {
|
|
||||||
#if defined(USE_LPD8806) || defined(USE_WS2801)
|
|
||||||
_pGrbw->SetPixelColor(indexPixel, RgbColor(col.R,col.G,col.B));
|
|
||||||
#else
|
|
||||||
_pGrbw->SetPixelColor(indexPixel, col);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetBrightness(byte b)
|
|
||||||
{
|
|
||||||
switch (_type) {
|
|
||||||
case NeoPixelType_Grb: _pGrb->SetBrightness(b); break;
|
|
||||||
case NeoPixelType_Grbw:_pGrbw->SetBrightness(b); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetColorOrder(byte colorOrder) {
|
|
||||||
_colorOrder = colorOrder;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t GetColorOrder() {
|
|
||||||
return _colorOrder;
|
|
||||||
}
|
|
||||||
|
|
||||||
RgbwColor GetPixelColorRaw(uint16_t indexPixel) const
|
|
||||||
{
|
|
||||||
switch (_type) {
|
|
||||||
case NeoPixelType_Grb: return _pGrb->GetPixelColor(indexPixel); break;
|
|
||||||
case NeoPixelType_Grbw: return _pGrbw->GetPixelColor(indexPixel); break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: Due to feature differences, some support RGBW but the method name
|
|
||||||
// here needs to be unique, thus GetPixeColorRgbw
|
|
||||||
uint32_t GetPixelColorRgbw(uint16_t indexPixel) const
|
|
||||||
{
|
|
||||||
RgbwColor col(0,0,0,0);
|
|
||||||
switch (_type) {
|
|
||||||
case NeoPixelType_Grb: col = _pGrb->GetPixelColor(indexPixel); break;
|
|
||||||
case NeoPixelType_Grbw: col = _pGrbw->GetPixelColor(indexPixel); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t co = _colorOrder;
|
|
||||||
#ifdef COLOR_ORDER_OVERRIDE
|
|
||||||
if (indexPixel >= COO_MIN && indexPixel < COO_MAX) co = COO_ORDER;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (co)
|
|
||||||
{
|
|
||||||
// W G R B
|
|
||||||
case 0: return ((col.W << 24) | (col.G << 8) | (col.R << 16) | (col.B)); //0 = GRB, default
|
|
||||||
case 1: return ((col.W << 24) | (col.R << 8) | (col.G << 16) | (col.B)); //1 = RGB, common for WS2811
|
|
||||||
case 2: return ((col.W << 24) | (col.B << 8) | (col.R << 16) | (col.G)); //2 = BRG
|
|
||||||
case 3: return ((col.W << 24) | (col.B << 8) | (col.G << 16) | (col.R)); //3 = RBG
|
|
||||||
case 4: return ((col.W << 24) | (col.R << 8) | (col.B << 16) | (col.G)); //4 = BGR
|
|
||||||
case 5: return ((col.W << 24) | (col.G << 8) | (col.B << 16) | (col.R)); //5 = GBR
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* GetPixels(void)
|
|
||||||
{
|
|
||||||
switch (_type) {
|
|
||||||
case NeoPixelType_Grb: return _pGrb->Pixels(); break;
|
|
||||||
case NeoPixelType_Grbw: return _pGrbw->Pixels(); break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
NeoPixelType _type;
|
|
||||||
|
|
||||||
// have a member for every possible type
|
|
||||||
NeoPixelBrightnessBus<PIXELFEATURE3,PIXELMETHOD>* _pGrb;
|
|
||||||
NeoPixelBrightnessBus<PIXELFEATURE4,PIXELMETHOD>* _pGrbw;
|
|
||||||
|
|
||||||
byte _colorOrder = 0;
|
|
||||||
|
|
||||||
void cleanup()
|
|
||||||
{
|
|
||||||
switch (_type) {
|
|
||||||
case NeoPixelType_Grb: delete _pGrb ; _pGrb = NULL; break;
|
|
||||||
case NeoPixelType_Grbw: delete _pGrbw; _pGrbw = NULL; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
404
wled00/bus_manager.h
Normal file
404
wled00/bus_manager.h
Normal file
@ -0,0 +1,404 @@
|
|||||||
|
#ifndef BusManager_h
|
||||||
|
#define BusManager_h
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class for addressing various light types
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "const.h"
|
||||||
|
#include "pin_manager.h"
|
||||||
|
#include "bus_wrapper.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
//temporary struct for passing bus configuration to bus
|
||||||
|
struct BusConfig {
|
||||||
|
uint8_t type = TYPE_WS2812_RGB;
|
||||||
|
uint16_t count = 1;
|
||||||
|
uint16_t start = 0;
|
||||||
|
uint8_t colorOrder = COL_ORDER_GRB;
|
||||||
|
bool reversed = false;
|
||||||
|
uint8_t pins[5] = {LEDPIN, 255, 255, 255, 255};
|
||||||
|
BusConfig(uint8_t busType, uint8_t* ppins, uint16_t pstart, uint16_t len = 1, uint8_t pcolorOrder = COL_ORDER_GRB, bool rev = false) {
|
||||||
|
type = busType; count = len; start = pstart; colorOrder = pcolorOrder; reversed = rev;
|
||||||
|
uint8_t nPins = 1;
|
||||||
|
if (type > 47) nPins = 2;
|
||||||
|
else if (type > 41 && type < 46) nPins = NUM_PWM_PINS(type);
|
||||||
|
for (uint8_t i = 0; i < nPins; i++) pins[i] = ppins[i];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//parent class of BusDigital and BusPwm
|
||||||
|
class Bus {
|
||||||
|
public:
|
||||||
|
Bus(uint8_t type, uint16_t start) {
|
||||||
|
_type = type;
|
||||||
|
_start = start;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual void show() {}
|
||||||
|
virtual bool canShow() { return true; }
|
||||||
|
|
||||||
|
virtual void setPixelColor(uint16_t pix, uint32_t c) {};
|
||||||
|
|
||||||
|
virtual void setBrightness(uint8_t b) {};
|
||||||
|
|
||||||
|
virtual uint32_t getPixelColor(uint16_t pix) { return 0; };
|
||||||
|
|
||||||
|
virtual void cleanup() {};
|
||||||
|
|
||||||
|
virtual ~Bus() { //throw the bus under the bus
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual uint8_t getPins(uint8_t* pinArray) { return 0; }
|
||||||
|
|
||||||
|
uint16_t getStart() {
|
||||||
|
return _start;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setStart(uint16_t start) {
|
||||||
|
_start = start;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual uint16_t getLength() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setColorOrder() {}
|
||||||
|
|
||||||
|
virtual uint8_t getColorOrder() {
|
||||||
|
return COL_ORDER_RGB;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getType() {
|
||||||
|
return _type;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isOk() {
|
||||||
|
return _valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool reversed = false;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint8_t _type = TYPE_NONE;
|
||||||
|
uint8_t _bri = 255;
|
||||||
|
uint16_t _start = 0;
|
||||||
|
bool _valid = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class BusDigital : public Bus {
|
||||||
|
public:
|
||||||
|
BusDigital(BusConfig &bc, uint8_t nr) : Bus(bc.type, bc.start) {
|
||||||
|
if (!IS_DIGITAL(bc.type) || !bc.count) return;
|
||||||
|
_pins[0] = bc.pins[0];
|
||||||
|
if (!pinManager.allocatePin(_pins[0])) return;
|
||||||
|
if (IS_2PIN(bc.type)) {
|
||||||
|
_pins[1] = bc.pins[1];
|
||||||
|
if (!pinManager.allocatePin(_pins[1])) {
|
||||||
|
cleanup(); return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_len = bc.count;
|
||||||
|
reversed = bc.reversed;
|
||||||
|
_iType = PolyBus::getI(bc.type, _pins, nr);
|
||||||
|
if (_iType == I_NONE) return;
|
||||||
|
_busPtr = PolyBus::create(_iType, _pins, _len);
|
||||||
|
_valid = (_busPtr != nullptr);
|
||||||
|
_colorOrder = bc.colorOrder;
|
||||||
|
//Serial.printf("Successfully inited strip %u (len %u) with type %u and pins %u,%u (itype %u)\n",nr, len, type, pins[0],pins[1],_iType);
|
||||||
|
};
|
||||||
|
|
||||||
|
void show() {
|
||||||
|
PolyBus::show(_busPtr, _iType);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool canShow() {
|
||||||
|
return PolyBus::canShow(_busPtr, _iType);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBrightness(uint8_t b) {
|
||||||
|
//Fix for turning off onboard LED breaking bus
|
||||||
|
#ifdef LED_BUILTIN
|
||||||
|
if (_bri == 0 && b > 0) {
|
||||||
|
if (_pins[0] == LED_BUILTIN || _pins[1] == LED_BUILTIN) PolyBus::begin(_busPtr, _iType, _pins);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
_bri = b;
|
||||||
|
PolyBus::setBrightness(_busPtr, _iType, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPixelColor(uint16_t pix, uint32_t c) {
|
||||||
|
if (reversed) pix = _len - pix -1;
|
||||||
|
PolyBus::setPixelColor(_busPtr, _iType, pix, c, _colorOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t getPixelColor(uint16_t pix) {
|
||||||
|
if (reversed) pix = _len - pix -1;
|
||||||
|
return PolyBus::getPixelColor(_busPtr, _iType, pix, _colorOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getColorOrder() {
|
||||||
|
return _colorOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t getLength() {
|
||||||
|
return _len;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getPins(uint8_t* pinArray) {
|
||||||
|
uint8_t numPins = IS_2PIN(_type) ? 2 : 1;
|
||||||
|
for (uint8_t i = 0; i < numPins; i++) pinArray[i] = _pins[i];
|
||||||
|
return numPins;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setColorOrder(uint8_t colorOrder) {
|
||||||
|
if (colorOrder > 5) return;
|
||||||
|
_colorOrder = colorOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reinit() {
|
||||||
|
PolyBus::begin(_busPtr, _iType, _pins);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanup() {
|
||||||
|
//Serial.println("Digital Cleanup");
|
||||||
|
PolyBus::cleanup(_busPtr, _iType);
|
||||||
|
_iType = I_NONE;
|
||||||
|
_valid = false;
|
||||||
|
_busPtr = nullptr;
|
||||||
|
pinManager.deallocatePin(_pins[0]);
|
||||||
|
pinManager.deallocatePin(_pins[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
~BusDigital() {
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t _colorOrder = COL_ORDER_GRB;
|
||||||
|
uint8_t _pins[2] = {255, 255};
|
||||||
|
uint8_t _iType = I_NONE;
|
||||||
|
uint16_t _len = 0;
|
||||||
|
void * _busPtr = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class BusPwm : public Bus {
|
||||||
|
public:
|
||||||
|
BusPwm(BusConfig &bc) : Bus(bc.type, bc.start) {
|
||||||
|
if (!IS_PWM(bc.type)) return;
|
||||||
|
uint8_t numPins = NUM_PWM_PINS(bc.type);
|
||||||
|
|
||||||
|
#ifdef ESP8266
|
||||||
|
analogWriteRange(255); //same range as one RGB channel
|
||||||
|
analogWriteFreq(WLED_PWM_FREQ);
|
||||||
|
#else
|
||||||
|
_ledcStart = pinManager.allocateLedc(numPins);
|
||||||
|
if (_ledcStart == 255) { //no more free LEDC channels
|
||||||
|
deallocatePins(); return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < numPins; i++) {
|
||||||
|
_pins[i] = bc.pins[i];
|
||||||
|
if (!pinManager.allocatePin(_pins[i])) {
|
||||||
|
deallocatePins(); return;
|
||||||
|
}
|
||||||
|
#ifdef ESP8266
|
||||||
|
pinMode(_pins[i], OUTPUT);
|
||||||
|
#else
|
||||||
|
ledcSetup(_ledcStart + i, WLED_PWM_FREQ, 8);
|
||||||
|
ledcAttachPin(_pins[i], _ledcStart + i);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
_valid = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
void setPixelColor(uint16_t pix, uint32_t c) {
|
||||||
|
if (pix != 0 || !_valid) return; //only react to first pixel
|
||||||
|
uint8_t r = c >> 16;
|
||||||
|
uint8_t g = c >> 8;
|
||||||
|
uint8_t b = c ;
|
||||||
|
uint8_t w = c >> 24;
|
||||||
|
|
||||||
|
switch (_type) {
|
||||||
|
case TYPE_ANALOG_1CH: //one channel (white), use highest RGBW value
|
||||||
|
_data[0] = max(r, max(g, max(b, w))); break;
|
||||||
|
|
||||||
|
case TYPE_ANALOG_2CH: //warm white + cold white, we'll need some nice handling here, for now just R+G channels
|
||||||
|
case TYPE_ANALOG_3CH: //standard dumb RGB
|
||||||
|
case TYPE_ANALOG_4CH: //RGBW
|
||||||
|
case TYPE_ANALOG_5CH: //we'll want the white handling from 2CH here + RGB
|
||||||
|
_data[0] = r; _data[1] = g; _data[2] = b; _data[3] = w; _data[4] = 0; break;
|
||||||
|
|
||||||
|
default: return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//does no index check
|
||||||
|
uint32_t getPixelColor(uint16_t pix) {
|
||||||
|
return ((_data[3] << 24) | (_data[0] << 16) | (_data[1] << 8) | (_data[2]));
|
||||||
|
}
|
||||||
|
|
||||||
|
void show() {
|
||||||
|
uint8_t numPins = NUM_PWM_PINS(_type);
|
||||||
|
for (uint8_t i = 0; i < numPins; i++) {
|
||||||
|
uint8_t scaled = (_data[i] * _bri) / 255;
|
||||||
|
#ifdef ESP8266
|
||||||
|
analogWrite(_pins[i], scaled);
|
||||||
|
#else
|
||||||
|
ledcWrite(_ledcStart + i, scaled);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBrightness(uint8_t b) {
|
||||||
|
_bri = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getPins(uint8_t* pinArray) {
|
||||||
|
uint8_t numPins = NUM_PWM_PINS(_type);
|
||||||
|
for (uint8_t i = 0; i < numPins; i++) pinArray[i] = _pins[i];
|
||||||
|
return numPins;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanup() {
|
||||||
|
deallocatePins();
|
||||||
|
}
|
||||||
|
|
||||||
|
~BusPwm() {
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t _pins[5] = {255, 255, 255, 255, 255};
|
||||||
|
uint8_t _data[5] = {255, 255, 255, 255, 255};
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
uint8_t _ledcStart = 255;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void deallocatePins() {
|
||||||
|
uint8_t numPins = NUM_PWM_PINS(_type);
|
||||||
|
for (uint8_t i = 0; i < numPins; i++) {
|
||||||
|
if (!pinManager.isPinOk(_pins[i])) continue;
|
||||||
|
#ifdef ESP8266
|
||||||
|
digitalWrite(_pins[i], LOW); //turn off PWM interrupt
|
||||||
|
#else
|
||||||
|
if (_ledcStart < 16) ledcDetachPin(_pins[i]);
|
||||||
|
#endif
|
||||||
|
pinManager.deallocatePin(_pins[i]);
|
||||||
|
}
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
pinManager.deallocateLedc(_ledcStart, numPins);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class BusManager {
|
||||||
|
public:
|
||||||
|
BusManager() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//utility to get the approx. memory usage of a given BusConfig
|
||||||
|
uint32_t memUsage(BusConfig &bc) {
|
||||||
|
uint8_t type = bc.type;
|
||||||
|
uint16_t len = bc.count;
|
||||||
|
if (type < 32) {
|
||||||
|
#ifdef ESP8266
|
||||||
|
if (bc.pins[0] == 3) { //8266 DMA uses 5x the mem
|
||||||
|
if (type > 29) return len*20; //RGBW
|
||||||
|
return len*15;
|
||||||
|
}
|
||||||
|
if (type > 29) return len*4; //RGBW
|
||||||
|
return len*3;
|
||||||
|
#else //ESP32 RMT uses double buffer?
|
||||||
|
if (type > 29) return len*8; //RGBW
|
||||||
|
return len*6;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type > 31 && type < 48) return 5;
|
||||||
|
if (type == 44 || type == 45) return len*4; //RGBW
|
||||||
|
return len*3;
|
||||||
|
}
|
||||||
|
|
||||||
|
int add(BusConfig &bc) {
|
||||||
|
if (numBusses >= WLED_MAX_BUSSES) return -1;
|
||||||
|
if (IS_DIGITAL(bc.type)) {
|
||||||
|
busses[numBusses] = new BusDigital(bc, numBusses);
|
||||||
|
} else {
|
||||||
|
busses[numBusses] = new BusPwm(bc);
|
||||||
|
}
|
||||||
|
numBusses++;
|
||||||
|
return numBusses -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//do not call this method from system context (network callback)
|
||||||
|
void removeAll() {
|
||||||
|
//Serial.println("Removing all.");
|
||||||
|
//prevents crashes due to deleting busses while in use.
|
||||||
|
while (!canAllShow()) yield();
|
||||||
|
for (uint8_t i = 0; i < numBusses; i++) delete busses[i];
|
||||||
|
numBusses = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void show() {
|
||||||
|
for (uint8_t i = 0; i < numBusses; i++) {
|
||||||
|
busses[i]->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPixelColor(uint16_t pix, uint32_t c) {
|
||||||
|
for (uint8_t i = 0; i < numBusses; i++) {
|
||||||
|
Bus* b = busses[i];
|
||||||
|
uint16_t bstart = b->getStart();
|
||||||
|
if (pix < bstart || pix >= bstart + b->getLength()) continue;
|
||||||
|
busses[i]->setPixelColor(pix - bstart, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBrightness(uint8_t b) {
|
||||||
|
for (uint8_t i = 0; i < numBusses; i++) {
|
||||||
|
busses[i]->setBrightness(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t getPixelColor(uint16_t pix) {
|
||||||
|
for (uint8_t i = 0; i < numBusses; i++) {
|
||||||
|
Bus* b = busses[i];
|
||||||
|
uint16_t bstart = b->getStart();
|
||||||
|
if (pix < bstart || pix >= bstart + b->getLength()) continue;
|
||||||
|
return b->getPixelColor(pix - bstart);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool canAllShow() {
|
||||||
|
for (uint8_t i = 0; i < numBusses; i++) {
|
||||||
|
if (!busses[i]->canShow()) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bus* getBus(uint8_t busNr) {
|
||||||
|
if (busNr >= numBusses) return nullptr;
|
||||||
|
return busses[busNr];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getNumBusses() {
|
||||||
|
return numBusses;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isRgbw(uint8_t type) {
|
||||||
|
if (type == TYPE_SK6812_RGBW || type == TYPE_TM1814) return true;
|
||||||
|
if (type > TYPE_ONOFF && type <= TYPE_ANALOG_5CH && type != TYPE_ANALOG_3CH) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t numBusses = 0;
|
||||||
|
Bus* busses[WLED_MAX_BUSSES];
|
||||||
|
};
|
||||||
|
#endif
|
882
wled00/bus_wrapper.h
Normal file
882
wled00/bus_wrapper.h
Normal file
@ -0,0 +1,882 @@
|
|||||||
|
#ifndef BusWrapper_h
|
||||||
|
#define BusWrapper_h
|
||||||
|
|
||||||
|
#include "NeoPixelBrightnessBus.h"
|
||||||
|
|
||||||
|
//Hardware SPI Pins
|
||||||
|
#define P_8266_HS_MOSI 13
|
||||||
|
#define P_8266_HS_CLK 14
|
||||||
|
#define P_32_HS_MOSI 13
|
||||||
|
#define P_32_HS_CLK 14
|
||||||
|
#define P_32_VS_MOSI 23
|
||||||
|
#define P_32_VS_CLK 18
|
||||||
|
|
||||||
|
//The dirty list of possible bus types. Quite a lot...
|
||||||
|
#define I_NONE 0
|
||||||
|
//ESP8266 RGB
|
||||||
|
#define I_8266_U0_NEO_3 1
|
||||||
|
#define I_8266_U1_NEO_3 2
|
||||||
|
#define I_8266_DM_NEO_3 3
|
||||||
|
#define I_8266_BB_NEO_3 4
|
||||||
|
//RGBW
|
||||||
|
#define I_8266_U0_NEO_4 5
|
||||||
|
#define I_8266_U1_NEO_4 6
|
||||||
|
#define I_8266_DM_NEO_4 7
|
||||||
|
#define I_8266_BB_NEO_4 8
|
||||||
|
//400Kbps
|
||||||
|
#define I_8266_U0_400_3 9
|
||||||
|
#define I_8266_U1_400_3 10
|
||||||
|
#define I_8266_DM_400_3 11
|
||||||
|
#define I_8266_BB_400_3 12
|
||||||
|
//TM1418 (RGBW)
|
||||||
|
#define I_8266_U0_TM1_4 13
|
||||||
|
#define I_8266_U1_TM1_4 14
|
||||||
|
#define I_8266_DM_TM1_4 15
|
||||||
|
#define I_8266_BB_TM1_4 16
|
||||||
|
|
||||||
|
/*** ESP32 Neopixel methods ***/
|
||||||
|
//RGB
|
||||||
|
#define I_32_R0_NEO_3 17
|
||||||
|
#define I_32_R1_NEO_3 18
|
||||||
|
#define I_32_R2_NEO_3 19
|
||||||
|
#define I_32_R3_NEO_3 20
|
||||||
|
#define I_32_R4_NEO_3 21
|
||||||
|
#define I_32_R5_NEO_3 22
|
||||||
|
#define I_32_R6_NEO_3 23
|
||||||
|
#define I_32_R7_NEO_3 24
|
||||||
|
#define I_32_I0_NEO_3 25
|
||||||
|
#define I_32_I1_NEO_3 26
|
||||||
|
//RGBW
|
||||||
|
#define I_32_R0_NEO_4 27
|
||||||
|
#define I_32_R1_NEO_4 28
|
||||||
|
#define I_32_R2_NEO_4 29
|
||||||
|
#define I_32_R3_NEO_4 30
|
||||||
|
#define I_32_R4_NEO_4 31
|
||||||
|
#define I_32_R5_NEO_4 32
|
||||||
|
#define I_32_R6_NEO_4 33
|
||||||
|
#define I_32_R7_NEO_4 34
|
||||||
|
#define I_32_I0_NEO_4 35
|
||||||
|
#define I_32_I1_NEO_4 36
|
||||||
|
//400Kbps
|
||||||
|
#define I_32_R0_400_3 37
|
||||||
|
#define I_32_R1_400_3 38
|
||||||
|
#define I_32_R2_400_3 39
|
||||||
|
#define I_32_R3_400_3 40
|
||||||
|
#define I_32_R4_400_3 41
|
||||||
|
#define I_32_R5_400_3 42
|
||||||
|
#define I_32_R6_400_3 43
|
||||||
|
#define I_32_R7_400_3 44
|
||||||
|
#define I_32_I0_400_3 45
|
||||||
|
#define I_32_I1_400_3 46
|
||||||
|
//TM1418 (RGBW)
|
||||||
|
#define I_32_R0_TM1_4 47
|
||||||
|
#define I_32_R1_TM1_4 48
|
||||||
|
#define I_32_R2_TM1_4 49
|
||||||
|
#define I_32_R3_TM1_4 50
|
||||||
|
#define I_32_R4_TM1_4 51
|
||||||
|
#define I_32_R5_TM1_4 52
|
||||||
|
#define I_32_R6_TM1_4 53
|
||||||
|
#define I_32_R7_TM1_4 54
|
||||||
|
#define I_32_I0_TM1_4 55
|
||||||
|
#define I_32_I1_TM1_4 56
|
||||||
|
//Bit Bang theoratically possible, but very undesirable and not needed (no pin restrictions on RMT and I2S)
|
||||||
|
|
||||||
|
//APA102
|
||||||
|
#define I_HS_DOT_3 57 //hardware SPI
|
||||||
|
#define I_SS_DOT_3 58 //soft SPI
|
||||||
|
|
||||||
|
//LPD8806
|
||||||
|
#define I_HS_LPD_3 59
|
||||||
|
#define I_SS_LPD_3 60
|
||||||
|
|
||||||
|
//WS2801
|
||||||
|
#define I_HS_WS1_3 61
|
||||||
|
#define I_SS_WS1_3 62
|
||||||
|
|
||||||
|
//P9813
|
||||||
|
#define I_HS_P98_3 63
|
||||||
|
#define I_SS_P98_3 64
|
||||||
|
|
||||||
|
|
||||||
|
/*** ESP8266 Neopixel methods ***/
|
||||||
|
#ifdef ESP8266
|
||||||
|
//RGB
|
||||||
|
#define B_8266_U0_NEO_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp8266Uart0Ws2813Method> //3 chan, esp8266, gpio1
|
||||||
|
#define B_8266_U1_NEO_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp8266Uart1Ws2813Method> //3 chan, esp8266, gpio2
|
||||||
|
#define B_8266_DM_NEO_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp8266Dma800KbpsMethod> //3 chan, esp8266, gpio3
|
||||||
|
#define B_8266_BB_NEO_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp8266BitBang800KbpsMethod> //3 chan, esp8266, bb (any pin but 16)
|
||||||
|
//RGBW
|
||||||
|
#define B_8266_U0_NEO_4 NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp8266Uart0Ws2813Method> //4 chan, esp8266, gpio1
|
||||||
|
#define B_8266_U1_NEO_4 NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp8266Uart1Ws2813Method> //4 chan, esp8266, gpio2
|
||||||
|
#define B_8266_DM_NEO_4 NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp8266Dma800KbpsMethod> //4 chan, esp8266, gpio3
|
||||||
|
#define B_8266_BB_NEO_4 NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp8266BitBang800KbpsMethod> //4 chan, esp8266, bb (any pin)
|
||||||
|
//400Kbps
|
||||||
|
#define B_8266_U0_400_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp8266Uart0400KbpsMethod> //3 chan, esp8266, gpio1
|
||||||
|
#define B_8266_U1_400_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp8266Uart1400KbpsMethod> //3 chan, esp8266, gpio2
|
||||||
|
#define B_8266_DM_400_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp8266Dma400KbpsMethod> //3 chan, esp8266, gpio3
|
||||||
|
#define B_8266_BB_400_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp8266BitBang400KbpsMethod> //3 chan, esp8266, bb (any pin)
|
||||||
|
//TM1418 (RGBW)
|
||||||
|
#define B_8266_U0_TM1_4 NeoPixelBrightnessBus<NeoWrgbTm1814Feature, NeoEsp8266Uart0Tm1814Method>
|
||||||
|
#define B_8266_U1_TM1_4 NeoPixelBrightnessBus<NeoWrgbTm1814Feature, NeoEsp8266Uart1Tm1814Method>
|
||||||
|
#define B_8266_DM_TM1_4 NeoPixelBrightnessBus<NeoWrgbTm1814Feature, NeoEsp8266DmaTm1814Method>
|
||||||
|
#define B_8266_BB_TM1_4 NeoPixelBrightnessBus<NeoWrgbTm1814Feature, NeoEsp8266BitBangTm1814Method>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*** ESP32 Neopixel methods ***/
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
//RGB
|
||||||
|
#define B_32_R0_NEO_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp32Rmt0Ws2812xMethod>
|
||||||
|
#define B_32_R1_NEO_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp32Rmt1Ws2812xMethod>
|
||||||
|
#define B_32_R2_NEO_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp32Rmt2Ws2812xMethod>
|
||||||
|
#define B_32_R3_NEO_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp32Rmt3Ws2812xMethod>
|
||||||
|
#define B_32_R4_NEO_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp32Rmt4Ws2812xMethod>
|
||||||
|
#define B_32_R5_NEO_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp32Rmt5Ws2812xMethod>
|
||||||
|
#define B_32_R6_NEO_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp32Rmt6Ws2812xMethod>
|
||||||
|
#define B_32_R7_NEO_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp32Rmt7Ws2812xMethod>
|
||||||
|
#define B_32_I0_NEO_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp32I2s0800KbpsMethod>
|
||||||
|
#define B_32_I1_NEO_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp32I2s1800KbpsMethod>
|
||||||
|
//RGBW
|
||||||
|
#define B_32_R0_NEO_4 NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt0Ws2812xMethod>
|
||||||
|
#define B_32_R1_NEO_4 NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt1Ws2812xMethod>
|
||||||
|
#define B_32_R2_NEO_4 NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt2Ws2812xMethod>
|
||||||
|
#define B_32_R3_NEO_4 NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt3Ws2812xMethod>
|
||||||
|
#define B_32_R4_NEO_4 NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt4Ws2812xMethod>
|
||||||
|
#define B_32_R5_NEO_4 NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt5Ws2812xMethod>
|
||||||
|
#define B_32_R6_NEO_4 NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt6Ws2812xMethod>
|
||||||
|
#define B_32_R7_NEO_4 NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt7Ws2812xMethod>
|
||||||
|
#define B_32_I0_NEO_4 NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32I2s0800KbpsMethod>
|
||||||
|
#define B_32_I1_NEO_4 NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32I2s1800KbpsMethod>
|
||||||
|
//400Kbps
|
||||||
|
#define B_32_R0_400_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp32Rmt0400KbpsMethod>
|
||||||
|
#define B_32_R1_400_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp32Rmt1400KbpsMethod>
|
||||||
|
#define B_32_R2_400_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp32Rmt2400KbpsMethod>
|
||||||
|
#define B_32_R3_400_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp32Rmt3400KbpsMethod>
|
||||||
|
#define B_32_R4_400_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp32Rmt4400KbpsMethod>
|
||||||
|
#define B_32_R5_400_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp32Rmt5400KbpsMethod>
|
||||||
|
#define B_32_R6_400_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp32Rmt6400KbpsMethod>
|
||||||
|
#define B_32_R7_400_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp32Rmt7400KbpsMethod>
|
||||||
|
#define B_32_I0_400_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp32I2s0400KbpsMethod>
|
||||||
|
#define B_32_I1_400_3 NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp32I2s1400KbpsMethod>
|
||||||
|
//TM1418 (RGBW)
|
||||||
|
#define B_32_R0_TM1_4 NeoPixelBrightnessBus<NeoWrgbTm1814Feature, NeoEsp32Rmt0Tm1814Method>
|
||||||
|
#define B_32_R1_TM1_4 NeoPixelBrightnessBus<NeoWrgbTm1814Feature, NeoEsp32Rmt1Tm1814Method>
|
||||||
|
#define B_32_R2_TM1_4 NeoPixelBrightnessBus<NeoWrgbTm1814Feature, NeoEsp32Rmt2Tm1814Method>
|
||||||
|
#define B_32_R3_TM1_4 NeoPixelBrightnessBus<NeoWrgbTm1814Feature, NeoEsp32Rmt3Tm1814Method>
|
||||||
|
#define B_32_R4_TM1_4 NeoPixelBrightnessBus<NeoWrgbTm1814Feature, NeoEsp32Rmt4Tm1814Method>
|
||||||
|
#define B_32_R5_TM1_4 NeoPixelBrightnessBus<NeoWrgbTm1814Feature, NeoEsp32Rmt5Tm1814Method>
|
||||||
|
#define B_32_R6_TM1_4 NeoPixelBrightnessBus<NeoWrgbTm1814Feature, NeoEsp32Rmt6Tm1814Method>
|
||||||
|
#define B_32_R7_TM1_4 NeoPixelBrightnessBus<NeoWrgbTm1814Feature, NeoEsp32Rmt7Tm1814Method>
|
||||||
|
#define B_32_I0_TM1_4 NeoPixelBrightnessBus<NeoWrgbTm1814Feature, NeoEsp32I2s0Tm1814Method>
|
||||||
|
#define B_32_I1_TM1_4 NeoPixelBrightnessBus<NeoWrgbTm1814Feature, NeoEsp32I2s1Tm1814Method>
|
||||||
|
//Bit Bang theoratically possible, but very undesirable and not needed (no pin restrictions on RMT and I2S)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//APA102
|
||||||
|
#define B_HS_DOT_3 NeoPixelBrightnessBus<DotStarBgrFeature, DotStarSpiMethod> //hardware SPI
|
||||||
|
#define B_SS_DOT_3 NeoPixelBrightnessBus<DotStarBgrFeature, DotStarMethod> //soft SPI
|
||||||
|
|
||||||
|
//LPD8806
|
||||||
|
#define B_HS_LPD_3 NeoPixelBrightnessBus<Lpd8806GrbFeature, Lpd8806SpiMethod>
|
||||||
|
#define B_SS_LPD_3 NeoPixelBrightnessBus<Lpd8806GrbFeature, Lpd8806Method>
|
||||||
|
|
||||||
|
//WS2801
|
||||||
|
#define B_HS_WS1_3 NeoPixelBrightnessBus<NeoRbgFeature, NeoWs2801SpiMethod>
|
||||||
|
#define B_SS_WS1_3 NeoPixelBrightnessBus<NeoRbgFeature, NeoWs2801Method>
|
||||||
|
|
||||||
|
//P9813
|
||||||
|
#define B_HS_P98_3 NeoPixelBrightnessBus<P9813BgrFeature, P9813SpiMethod>
|
||||||
|
#define B_SS_P98_3 NeoPixelBrightnessBus<P9813BgrFeature, P9813Method>
|
||||||
|
|
||||||
|
//handles pointer type conversion for all possible bus types
|
||||||
|
class PolyBus {
|
||||||
|
public:
|
||||||
|
static void begin(void* busPtr, uint8_t busType, uint8_t* pins) {
|
||||||
|
switch (busType) {
|
||||||
|
case I_NONE: break;
|
||||||
|
#ifdef ESP8266
|
||||||
|
case I_8266_U0_NEO_3: (static_cast<B_8266_U0_NEO_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_U1_NEO_3: (static_cast<B_8266_U1_NEO_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_DM_NEO_3: (static_cast<B_8266_DM_NEO_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_BB_NEO_3: (static_cast<B_8266_BB_NEO_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_U0_NEO_4: (static_cast<B_8266_U0_NEO_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_U1_NEO_4: (static_cast<B_8266_U1_NEO_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_DM_NEO_4: (static_cast<B_8266_DM_NEO_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_BB_NEO_4: (static_cast<B_8266_BB_NEO_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_U0_400_3: (static_cast<B_8266_U0_400_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_U1_400_3: (static_cast<B_8266_U1_400_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_DM_400_3: (static_cast<B_8266_DM_400_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_BB_400_3: (static_cast<B_8266_BB_400_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_U0_TM1_4: (static_cast<B_8266_U0_TM1_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_U1_TM1_4: (static_cast<B_8266_U1_TM1_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_DM_TM1_4: (static_cast<B_8266_DM_TM1_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_BB_TM1_4: (static_cast<B_8266_BB_TM1_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_HS_DOT_3: (static_cast<B_HS_DOT_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_HS_LPD_3: (static_cast<B_HS_LPD_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_HS_WS1_3: (static_cast<B_HS_WS1_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_HS_P98_3: (static_cast<B_HS_P98_3*>(busPtr))->Begin(); break;
|
||||||
|
#endif
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
case I_32_R0_NEO_3: (static_cast<B_32_R0_NEO_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R1_NEO_3: (static_cast<B_32_R1_NEO_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R2_NEO_3: (static_cast<B_32_R2_NEO_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R3_NEO_3: (static_cast<B_32_R3_NEO_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R4_NEO_3: (static_cast<B_32_R4_NEO_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R5_NEO_3: (static_cast<B_32_R5_NEO_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R6_NEO_3: (static_cast<B_32_R6_NEO_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R7_NEO_3: (static_cast<B_32_R7_NEO_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_I0_NEO_3: (static_cast<B_32_I0_NEO_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_I1_NEO_3: (static_cast<B_32_I1_NEO_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R0_NEO_4: (static_cast<B_32_R0_NEO_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R1_NEO_4: (static_cast<B_32_R1_NEO_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R2_NEO_4: (static_cast<B_32_R2_NEO_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R3_NEO_4: (static_cast<B_32_R3_NEO_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R4_NEO_4: (static_cast<B_32_R4_NEO_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R5_NEO_4: (static_cast<B_32_R5_NEO_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R6_NEO_4: (static_cast<B_32_R6_NEO_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R7_NEO_4: (static_cast<B_32_R7_NEO_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_I0_NEO_4: (static_cast<B_32_I0_NEO_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_I1_NEO_4: (static_cast<B_32_I1_NEO_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R0_400_3: (static_cast<B_32_R0_400_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R1_400_3: (static_cast<B_32_R1_400_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R2_400_3: (static_cast<B_32_R2_400_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R3_400_3: (static_cast<B_32_R3_400_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R4_400_3: (static_cast<B_32_R4_400_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R5_400_3: (static_cast<B_32_R5_400_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R6_400_3: (static_cast<B_32_R6_400_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R7_400_3: (static_cast<B_32_R7_400_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_I0_400_3: (static_cast<B_32_I0_400_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_I1_400_3: (static_cast<B_32_I1_400_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R0_TM1_4: (static_cast<B_32_R0_TM1_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R1_TM1_4: (static_cast<B_32_R1_TM1_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R2_TM1_4: (static_cast<B_32_R2_TM1_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R3_TM1_4: (static_cast<B_32_R3_TM1_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R4_TM1_4: (static_cast<B_32_R4_TM1_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R5_TM1_4: (static_cast<B_32_R5_TM1_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R6_TM1_4: (static_cast<B_32_R6_TM1_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_R7_TM1_4: (static_cast<B_32_R7_TM1_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_I0_TM1_4: (static_cast<B_32_I0_TM1_4*>(busPtr))->Begin(); break;
|
||||||
|
case I_32_I1_TM1_4: (static_cast<B_32_I1_TM1_4*>(busPtr))->Begin(); break;
|
||||||
|
// ESP32 can (and should, to avoid inadvertantly driving the chip select signal) specify the pins used for SPI, but only in begin()
|
||||||
|
case I_HS_DOT_3: (static_cast<B_HS_DOT_3*>(busPtr))->Begin(pins[1], -1, pins[0], -1); break;
|
||||||
|
case I_HS_LPD_3: (static_cast<B_HS_LPD_3*>(busPtr))->Begin(pins[1], -1, pins[0], -1); break;
|
||||||
|
case I_HS_WS1_3: (static_cast<B_HS_WS1_3*>(busPtr))->Begin(pins[1], -1, pins[0], -1); break;
|
||||||
|
case I_HS_P98_3: (static_cast<B_HS_P98_3*>(busPtr))->Begin(pins[1], -1, pins[0], -1); break;
|
||||||
|
#endif
|
||||||
|
case I_SS_DOT_3: (static_cast<B_SS_DOT_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_SS_LPD_3: (static_cast<B_SS_LPD_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_SS_WS1_3: (static_cast<B_SS_WS1_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_SS_P98_3: (static_cast<B_SS_P98_3*>(busPtr))->Begin(); break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static void* create(uint8_t busType, uint8_t* pins, uint16_t len) {
|
||||||
|
void* busPtr = nullptr;
|
||||||
|
switch (busType) {
|
||||||
|
case I_NONE: break;
|
||||||
|
#ifdef ESP8266
|
||||||
|
case I_8266_U0_NEO_3: busPtr = new B_8266_U0_NEO_3(len, pins[0]); break;
|
||||||
|
case I_8266_U1_NEO_3: busPtr = new B_8266_U1_NEO_3(len, pins[0]); break;
|
||||||
|
case I_8266_DM_NEO_3: busPtr = new B_8266_DM_NEO_3(len, pins[0]); break;
|
||||||
|
case I_8266_BB_NEO_3: busPtr = new B_8266_BB_NEO_3(len, pins[0]); break;
|
||||||
|
case I_8266_U0_NEO_4: busPtr = new B_8266_U0_NEO_4(len, pins[0]); break;
|
||||||
|
case I_8266_U1_NEO_4: busPtr = new B_8266_U1_NEO_4(len, pins[0]); break;
|
||||||
|
case I_8266_DM_NEO_4: busPtr = new B_8266_DM_NEO_4(len, pins[0]); break;
|
||||||
|
case I_8266_BB_NEO_4: busPtr = new B_8266_BB_NEO_4(len, pins[0]); break;
|
||||||
|
case I_8266_U0_400_3: busPtr = new B_8266_U0_400_3(len, pins[0]); break;
|
||||||
|
case I_8266_U1_400_3: busPtr = new B_8266_U1_400_3(len, pins[0]); break;
|
||||||
|
case I_8266_DM_400_3: busPtr = new B_8266_DM_400_3(len, pins[0]); break;
|
||||||
|
case I_8266_BB_400_3: busPtr = new B_8266_BB_400_3(len, pins[0]); break;
|
||||||
|
case I_8266_U0_TM1_4: busPtr = new B_8266_U0_TM1_4(len, pins[0]); break;
|
||||||
|
case I_8266_U1_TM1_4: busPtr = new B_8266_U1_TM1_4(len, pins[0]); break;
|
||||||
|
case I_8266_DM_TM1_4: busPtr = new B_8266_DM_TM1_4(len, pins[0]); break;
|
||||||
|
case I_8266_BB_TM1_4: busPtr = new B_8266_BB_TM1_4(len, pins[0]); break;
|
||||||
|
#endif
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
case I_32_R0_NEO_3: busPtr = new B_32_R0_NEO_3(len, pins[0]); break;
|
||||||
|
case I_32_R1_NEO_3: busPtr = new B_32_R1_NEO_3(len, pins[0]); break;
|
||||||
|
case I_32_R2_NEO_3: busPtr = new B_32_R2_NEO_3(len, pins[0]); break;
|
||||||
|
case I_32_R3_NEO_3: busPtr = new B_32_R3_NEO_3(len, pins[0]); break;
|
||||||
|
case I_32_R4_NEO_3: busPtr = new B_32_R4_NEO_3(len, pins[0]); break;
|
||||||
|
case I_32_R5_NEO_3: busPtr = new B_32_R5_NEO_3(len, pins[0]); break;
|
||||||
|
case I_32_R6_NEO_3: busPtr = new B_32_R6_NEO_3(len, pins[0]); break;
|
||||||
|
case I_32_R7_NEO_3: busPtr = new B_32_R7_NEO_3(len, pins[0]); break;
|
||||||
|
case I_32_I0_NEO_3: busPtr = new B_32_I0_NEO_3(len, pins[0]); break;
|
||||||
|
case I_32_I1_NEO_3: busPtr = new B_32_I1_NEO_3(len, pins[0]); break;
|
||||||
|
case I_32_R0_NEO_4: busPtr = new B_32_R0_NEO_4(len, pins[0]); break;
|
||||||
|
case I_32_R1_NEO_4: busPtr = new B_32_R1_NEO_4(len, pins[0]); break;
|
||||||
|
case I_32_R2_NEO_4: busPtr = new B_32_R2_NEO_4(len, pins[0]); break;
|
||||||
|
case I_32_R3_NEO_4: busPtr = new B_32_R3_NEO_4(len, pins[0]); break;
|
||||||
|
case I_32_R4_NEO_4: busPtr = new B_32_R4_NEO_4(len, pins[0]); break;
|
||||||
|
case I_32_R5_NEO_4: busPtr = new B_32_R5_NEO_4(len, pins[0]); break;
|
||||||
|
case I_32_R6_NEO_4: busPtr = new B_32_R6_NEO_4(len, pins[0]); break;
|
||||||
|
case I_32_R7_NEO_4: busPtr = new B_32_R7_NEO_4(len, pins[0]); break;
|
||||||
|
case I_32_I0_NEO_4: busPtr = new B_32_I0_NEO_4(len, pins[0]); break;
|
||||||
|
case I_32_I1_NEO_4: busPtr = new B_32_I1_NEO_4(len, pins[0]); break;
|
||||||
|
case I_32_R0_400_3: busPtr = new B_32_R0_400_3(len, pins[0]); break;
|
||||||
|
case I_32_R1_400_3: busPtr = new B_32_R1_400_3(len, pins[0]); break;
|
||||||
|
case I_32_R2_400_3: busPtr = new B_32_R2_400_3(len, pins[0]); break;
|
||||||
|
case I_32_R3_400_3: busPtr = new B_32_R3_400_3(len, pins[0]); break;
|
||||||
|
case I_32_R4_400_3: busPtr = new B_32_R4_400_3(len, pins[0]); break;
|
||||||
|
case I_32_R5_400_3: busPtr = new B_32_R5_400_3(len, pins[0]); break;
|
||||||
|
case I_32_R6_400_3: busPtr = new B_32_R6_400_3(len, pins[0]); break;
|
||||||
|
case I_32_R7_400_3: busPtr = new B_32_R7_400_3(len, pins[0]); break;
|
||||||
|
case I_32_I0_400_3: busPtr = new B_32_I0_400_3(len, pins[0]); break;
|
||||||
|
case I_32_I1_400_3: busPtr = new B_32_I1_400_3(len, pins[0]); break;
|
||||||
|
case I_32_R0_TM1_4: busPtr = new B_32_R0_TM1_4(len, pins[0]); break;
|
||||||
|
case I_32_R1_TM1_4: busPtr = new B_32_R1_TM1_4(len, pins[0]); break;
|
||||||
|
case I_32_R2_TM1_4: busPtr = new B_32_R2_TM1_4(len, pins[0]); break;
|
||||||
|
case I_32_R3_TM1_4: busPtr = new B_32_R3_TM1_4(len, pins[0]); break;
|
||||||
|
case I_32_R4_TM1_4: busPtr = new B_32_R4_TM1_4(len, pins[0]); break;
|
||||||
|
case I_32_R5_TM1_4: busPtr = new B_32_R5_TM1_4(len, pins[0]); break;
|
||||||
|
case I_32_R6_TM1_4: busPtr = new B_32_R6_TM1_4(len, pins[0]); break;
|
||||||
|
case I_32_R7_TM1_4: busPtr = new B_32_R7_TM1_4(len, pins[0]); break;
|
||||||
|
case I_32_I0_TM1_4: busPtr = new B_32_I0_TM1_4(len, pins[0]); break;
|
||||||
|
case I_32_I1_TM1_4: busPtr = new B_32_I1_TM1_4(len, pins[0]); break;
|
||||||
|
#endif
|
||||||
|
// for 2-wire: pins[1] is clk, pins[0] is dat. begin expects (len, clk, dat)
|
||||||
|
case I_HS_DOT_3: busPtr = new B_HS_DOT_3(len, pins[1], pins[0]); break;
|
||||||
|
case I_SS_DOT_3: busPtr = new B_SS_DOT_3(len, pins[1], pins[0]); break;
|
||||||
|
case I_HS_LPD_3: busPtr = new B_HS_LPD_3(len, pins[1], pins[0]); break;
|
||||||
|
case I_SS_LPD_3: busPtr = new B_SS_LPD_3(len, pins[1], pins[0]); break;
|
||||||
|
case I_HS_WS1_3: busPtr = new B_HS_WS1_3(len, pins[1], pins[0]); break;
|
||||||
|
case I_SS_WS1_3: busPtr = new B_SS_WS1_3(len, pins[1], pins[0]); break;
|
||||||
|
case I_HS_P98_3: busPtr = new B_HS_P98_3(len, pins[1], pins[0]); break;
|
||||||
|
case I_SS_P98_3: busPtr = new B_SS_P98_3(len, pins[1], pins[0]); break;
|
||||||
|
}
|
||||||
|
begin(busPtr, busType, pins);
|
||||||
|
return busPtr;
|
||||||
|
};
|
||||||
|
static void show(void* busPtr, uint8_t busType) {
|
||||||
|
switch (busType) {
|
||||||
|
case I_NONE: break;
|
||||||
|
#ifdef ESP8266
|
||||||
|
case I_8266_U0_NEO_3: (static_cast<B_8266_U0_NEO_3*>(busPtr))->Show(); break;
|
||||||
|
case I_8266_U1_NEO_3: (static_cast<B_8266_U1_NEO_3*>(busPtr))->Show(); break;
|
||||||
|
case I_8266_DM_NEO_3: (static_cast<B_8266_DM_NEO_3*>(busPtr))->Show(); break;
|
||||||
|
case I_8266_BB_NEO_3: (static_cast<B_8266_BB_NEO_3*>(busPtr))->Show(); break;
|
||||||
|
case I_8266_U0_NEO_4: (static_cast<B_8266_U0_NEO_4*>(busPtr))->Show(); break;
|
||||||
|
case I_8266_U1_NEO_4: (static_cast<B_8266_U1_NEO_4*>(busPtr))->Show(); break;
|
||||||
|
case I_8266_DM_NEO_4: (static_cast<B_8266_DM_NEO_4*>(busPtr))->Show(); break;
|
||||||
|
case I_8266_BB_NEO_4: (static_cast<B_8266_BB_NEO_4*>(busPtr))->Show(); break;
|
||||||
|
case I_8266_U0_400_3: (static_cast<B_8266_U0_400_3*>(busPtr))->Show(); break;
|
||||||
|
case I_8266_U1_400_3: (static_cast<B_8266_U1_400_3*>(busPtr))->Show(); break;
|
||||||
|
case I_8266_DM_400_3: (static_cast<B_8266_DM_400_3*>(busPtr))->Show(); break;
|
||||||
|
case I_8266_BB_400_3: (static_cast<B_8266_BB_400_3*>(busPtr))->Show(); break;
|
||||||
|
case I_8266_U0_TM1_4: (static_cast<B_8266_U0_TM1_4*>(busPtr))->Show(); break;
|
||||||
|
case I_8266_U1_TM1_4: (static_cast<B_8266_U1_TM1_4*>(busPtr))->Show(); break;
|
||||||
|
case I_8266_DM_TM1_4: (static_cast<B_8266_DM_TM1_4*>(busPtr))->Show(); break;
|
||||||
|
case I_8266_BB_TM1_4: (static_cast<B_8266_BB_TM1_4*>(busPtr))->Show(); break;
|
||||||
|
#endif
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
case I_32_R0_NEO_3: (static_cast<B_32_R0_NEO_3*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R1_NEO_3: (static_cast<B_32_R1_NEO_3*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R2_NEO_3: (static_cast<B_32_R2_NEO_3*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R3_NEO_3: (static_cast<B_32_R3_NEO_3*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R4_NEO_3: (static_cast<B_32_R4_NEO_3*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R5_NEO_3: (static_cast<B_32_R5_NEO_3*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R6_NEO_3: (static_cast<B_32_R6_NEO_3*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R7_NEO_3: (static_cast<B_32_R7_NEO_3*>(busPtr))->Show(); break;
|
||||||
|
case I_32_I0_NEO_3: (static_cast<B_32_I0_NEO_3*>(busPtr))->Show(); break;
|
||||||
|
case I_32_I1_NEO_3: (static_cast<B_32_I1_NEO_3*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R0_NEO_4: (static_cast<B_32_R0_NEO_4*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R1_NEO_4: (static_cast<B_32_R1_NEO_4*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R2_NEO_4: (static_cast<B_32_R2_NEO_4*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R3_NEO_4: (static_cast<B_32_R3_NEO_4*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R4_NEO_4: (static_cast<B_32_R4_NEO_4*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R5_NEO_4: (static_cast<B_32_R5_NEO_4*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R6_NEO_4: (static_cast<B_32_R6_NEO_4*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R7_NEO_4: (static_cast<B_32_R7_NEO_4*>(busPtr))->Show(); break;
|
||||||
|
case I_32_I0_NEO_4: (static_cast<B_32_I0_NEO_4*>(busPtr))->Show(); break;
|
||||||
|
case I_32_I1_NEO_4: (static_cast<B_32_I1_NEO_4*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R0_400_3: (static_cast<B_32_R0_400_3*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R1_400_3: (static_cast<B_32_R1_400_3*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R2_400_3: (static_cast<B_32_R2_400_3*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R3_400_3: (static_cast<B_32_R3_400_3*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R4_400_3: (static_cast<B_32_R4_400_3*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R5_400_3: (static_cast<B_32_R5_400_3*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R6_400_3: (static_cast<B_32_R6_400_3*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R7_400_3: (static_cast<B_32_R7_400_3*>(busPtr))->Show(); break;
|
||||||
|
case I_32_I0_400_3: (static_cast<B_32_I0_400_3*>(busPtr))->Show(); break;
|
||||||
|
case I_32_I1_400_3: (static_cast<B_32_I1_400_3*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R0_TM1_4: (static_cast<B_32_R0_TM1_4*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R1_TM1_4: (static_cast<B_32_R1_TM1_4*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R2_TM1_4: (static_cast<B_32_R2_TM1_4*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R3_TM1_4: (static_cast<B_32_R3_TM1_4*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R4_TM1_4: (static_cast<B_32_R4_TM1_4*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R5_TM1_4: (static_cast<B_32_R5_TM1_4*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R6_TM1_4: (static_cast<B_32_R6_TM1_4*>(busPtr))->Show(); break;
|
||||||
|
case I_32_R7_TM1_4: (static_cast<B_32_R7_TM1_4*>(busPtr))->Show(); break;
|
||||||
|
case I_32_I0_TM1_4: (static_cast<B_32_I0_TM1_4*>(busPtr))->Show(); break;
|
||||||
|
case I_32_I1_TM1_4: (static_cast<B_32_I1_TM1_4*>(busPtr))->Show(); break;
|
||||||
|
#endif
|
||||||
|
case I_HS_DOT_3: (static_cast<B_HS_DOT_3*>(busPtr))->Show(); break;
|
||||||
|
case I_SS_DOT_3: (static_cast<B_SS_DOT_3*>(busPtr))->Show(); break;
|
||||||
|
case I_HS_LPD_3: (static_cast<B_HS_LPD_3*>(busPtr))->Show(); break;
|
||||||
|
case I_SS_LPD_3: (static_cast<B_SS_LPD_3*>(busPtr))->Show(); break;
|
||||||
|
case I_HS_WS1_3: (static_cast<B_HS_WS1_3*>(busPtr))->Show(); break;
|
||||||
|
case I_SS_WS1_3: (static_cast<B_SS_WS1_3*>(busPtr))->Show(); break;
|
||||||
|
case I_HS_P98_3: (static_cast<B_HS_P98_3*>(busPtr))->Show(); break;
|
||||||
|
case I_SS_P98_3: (static_cast<B_SS_P98_3*>(busPtr))->Show(); break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static bool canShow(void* busPtr, uint8_t busType) {
|
||||||
|
switch (busType) {
|
||||||
|
case I_NONE: return true;
|
||||||
|
#ifdef ESP8266
|
||||||
|
case I_8266_U0_NEO_3: return (static_cast<B_8266_U0_NEO_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_U1_NEO_3: return (static_cast<B_8266_U1_NEO_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_DM_NEO_3: return (static_cast<B_8266_DM_NEO_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_BB_NEO_3: return (static_cast<B_8266_BB_NEO_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_U0_NEO_4: return (static_cast<B_8266_U0_NEO_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_U1_NEO_4: return (static_cast<B_8266_U1_NEO_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_DM_NEO_4: return (static_cast<B_8266_DM_NEO_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_BB_NEO_4: return (static_cast<B_8266_BB_NEO_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_U0_400_3: return (static_cast<B_8266_U0_400_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_U1_400_3: return (static_cast<B_8266_U1_400_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_DM_400_3: return (static_cast<B_8266_DM_400_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_BB_400_3: return (static_cast<B_8266_BB_400_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_U0_TM1_4: return (static_cast<B_8266_U0_TM1_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_U1_TM1_4: return (static_cast<B_8266_U1_TM1_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_DM_TM1_4: return (static_cast<B_8266_DM_TM1_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_BB_TM1_4: return (static_cast<B_8266_BB_TM1_4*>(busPtr))->CanShow(); break;
|
||||||
|
#endif
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
case I_32_R0_NEO_3: return (static_cast<B_32_R0_NEO_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R1_NEO_3: return (static_cast<B_32_R1_NEO_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R2_NEO_3: return (static_cast<B_32_R2_NEO_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R3_NEO_3: return (static_cast<B_32_R3_NEO_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R4_NEO_3: return (static_cast<B_32_R4_NEO_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R5_NEO_3: return (static_cast<B_32_R5_NEO_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R6_NEO_3: return (static_cast<B_32_R6_NEO_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R7_NEO_3: return (static_cast<B_32_R7_NEO_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_I0_NEO_3: return (static_cast<B_32_I0_NEO_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_I1_NEO_3: return (static_cast<B_32_I1_NEO_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R0_NEO_4: return (static_cast<B_32_R0_NEO_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R1_NEO_4: return (static_cast<B_32_R1_NEO_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R2_NEO_4: return (static_cast<B_32_R2_NEO_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R3_NEO_4: return (static_cast<B_32_R3_NEO_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R4_NEO_4: return (static_cast<B_32_R4_NEO_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R5_NEO_4: return (static_cast<B_32_R5_NEO_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R6_NEO_4: return (static_cast<B_32_R6_NEO_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R7_NEO_4: return (static_cast<B_32_R7_NEO_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_I0_NEO_4: return (static_cast<B_32_I0_NEO_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_I1_NEO_4: return (static_cast<B_32_I1_NEO_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R0_400_3: return (static_cast<B_32_R0_400_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R1_400_3: return (static_cast<B_32_R1_400_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R2_400_3: return (static_cast<B_32_R2_400_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R3_400_3: return (static_cast<B_32_R3_400_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R4_400_3: return (static_cast<B_32_R4_400_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R5_400_3: return (static_cast<B_32_R5_400_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R6_400_3: return (static_cast<B_32_R6_400_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R7_400_3: return (static_cast<B_32_R7_400_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_I0_400_3: return (static_cast<B_32_I0_400_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_I1_400_3: return (static_cast<B_32_I1_400_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R0_TM1_4: return (static_cast<B_32_R0_TM1_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R1_TM1_4: return (static_cast<B_32_R1_TM1_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R2_TM1_4: return (static_cast<B_32_R2_TM1_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R3_TM1_4: return (static_cast<B_32_R3_TM1_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R4_TM1_4: return (static_cast<B_32_R4_TM1_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R5_TM1_4: return (static_cast<B_32_R5_TM1_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R6_TM1_4: return (static_cast<B_32_R6_TM1_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_R7_TM1_4: return (static_cast<B_32_R7_TM1_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_I0_TM1_4: return (static_cast<B_32_I0_TM1_4*>(busPtr))->CanShow(); break;
|
||||||
|
case I_32_I1_TM1_4: return (static_cast<B_32_I1_TM1_4*>(busPtr))->CanShow(); break;
|
||||||
|
#endif
|
||||||
|
case I_HS_DOT_3: return (static_cast<B_HS_DOT_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_SS_DOT_3: return (static_cast<B_SS_DOT_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_HS_LPD_3: return (static_cast<B_HS_LPD_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_SS_LPD_3: return (static_cast<B_SS_LPD_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_HS_WS1_3: return (static_cast<B_HS_WS1_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_SS_WS1_3: return (static_cast<B_SS_WS1_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_HS_P98_3: return (static_cast<B_HS_P98_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_SS_P98_3: return (static_cast<B_SS_P98_3*>(busPtr))->CanShow(); break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
static void setPixelColor(void* busPtr, uint8_t busType, uint16_t pix, uint32_t c, uint8_t co) {
|
||||||
|
uint8_t r = c >> 16;
|
||||||
|
uint8_t g = c >> 8;
|
||||||
|
uint8_t b = c >> 0;
|
||||||
|
uint8_t w = c >> 24;
|
||||||
|
RgbwColor col;
|
||||||
|
|
||||||
|
//TODO make color order override possible on a per-strip basis
|
||||||
|
#ifdef COLOR_ORDER_OVERRIDE
|
||||||
|
if (indexPixel >= COO_MIN && indexPixel < COO_MAX) co = COO_ORDER;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//reorder channels to selected order
|
||||||
|
switch (co)
|
||||||
|
{
|
||||||
|
case 0: col.G = g; col.R = r; col.B = b; break; //0 = GRB, default
|
||||||
|
case 1: col.G = r; col.R = g; col.B = b; break; //1 = RGB, common for WS2811
|
||||||
|
case 2: col.G = b; col.R = r; col.B = g; break; //2 = BRG
|
||||||
|
case 3: col.G = r; col.R = b; col.B = g; break; //3 = RBG
|
||||||
|
case 4: col.G = b; col.R = g; col.B = r; break; //4 = BGR
|
||||||
|
default: col.G = g; col.R = b; col.B = r; break; //5 = GBR
|
||||||
|
}
|
||||||
|
col.W = w;
|
||||||
|
|
||||||
|
switch (busType) {
|
||||||
|
case I_NONE: break;
|
||||||
|
#ifdef ESP8266
|
||||||
|
case I_8266_U0_NEO_3: (static_cast<B_8266_U0_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_8266_U1_NEO_3: (static_cast<B_8266_U1_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_8266_DM_NEO_3: (static_cast<B_8266_DM_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_8266_BB_NEO_3: (static_cast<B_8266_BB_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_8266_U0_NEO_4: (static_cast<B_8266_U0_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_8266_U1_NEO_4: (static_cast<B_8266_U1_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_8266_DM_NEO_4: (static_cast<B_8266_DM_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_8266_BB_NEO_4: (static_cast<B_8266_BB_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_8266_U0_400_3: (static_cast<B_8266_U0_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_8266_U1_400_3: (static_cast<B_8266_U1_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_8266_DM_400_3: (static_cast<B_8266_DM_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_8266_BB_400_3: (static_cast<B_8266_BB_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_8266_U0_TM1_4: (static_cast<B_8266_U0_TM1_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_8266_U1_TM1_4: (static_cast<B_8266_U1_TM1_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_8266_DM_TM1_4: (static_cast<B_8266_DM_TM1_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_8266_BB_TM1_4: (static_cast<B_8266_BB_TM1_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
#endif
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
case I_32_R0_NEO_3: (static_cast<B_32_R0_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_32_R1_NEO_3: (static_cast<B_32_R1_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_32_R2_NEO_3: (static_cast<B_32_R2_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_32_R3_NEO_3: (static_cast<B_32_R3_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_32_R4_NEO_3: (static_cast<B_32_R4_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_32_R5_NEO_3: (static_cast<B_32_R5_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_32_R6_NEO_3: (static_cast<B_32_R6_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_32_R7_NEO_3: (static_cast<B_32_R7_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_32_I0_NEO_3: (static_cast<B_32_I0_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_32_I1_NEO_3: (static_cast<B_32_I1_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_32_R0_NEO_4: (static_cast<B_32_R0_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_32_R1_NEO_4: (static_cast<B_32_R1_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_32_R2_NEO_4: (static_cast<B_32_R2_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_32_R3_NEO_4: (static_cast<B_32_R3_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_32_R4_NEO_4: (static_cast<B_32_R4_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_32_R5_NEO_4: (static_cast<B_32_R5_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_32_R6_NEO_4: (static_cast<B_32_R6_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_32_R7_NEO_4: (static_cast<B_32_R7_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_32_I0_NEO_4: (static_cast<B_32_I0_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_32_I1_NEO_4: (static_cast<B_32_I1_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_32_R0_400_3: (static_cast<B_32_R0_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_32_R1_400_3: (static_cast<B_32_R1_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_32_R2_400_3: (static_cast<B_32_R2_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_32_R3_400_3: (static_cast<B_32_R3_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_32_R4_400_3: (static_cast<B_32_R4_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_32_R5_400_3: (static_cast<B_32_R5_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_32_R6_400_3: (static_cast<B_32_R6_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_32_R7_400_3: (static_cast<B_32_R7_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_32_I0_400_3: (static_cast<B_32_I0_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_32_I1_400_3: (static_cast<B_32_I1_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_32_R0_TM1_4: (static_cast<B_32_R0_TM1_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_32_R1_TM1_4: (static_cast<B_32_R1_TM1_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_32_R2_TM1_4: (static_cast<B_32_R2_TM1_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_32_R3_TM1_4: (static_cast<B_32_R3_TM1_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_32_R4_TM1_4: (static_cast<B_32_R4_TM1_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_32_R5_TM1_4: (static_cast<B_32_R5_TM1_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_32_R6_TM1_4: (static_cast<B_32_R6_TM1_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_32_R7_TM1_4: (static_cast<B_32_R7_TM1_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_32_I0_TM1_4: (static_cast<B_32_I0_TM1_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
case I_32_I1_TM1_4: (static_cast<B_32_I1_TM1_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
#endif
|
||||||
|
case I_HS_DOT_3: (static_cast<B_HS_DOT_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_SS_DOT_3: (static_cast<B_SS_DOT_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_HS_LPD_3: (static_cast<B_HS_LPD_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_SS_LPD_3: (static_cast<B_SS_LPD_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_HS_WS1_3: (static_cast<B_HS_WS1_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_SS_WS1_3: (static_cast<B_SS_WS1_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_HS_P98_3: (static_cast<B_HS_P98_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
case I_SS_P98_3: (static_cast<B_SS_P98_3*>(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static void setBrightness(void* busPtr, uint8_t busType, uint8_t b) {
|
||||||
|
switch (busType) {
|
||||||
|
case I_NONE: break;
|
||||||
|
#ifdef ESP8266
|
||||||
|
case I_8266_U0_NEO_3: (static_cast<B_8266_U0_NEO_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_8266_U1_NEO_3: (static_cast<B_8266_U1_NEO_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_8266_DM_NEO_3: (static_cast<B_8266_DM_NEO_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_8266_BB_NEO_3: (static_cast<B_8266_BB_NEO_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_8266_U0_NEO_4: (static_cast<B_8266_U0_NEO_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_8266_U1_NEO_4: (static_cast<B_8266_U1_NEO_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_8266_DM_NEO_4: (static_cast<B_8266_DM_NEO_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_8266_BB_NEO_4: (static_cast<B_8266_BB_NEO_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_8266_U0_400_3: (static_cast<B_8266_U0_400_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_8266_U1_400_3: (static_cast<B_8266_U1_400_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_8266_DM_400_3: (static_cast<B_8266_DM_400_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_8266_BB_400_3: (static_cast<B_8266_BB_400_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_8266_U0_TM1_4: (static_cast<B_8266_U0_TM1_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_8266_U1_TM1_4: (static_cast<B_8266_U1_TM1_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_8266_DM_TM1_4: (static_cast<B_8266_DM_TM1_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_8266_BB_TM1_4: (static_cast<B_8266_BB_TM1_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
#endif
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
case I_32_R0_NEO_3: (static_cast<B_32_R0_NEO_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R1_NEO_3: (static_cast<B_32_R1_NEO_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R2_NEO_3: (static_cast<B_32_R2_NEO_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R3_NEO_3: (static_cast<B_32_R3_NEO_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R4_NEO_3: (static_cast<B_32_R4_NEO_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R5_NEO_3: (static_cast<B_32_R5_NEO_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R6_NEO_3: (static_cast<B_32_R6_NEO_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R7_NEO_3: (static_cast<B_32_R7_NEO_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_I0_NEO_3: (static_cast<B_32_I0_NEO_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_I1_NEO_3: (static_cast<B_32_I1_NEO_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R0_NEO_4: (static_cast<B_32_R0_NEO_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R1_NEO_4: (static_cast<B_32_R1_NEO_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R2_NEO_4: (static_cast<B_32_R2_NEO_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R3_NEO_4: (static_cast<B_32_R3_NEO_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R4_NEO_4: (static_cast<B_32_R4_NEO_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R5_NEO_4: (static_cast<B_32_R5_NEO_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R6_NEO_4: (static_cast<B_32_R6_NEO_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R7_NEO_4: (static_cast<B_32_R7_NEO_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_I0_NEO_4: (static_cast<B_32_I0_NEO_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_I1_NEO_4: (static_cast<B_32_I1_NEO_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R0_400_3: (static_cast<B_32_R0_400_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R1_400_3: (static_cast<B_32_R1_400_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R2_400_3: (static_cast<B_32_R2_400_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R3_400_3: (static_cast<B_32_R3_400_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R4_400_3: (static_cast<B_32_R4_400_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R5_400_3: (static_cast<B_32_R5_400_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R6_400_3: (static_cast<B_32_R6_400_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R7_400_3: (static_cast<B_32_R7_400_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_I0_400_3: (static_cast<B_32_I0_400_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_I1_400_3: (static_cast<B_32_I1_400_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R0_TM1_4: (static_cast<B_32_R0_TM1_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R1_TM1_4: (static_cast<B_32_R1_TM1_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R2_TM1_4: (static_cast<B_32_R2_TM1_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R3_TM1_4: (static_cast<B_32_R3_TM1_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R4_TM1_4: (static_cast<B_32_R4_TM1_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R5_TM1_4: (static_cast<B_32_R5_TM1_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R6_TM1_4: (static_cast<B_32_R6_TM1_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_R7_TM1_4: (static_cast<B_32_R7_TM1_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_I0_TM1_4: (static_cast<B_32_I0_TM1_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_32_I1_TM1_4: (static_cast<B_32_I1_TM1_4*>(busPtr))->SetBrightness(b); break;
|
||||||
|
#endif
|
||||||
|
case I_HS_DOT_3: (static_cast<B_HS_DOT_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_SS_DOT_3: (static_cast<B_SS_DOT_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_HS_LPD_3: (static_cast<B_HS_LPD_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_SS_LPD_3: (static_cast<B_SS_LPD_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_HS_WS1_3: (static_cast<B_HS_WS1_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_SS_WS1_3: (static_cast<B_SS_WS1_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_HS_P98_3: (static_cast<B_HS_P98_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
case I_SS_P98_3: (static_cast<B_SS_P98_3*>(busPtr))->SetBrightness(b); break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static uint32_t getPixelColor(void* busPtr, uint8_t busType, uint16_t pix, uint8_t co) {
|
||||||
|
RgbwColor col(0,0,0,0);
|
||||||
|
switch (busType) {
|
||||||
|
case I_NONE: break;
|
||||||
|
#ifdef ESP8266
|
||||||
|
case I_8266_U0_NEO_3: col = (static_cast<B_8266_U0_NEO_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_8266_U1_NEO_3: col = (static_cast<B_8266_U1_NEO_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_8266_DM_NEO_3: col = (static_cast<B_8266_DM_NEO_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_8266_BB_NEO_3: col = (static_cast<B_8266_BB_NEO_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_8266_U0_NEO_4: col = (static_cast<B_8266_U0_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_8266_U1_NEO_4: col = (static_cast<B_8266_U1_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_8266_DM_NEO_4: col = (static_cast<B_8266_DM_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_8266_BB_NEO_4: col = (static_cast<B_8266_BB_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_8266_U0_400_3: col = (static_cast<B_8266_U0_400_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_8266_U1_400_3: col = (static_cast<B_8266_U1_400_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_8266_DM_400_3: col = (static_cast<B_8266_DM_400_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_8266_BB_400_3: col = (static_cast<B_8266_BB_400_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_8266_U0_TM1_4: col = (static_cast<B_8266_U0_TM1_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_8266_U1_TM1_4: col = (static_cast<B_8266_U1_TM1_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_8266_DM_TM1_4: col = (static_cast<B_8266_DM_TM1_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_8266_BB_TM1_4: col = (static_cast<B_8266_BB_TM1_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
#endif
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
case I_32_R0_NEO_3: col = (static_cast<B_32_R0_NEO_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R1_NEO_3: col = (static_cast<B_32_R1_NEO_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R2_NEO_3: col = (static_cast<B_32_R2_NEO_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R3_NEO_3: col = (static_cast<B_32_R3_NEO_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R4_NEO_3: col = (static_cast<B_32_R4_NEO_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R5_NEO_3: col = (static_cast<B_32_R5_NEO_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R6_NEO_3: col = (static_cast<B_32_R6_NEO_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R7_NEO_3: col = (static_cast<B_32_R7_NEO_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_I0_NEO_3: col = (static_cast<B_32_I0_NEO_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_I1_NEO_3: col = (static_cast<B_32_I1_NEO_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R0_NEO_4: col = (static_cast<B_32_R0_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R1_NEO_4: col = (static_cast<B_32_R1_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R2_NEO_4: col = (static_cast<B_32_R2_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R3_NEO_4: col = (static_cast<B_32_R3_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R4_NEO_4: col = (static_cast<B_32_R4_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R5_NEO_4: col = (static_cast<B_32_R5_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R6_NEO_4: col = (static_cast<B_32_R6_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R7_NEO_4: col = (static_cast<B_32_R7_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_I0_NEO_4: col = (static_cast<B_32_I0_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_I1_NEO_4: col = (static_cast<B_32_I1_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R0_400_3: col = (static_cast<B_32_R0_400_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R1_400_3: col = (static_cast<B_32_R1_400_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R2_400_3: col = (static_cast<B_32_R2_400_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R3_400_3: col = (static_cast<B_32_R3_400_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R4_400_3: col = (static_cast<B_32_R4_400_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R5_400_3: col = (static_cast<B_32_R5_400_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R6_400_3: col = (static_cast<B_32_R6_400_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R7_400_3: col = (static_cast<B_32_R7_400_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_I0_400_3: col = (static_cast<B_32_I0_400_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_I1_400_3: col = (static_cast<B_32_I1_400_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R0_TM1_4: col = (static_cast<B_32_R0_TM1_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R1_TM1_4: col = (static_cast<B_32_R1_TM1_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R2_TM1_4: col = (static_cast<B_32_R2_TM1_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R3_TM1_4: col = (static_cast<B_32_R3_TM1_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R4_TM1_4: col = (static_cast<B_32_R4_TM1_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R5_TM1_4: col = (static_cast<B_32_R5_TM1_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R6_TM1_4: col = (static_cast<B_32_R6_TM1_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_R7_TM1_4: col = (static_cast<B_32_R7_TM1_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_I0_TM1_4: col = (static_cast<B_32_I0_TM1_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_32_I1_TM1_4: col = (static_cast<B_32_I1_TM1_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
#endif
|
||||||
|
case I_HS_DOT_3: col = (static_cast<B_HS_DOT_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_SS_DOT_3: col = (static_cast<B_SS_DOT_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_HS_LPD_3: col = (static_cast<B_HS_LPD_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_SS_LPD_3: col = (static_cast<B_SS_LPD_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_HS_WS1_3: col = (static_cast<B_HS_WS1_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_SS_WS1_3: col = (static_cast<B_SS_WS1_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_HS_P98_3: col = (static_cast<B_HS_P98_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_SS_P98_3: col = (static_cast<B_SS_P98_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef COLOR_ORDER_OVERRIDE
|
||||||
|
if (indexPixel >= COO_MIN && indexPixel < COO_MAX) co = COO_ORDER;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (co)
|
||||||
|
{
|
||||||
|
// W G R B
|
||||||
|
case 0: return ((col.W << 24) | (col.G << 8) | (col.R << 16) | (col.B)); //0 = GRB, default
|
||||||
|
case 1: return ((col.W << 24) | (col.R << 8) | (col.G << 16) | (col.B)); //1 = RGB, common for WS2811
|
||||||
|
case 2: return ((col.W << 24) | (col.B << 8) | (col.R << 16) | (col.G)); //2 = BRG
|
||||||
|
case 3: return ((col.W << 24) | (col.B << 8) | (col.G << 16) | (col.R)); //3 = RBG
|
||||||
|
case 4: return ((col.W << 24) | (col.R << 8) | (col.B << 16) | (col.G)); //4 = BGR
|
||||||
|
case 5: return ((col.W << 24) | (col.G << 8) | (col.B << 16) | (col.R)); //5 = GBR
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cleanup(void* busPtr, uint8_t busType) {
|
||||||
|
if (busPtr == nullptr) return;
|
||||||
|
switch (busType) {
|
||||||
|
case I_NONE: break;
|
||||||
|
#ifdef ESP8266
|
||||||
|
case I_8266_U0_NEO_3: delete (static_cast<B_8266_U0_NEO_3*>(busPtr)); break;
|
||||||
|
case I_8266_U1_NEO_3: delete (static_cast<B_8266_U1_NEO_3*>(busPtr)); break;
|
||||||
|
case I_8266_DM_NEO_3: delete (static_cast<B_8266_DM_NEO_3*>(busPtr)); break;
|
||||||
|
case I_8266_BB_NEO_3: delete (static_cast<B_8266_BB_NEO_3*>(busPtr)); break;
|
||||||
|
case I_8266_U0_NEO_4: delete (static_cast<B_8266_U0_NEO_4*>(busPtr)); break;
|
||||||
|
case I_8266_U1_NEO_4: delete (static_cast<B_8266_U1_NEO_4*>(busPtr)); break;
|
||||||
|
case I_8266_DM_NEO_4: delete (static_cast<B_8266_DM_NEO_4*>(busPtr)); break;
|
||||||
|
case I_8266_BB_NEO_4: delete (static_cast<B_8266_BB_NEO_4*>(busPtr)); break;
|
||||||
|
case I_8266_U0_400_3: delete (static_cast<B_8266_U0_400_3*>(busPtr)); break;
|
||||||
|
case I_8266_U1_400_3: delete (static_cast<B_8266_U1_400_3*>(busPtr)); break;
|
||||||
|
case I_8266_DM_400_3: delete (static_cast<B_8266_DM_400_3*>(busPtr)); break;
|
||||||
|
case I_8266_BB_400_3: delete (static_cast<B_8266_BB_400_3*>(busPtr)); break;
|
||||||
|
case I_8266_U0_TM1_4: delete (static_cast<B_8266_U0_TM1_4*>(busPtr)); break;
|
||||||
|
case I_8266_U1_TM1_4: delete (static_cast<B_8266_U1_TM1_4*>(busPtr)); break;
|
||||||
|
case I_8266_DM_TM1_4: delete (static_cast<B_8266_DM_TM1_4*>(busPtr)); break;
|
||||||
|
case I_8266_BB_TM1_4: delete (static_cast<B_8266_BB_TM1_4*>(busPtr)); break;
|
||||||
|
#endif
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
case I_32_R0_NEO_3: delete (static_cast<B_32_R0_NEO_3*>(busPtr)); break;
|
||||||
|
case I_32_R1_NEO_3: delete (static_cast<B_32_R1_NEO_3*>(busPtr)); break;
|
||||||
|
case I_32_R2_NEO_3: delete (static_cast<B_32_R2_NEO_3*>(busPtr)); break;
|
||||||
|
case I_32_R3_NEO_3: delete (static_cast<B_32_R3_NEO_3*>(busPtr)); break;
|
||||||
|
case I_32_R4_NEO_3: delete (static_cast<B_32_R4_NEO_3*>(busPtr)); break;
|
||||||
|
case I_32_R5_NEO_3: delete (static_cast<B_32_R5_NEO_3*>(busPtr)); break;
|
||||||
|
case I_32_R6_NEO_3: delete (static_cast<B_32_R6_NEO_3*>(busPtr)); break;
|
||||||
|
case I_32_R7_NEO_3: delete (static_cast<B_32_R7_NEO_3*>(busPtr)); break;
|
||||||
|
case I_32_I0_NEO_3: delete (static_cast<B_32_I0_NEO_3*>(busPtr)); break;
|
||||||
|
case I_32_I1_NEO_3: delete (static_cast<B_32_I1_NEO_3*>(busPtr)); break;
|
||||||
|
case I_32_R0_NEO_4: delete (static_cast<B_32_R0_NEO_4*>(busPtr)); break;
|
||||||
|
case I_32_R1_NEO_4: delete (static_cast<B_32_R1_NEO_4*>(busPtr)); break;
|
||||||
|
case I_32_R2_NEO_4: delete (static_cast<B_32_R2_NEO_4*>(busPtr)); break;
|
||||||
|
case I_32_R3_NEO_4: delete (static_cast<B_32_R3_NEO_4*>(busPtr)); break;
|
||||||
|
case I_32_R4_NEO_4: delete (static_cast<B_32_R4_NEO_4*>(busPtr)); break;
|
||||||
|
case I_32_R5_NEO_4: delete (static_cast<B_32_R5_NEO_4*>(busPtr)); break;
|
||||||
|
case I_32_R6_NEO_4: delete (static_cast<B_32_R6_NEO_4*>(busPtr)); break;
|
||||||
|
case I_32_R7_NEO_4: delete (static_cast<B_32_R7_NEO_4*>(busPtr)); break;
|
||||||
|
case I_32_I0_NEO_4: delete (static_cast<B_32_I0_NEO_4*>(busPtr)); break;
|
||||||
|
case I_32_I1_NEO_4: delete (static_cast<B_32_I1_NEO_4*>(busPtr)); break;
|
||||||
|
case I_32_R0_400_3: delete (static_cast<B_32_R0_400_3*>(busPtr)); break;
|
||||||
|
case I_32_R1_400_3: delete (static_cast<B_32_R1_400_3*>(busPtr)); break;
|
||||||
|
case I_32_R2_400_3: delete (static_cast<B_32_R2_400_3*>(busPtr)); break;
|
||||||
|
case I_32_R3_400_3: delete (static_cast<B_32_R3_400_3*>(busPtr)); break;
|
||||||
|
case I_32_R4_400_3: delete (static_cast<B_32_R4_400_3*>(busPtr)); break;
|
||||||
|
case I_32_R5_400_3: delete (static_cast<B_32_R5_400_3*>(busPtr)); break;
|
||||||
|
case I_32_R6_400_3: delete (static_cast<B_32_R6_400_3*>(busPtr)); break;
|
||||||
|
case I_32_R7_400_3: delete (static_cast<B_32_R7_400_3*>(busPtr)); break;
|
||||||
|
case I_32_I0_400_3: delete (static_cast<B_32_I0_400_3*>(busPtr)); break;
|
||||||
|
case I_32_I1_400_3: delete (static_cast<B_32_I1_400_3*>(busPtr)); break;
|
||||||
|
case I_32_R0_TM1_4: delete (static_cast<B_32_R0_TM1_4*>(busPtr)); break;
|
||||||
|
case I_32_R1_TM1_4: delete (static_cast<B_32_R1_TM1_4*>(busPtr)); break;
|
||||||
|
case I_32_R2_TM1_4: delete (static_cast<B_32_R2_TM1_4*>(busPtr)); break;
|
||||||
|
case I_32_R3_TM1_4: delete (static_cast<B_32_R3_TM1_4*>(busPtr)); break;
|
||||||
|
case I_32_R4_TM1_4: delete (static_cast<B_32_R4_TM1_4*>(busPtr)); break;
|
||||||
|
case I_32_R5_TM1_4: delete (static_cast<B_32_R5_TM1_4*>(busPtr)); break;
|
||||||
|
case I_32_R6_TM1_4: delete (static_cast<B_32_R6_TM1_4*>(busPtr)); break;
|
||||||
|
case I_32_R7_TM1_4: delete (static_cast<B_32_R7_TM1_4*>(busPtr)); break;
|
||||||
|
case I_32_I0_TM1_4: delete (static_cast<B_32_I0_TM1_4*>(busPtr)); break;
|
||||||
|
case I_32_I1_TM1_4: delete (static_cast<B_32_I1_TM1_4*>(busPtr)); break;
|
||||||
|
#endif
|
||||||
|
case I_HS_DOT_3: delete (static_cast<B_HS_DOT_3*>(busPtr)); break;
|
||||||
|
case I_SS_DOT_3: delete (static_cast<B_SS_DOT_3*>(busPtr)); break;
|
||||||
|
case I_HS_LPD_3: delete (static_cast<B_HS_LPD_3*>(busPtr)); break;
|
||||||
|
case I_SS_LPD_3: delete (static_cast<B_SS_LPD_3*>(busPtr)); break;
|
||||||
|
case I_HS_WS1_3: delete (static_cast<B_HS_WS1_3*>(busPtr)); break;
|
||||||
|
case I_SS_WS1_3: delete (static_cast<B_SS_WS1_3*>(busPtr)); break;
|
||||||
|
case I_HS_P98_3: delete (static_cast<B_HS_P98_3*>(busPtr)); break;
|
||||||
|
case I_SS_P98_3: delete (static_cast<B_SS_P98_3*>(busPtr)); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//gives back the internal type index (I_XX_XXX_X above) for the input
|
||||||
|
static uint8_t getI(uint8_t busType, uint8_t* pins, uint8_t num = 0) {
|
||||||
|
if (!IS_DIGITAL(busType)) return I_NONE;
|
||||||
|
if (IS_2PIN(busType)) { //SPI LED chips
|
||||||
|
bool isHSPI = false;
|
||||||
|
#ifdef ESP8266
|
||||||
|
if (pins[0] == P_8266_HS_MOSI && pins[1] == P_8266_HS_CLK) isHSPI = true;
|
||||||
|
#else
|
||||||
|
if(!num) isHSPI = true; // temporary hack to limit use of hardware SPI to a single SPI peripheral: only allow ESP32 hardware serial on segment 0
|
||||||
|
#endif
|
||||||
|
uint8_t t = I_NONE;
|
||||||
|
switch (busType) {
|
||||||
|
case TYPE_APA102: t = I_SS_DOT_3; break;
|
||||||
|
case TYPE_LPD8806: t = I_SS_LPD_3; break;
|
||||||
|
case TYPE_WS2801: t = I_SS_WS1_3; break;
|
||||||
|
case TYPE_P9813: t = I_SS_P98_3; break;
|
||||||
|
default: t=I_NONE;
|
||||||
|
}
|
||||||
|
if (t > I_NONE && isHSPI) t--; //hardware SPI has one smaller ID than software
|
||||||
|
return t;
|
||||||
|
} else {
|
||||||
|
#ifdef ESP8266
|
||||||
|
uint8_t offset = pins[0] -1; //for driver: 0 = uart0, 1 = uart1, 2 = dma, 3 = bitbang
|
||||||
|
if (offset > 3) offset = 3;
|
||||||
|
switch (busType) {
|
||||||
|
case TYPE_WS2812_RGB:
|
||||||
|
case TYPE_WS2812_WWA:
|
||||||
|
return I_8266_U0_NEO_3 + offset;
|
||||||
|
case TYPE_SK6812_RGBW:
|
||||||
|
return I_8266_U0_NEO_4 + offset;
|
||||||
|
case TYPE_WS2811_400KHZ:
|
||||||
|
return I_8266_U0_400_3 + offset;
|
||||||
|
}
|
||||||
|
#else //ESP32
|
||||||
|
uint8_t offset = num; //RMT bus # == bus index in BusManager
|
||||||
|
if (offset > 9) return I_NONE;
|
||||||
|
switch (busType) {
|
||||||
|
case TYPE_WS2812_RGB:
|
||||||
|
case TYPE_WS2812_WWA:
|
||||||
|
return I_32_R0_NEO_3 + offset;
|
||||||
|
case TYPE_SK6812_RGBW:
|
||||||
|
return I_32_R0_NEO_4 + offset;
|
||||||
|
case TYPE_WS2811_400KHZ:
|
||||||
|
return I_32_R0_400_3 + offset;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return I_NONE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -17,9 +17,7 @@ void shortPressAction()
|
|||||||
|
|
||||||
bool isButtonPressed()
|
bool isButtonPressed()
|
||||||
{
|
{
|
||||||
#if defined(BTNPIN) && BTNPIN > -1
|
if (btnPin>=0 && digitalRead(btnPin) == LOW) return true;
|
||||||
if (digitalRead(BTNPIN) == LOW) return true;
|
|
||||||
#endif
|
|
||||||
#ifdef TOUCHPIN
|
#ifdef TOUCHPIN
|
||||||
if (touchRead(TOUCHPIN) <= TOUCH_THRESHOLD) return true;
|
if (touchRead(TOUCHPIN) <= TOUCH_THRESHOLD) return true;
|
||||||
#endif
|
#endif
|
||||||
@ -29,8 +27,7 @@ bool isButtonPressed()
|
|||||||
|
|
||||||
void handleButton()
|
void handleButton()
|
||||||
{
|
{
|
||||||
#if (defined(BTNPIN) && BTNPIN > -1) || defined(TOUCHPIN)
|
if (btnPin<0 || !buttonEnabled) return;
|
||||||
if (!buttonEnabled) return;
|
|
||||||
|
|
||||||
if (isButtonPressed()) //pressed
|
if (isButtonPressed()) //pressed
|
||||||
{
|
{
|
||||||
@ -75,7 +72,6 @@ void handleButton()
|
|||||||
buttonWaitTime = 0;
|
buttonWaitTime = 0;
|
||||||
shortPressAction();
|
shortPressAction();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleIO()
|
void handleIO()
|
||||||
@ -88,37 +84,39 @@ void handleIO()
|
|||||||
lastOnTime = millis();
|
lastOnTime = millis();
|
||||||
if (offMode)
|
if (offMode)
|
||||||
{
|
{
|
||||||
#if RLYPIN >= 0
|
if (rlyPin>=0) {
|
||||||
digitalWrite(RLYPIN, RLYMDE);
|
pinMode(rlyPin, OUTPUT);
|
||||||
#endif
|
digitalWrite(rlyPin, rlyMde);
|
||||||
|
}
|
||||||
offMode = false;
|
offMode = false;
|
||||||
}
|
}
|
||||||
} else if (millis() - lastOnTime > 600)
|
} else if (millis() - lastOnTime > 600)
|
||||||
{
|
{
|
||||||
if (!offMode) {
|
if (!offMode) {
|
||||||
#if LEDPIN == LED_BUILTIN
|
#ifdef ESP8266
|
||||||
|
//turn off built-in LED if strip is turned off
|
||||||
pinMode(LED_BUILTIN, OUTPUT);
|
pinMode(LED_BUILTIN, OUTPUT);
|
||||||
digitalWrite(LED_BUILTIN, HIGH);
|
digitalWrite(LED_BUILTIN, HIGH);
|
||||||
#endif
|
#endif
|
||||||
#if RLYPIN >= 0
|
if (rlyPin>=0) {
|
||||||
digitalWrite(RLYPIN, !RLYMDE);
|
pinMode(rlyPin, OUTPUT);
|
||||||
#endif
|
digitalWrite(rlyPin, !rlyMde);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
offMode = true;
|
offMode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if AUXPIN >= 0
|
|
||||||
//output
|
//output
|
||||||
if (auxActive || auxActiveBefore)
|
if (auxPin>=1 && (auxActive || auxActiveBefore))
|
||||||
{
|
{
|
||||||
if (!auxActiveBefore)
|
if (!auxActiveBefore)
|
||||||
{
|
{
|
||||||
auxActiveBefore = true;
|
auxActiveBefore = true;
|
||||||
switch (auxTriggeredState)
|
switch (auxTriggeredState)
|
||||||
{
|
{
|
||||||
case 0: pinMode(AUXPIN, INPUT); break;
|
case 0: pinMode(auxPin, INPUT); break;
|
||||||
case 1: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, HIGH); break;
|
case 1: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, HIGH); break;
|
||||||
case 2: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, LOW); break;
|
case 2: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, LOW); break;
|
||||||
}
|
}
|
||||||
auxStartTime = millis();
|
auxStartTime = millis();
|
||||||
}
|
}
|
||||||
@ -128,11 +126,10 @@ void handleIO()
|
|||||||
auxActiveBefore = false;
|
auxActiveBefore = false;
|
||||||
switch (auxDefaultState)
|
switch (auxDefaultState)
|
||||||
{
|
{
|
||||||
case 0: pinMode(AUXPIN, INPUT); break;
|
case 0: pinMode(auxPin, INPUT); break;
|
||||||
case 1: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, HIGH); break;
|
case 1: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, HIGH); break;
|
||||||
case 2: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, LOW); break;
|
case 2: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, LOW); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
283
wled00/cfg.cpp
283
wled00/cfg.cpp
@ -30,14 +30,12 @@ void deserializeConfig() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//deserializeJson(doc, json);
|
//int rev_major = doc["rev"][0]; // 1
|
||||||
|
//int rev_minor = doc["rev"][1]; // 0
|
||||||
//int rev_major = doc[F("rev")][0]; // 1
|
|
||||||
//int rev_minor = doc[F("rev")][1]; // 0
|
|
||||||
|
|
||||||
//long vid = doc[F("vid")]; // 2010020
|
//long vid = doc[F("vid")]; // 2010020
|
||||||
|
|
||||||
JsonObject id = doc[F("id")];
|
JsonObject id = doc["id"];
|
||||||
getStringFromJson(cmDNS, id[F("mdns")], 33);
|
getStringFromJson(cmDNS, id[F("mdns")], 33);
|
||||||
getStringFromJson(serverDescription, id[F("name")], 33);
|
getStringFromJson(serverDescription, id[F("name")], 33);
|
||||||
getStringFromJson(alexaInvocationName, id[F("inv")], 33);
|
getStringFromJson(alexaInvocationName, id[F("inv")], 33);
|
||||||
@ -49,9 +47,9 @@ void deserializeConfig() {
|
|||||||
//If it is present however, we will use it
|
//If it is present however, we will use it
|
||||||
getStringFromJson(clientPass, nw_ins_0["psk"], 65);
|
getStringFromJson(clientPass, nw_ins_0["psk"], 65);
|
||||||
|
|
||||||
JsonArray nw_ins_0_ip = nw_ins_0[F("ip")];
|
JsonArray nw_ins_0_ip = nw_ins_0["ip"];
|
||||||
JsonArray nw_ins_0_gw = nw_ins_0[F("gw")];
|
JsonArray nw_ins_0_gw = nw_ins_0["gw"];
|
||||||
JsonArray nw_ins_0_sn = nw_ins_0[F("sn")];
|
JsonArray nw_ins_0_sn = nw_ins_0["sn"];
|
||||||
|
|
||||||
for (byte i = 0; i < 4; i++) {
|
for (byte i = 0; i < 4; i++) {
|
||||||
CJSON(staticIP[i], nw_ins_0_ip[i]);
|
CJSON(staticIP[i], nw_ins_0_ip[i]);
|
||||||
@ -59,7 +57,7 @@ void deserializeConfig() {
|
|||||||
CJSON(staticSubnet[i], nw_ins_0_sn[i]);
|
CJSON(staticSubnet[i], nw_ins_0_sn[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonObject ap = doc[F("ap")];
|
JsonObject ap = doc["ap"];
|
||||||
getStringFromJson(apSSID, ap[F("ssid")], 33);
|
getStringFromJson(apSSID, ap[F("ssid")], 33);
|
||||||
getStringFromJson(apPass, ap["psk"] , 65); //normally not present due to security
|
getStringFromJson(apPass, ap["psk"] , 65); //normally not present due to security
|
||||||
//int ap_pskl = ap[F("pskl")];
|
//int ap_pskl = ap[F("pskl")];
|
||||||
@ -74,11 +72,11 @@ void deserializeConfig() {
|
|||||||
|
|
||||||
#ifdef WLED_USE_ETHERNET
|
#ifdef WLED_USE_ETHERNET
|
||||||
JsonObject ethernet = doc[F("eth")];
|
JsonObject ethernet = doc[F("eth")];
|
||||||
CJSON(ethernetType, ethernet[F("type")]);
|
CJSON(ethernetType, ethernet["type"]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
JsonArray ap_ip = ap[F("ip")];
|
JsonArray ap_ip = ap["ip"];
|
||||||
for (byte i = 0; i < 4; i++) {
|
for (byte i = 0; i < 4; i++) {
|
||||||
apIP[i] = ap_ip;
|
apIP[i] = ap_ip;
|
||||||
}*/
|
}*/
|
||||||
@ -89,44 +87,94 @@ void deserializeConfig() {
|
|||||||
|
|
||||||
JsonObject hw = doc[F("hw")];
|
JsonObject hw = doc[F("hw")];
|
||||||
|
|
||||||
|
// initialize LED pins and lengths prior to other HW
|
||||||
JsonObject hw_led = hw[F("led")];
|
JsonObject hw_led = hw[F("led")];
|
||||||
|
|
||||||
CJSON(ledCount, hw_led[F("total")]);
|
CJSON(ledCount, hw_led[F("total")]);
|
||||||
if (ledCount > MAX_LEDS) ledCount = MAX_LEDS;
|
if (ledCount > MAX_LEDS) ledCount = MAX_LEDS;
|
||||||
|
|
||||||
CJSON(strip.ablMilliampsMax, hw_led[F("maxpwr")]);
|
CJSON(strip.ablMilliampsMax, hw_led[F("maxpwr")]);
|
||||||
CJSON(strip.milliampsPerLed, hw_led[F("ledma")]);
|
CJSON(strip.milliampsPerLed, hw_led[F("ledma")]);
|
||||||
CJSON(strip.reverseMode, hw_led[F("rev")]);
|
CJSON(strip.reverseMode, hw_led["rev"]);
|
||||||
CJSON(strip.rgbwMode, hw_led[F("rgbwm")]);
|
CJSON(strip.rgbwMode, hw_led[F("rgbwm")]);
|
||||||
|
|
||||||
JsonObject hw_led_ins_0 = hw_led[F("ins")][0];
|
JsonArray ins = hw_led["ins"];
|
||||||
//bool hw_led_ins_0_en = hw_led_ins_0[F("en")]; // true
|
uint8_t s = 0; //bus iterator
|
||||||
//int hw_led_ins_0_start = hw_led_ins_0[F("start")]; // 0
|
useRGBW = false;
|
||||||
//int hw_led_ins_0_len = hw_led_ins_0[F("len")]; // 1200
|
busses.removeAll();
|
||||||
|
uint32_t mem = 0;
|
||||||
|
for (JsonObject elm : ins) {
|
||||||
|
if (s >= WLED_MAX_BUSSES) break;
|
||||||
|
uint8_t pins[5] = {255, 255, 255, 255, 255};
|
||||||
|
JsonArray pinArr = elm[F("pin")];
|
||||||
|
if (pinArr.size() == 0) continue;
|
||||||
|
pins[0] = pinArr[0];
|
||||||
|
uint8_t i = 0;
|
||||||
|
for (int p : pinArr) {
|
||||||
|
pins[i] = p;
|
||||||
|
i++;
|
||||||
|
if (i>4) break;
|
||||||
|
}
|
||||||
|
|
||||||
//int hw_led_ins_0_pin_0 = hw_led_ins_0[F("pin")][0]; // 2
|
uint16_t length = elm[F("len")];
|
||||||
|
if (length==0) continue;
|
||||||
strip.setColorOrder(hw_led_ins_0[F("order")]);
|
uint8_t colorOrder = (int)elm[F("order")];
|
||||||
//bool hw_led_ins_0_rev = hw_led_ins_0[F("rev")]; // false
|
//only use skip from the first strip (this shouldn't have been in ins obj. but remains here for compatibility)
|
||||||
skipFirstLed = hw_led_ins_0[F("skip")]; // 0
|
if (s==0) skipFirstLed = elm[F("skip")];
|
||||||
useRGBW = (hw_led_ins_0[F("type")] == TYPE_SK6812_RGBW);
|
uint16_t start = elm[F("start")] | 0;
|
||||||
|
if (start >= ledCount) continue;
|
||||||
|
//limit length of strip if it would exceed total configured LEDs
|
||||||
|
if (start + length > ledCount) length = ledCount - start;
|
||||||
|
uint8_t ledType = elm["type"] | TYPE_WS2812_RGB;
|
||||||
|
bool reversed = elm["rev"];
|
||||||
|
//RGBW mode is enabled if at least one of the strips is RGBW
|
||||||
|
useRGBW = (useRGBW || BusManager::isRgbw(ledType));
|
||||||
|
s++;
|
||||||
|
BusConfig bc = BusConfig(ledType, pins, start, length, colorOrder, reversed);
|
||||||
|
mem += busses.memUsage(bc);
|
||||||
|
if (mem <= MAX_LED_MEMORY) busses.add(bc);
|
||||||
|
}
|
||||||
|
strip.finalizeInit(useRGBW, ledCount, skipFirstLed);
|
||||||
|
|
||||||
JsonObject hw_btn_ins_0 = hw[F("btn")][F("ins")][0];
|
JsonObject hw_btn_ins_0 = hw[F("btn")][F("ins")][0];
|
||||||
buttonEnabled = hw_btn_ins_0[F("en")] | buttonEnabled;
|
CJSON(buttonEnabled, hw_btn_ins_0["type"]);
|
||||||
|
int hw_btn_pin = hw_btn_ins_0[F("pin")][0];
|
||||||
//int hw_btn_ins_0_pin_0 = hw_btn_ins_0[F("pin")][0]; // 0
|
if (pinManager.allocatePin(hw_btn_pin,false)) {
|
||||||
|
btnPin = hw_btn_pin;
|
||||||
|
pinMode(btnPin, INPUT_PULLUP);
|
||||||
|
} else {
|
||||||
|
btnPin = -1;
|
||||||
|
}
|
||||||
|
|
||||||
JsonArray hw_btn_ins_0_macros = hw_btn_ins_0[F("macros")];
|
JsonArray hw_btn_ins_0_macros = hw_btn_ins_0[F("macros")];
|
||||||
CJSON(macroButton, hw_btn_ins_0_macros[0]);
|
CJSON(macroButton, hw_btn_ins_0_macros[0]);
|
||||||
CJSON(macroLongPress,hw_btn_ins_0_macros[1]);
|
CJSON(macroLongPress,hw_btn_ins_0_macros[1]);
|
||||||
CJSON(macroDoublePress, hw_btn_ins_0_macros[2]);
|
CJSON(macroDoublePress, hw_btn_ins_0_macros[2]);
|
||||||
|
|
||||||
//int hw_btn_ins_0_type = hw_btn_ins_0[F("type")]; // 0
|
//int hw_btn_ins_0_type = hw_btn_ins_0["type"]; // 0
|
||||||
|
|
||||||
//int hw_ir_pin = hw[F("ir")][F("pin")]; // 4
|
#ifndef WLED_DISABLE_INFRARED
|
||||||
CJSON(irEnabled, hw[F("ir")][F("type")]); // 0
|
int hw_ir_pin = hw["ir"]["pin"]; // 4
|
||||||
|
if (pinManager.allocatePin(hw_ir_pin,false)) {
|
||||||
|
irPin = hw_ir_pin;
|
||||||
|
} else {
|
||||||
|
irPin = -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
CJSON(irEnabled, hw["ir"]["type"]);
|
||||||
|
|
||||||
//int hw_relay_pin = hw[F("relay")][F("pin")]; // 12
|
JsonObject relay = hw[F("relay")];
|
||||||
//bool hw_relay_rev = hw[F("relay")][F("rev")]; // false
|
|
||||||
|
int hw_relay_pin = relay["pin"];
|
||||||
|
if (pinManager.allocatePin(hw_relay_pin,true)) {
|
||||||
|
rlyPin = hw_relay_pin;
|
||||||
|
pinMode(rlyPin, OUTPUT);
|
||||||
|
} else {
|
||||||
|
rlyPin = -1;
|
||||||
|
}
|
||||||
|
if (relay.containsKey("rev")) {
|
||||||
|
rlyMde = !relay["rev"];
|
||||||
|
}
|
||||||
|
|
||||||
//int hw_status_pin = hw[F("status")][F("pin")]; // -1
|
//int hw_status_pin = hw[F("status")][F("pin")]; // -1
|
||||||
|
|
||||||
@ -135,7 +183,7 @@ void deserializeConfig() {
|
|||||||
CJSON(strip.paletteBlend, light[F("pal-mode")]);
|
CJSON(strip.paletteBlend, light[F("pal-mode")]);
|
||||||
|
|
||||||
float light_gc_bri = light[F("gc")]["bri"];
|
float light_gc_bri = light[F("gc")]["bri"];
|
||||||
float light_gc_col = light[F("gc")][F("col")]; // 2.8
|
float light_gc_col = light[F("gc")]["col"]; // 2.8
|
||||||
if (light_gc_bri > 1.5) strip.gammaCorrectBri = true;
|
if (light_gc_bri > 1.5) strip.gammaCorrectBri = true;
|
||||||
else if (light_gc_bri > 0.5) strip.gammaCorrectBri = false;
|
else if (light_gc_bri > 0.5) strip.gammaCorrectBri = false;
|
||||||
if (light_gc_col > 1.5) strip.gammaCorrectCol = true;
|
if (light_gc_col > 1.5) strip.gammaCorrectCol = true;
|
||||||
@ -175,13 +223,13 @@ void deserializeConfig() {
|
|||||||
CJSON(udpPort, if_sync[F("port0")]); // 21324
|
CJSON(udpPort, if_sync[F("port0")]); // 21324
|
||||||
CJSON(udpPort2, if_sync[F("port1")]); // 65506
|
CJSON(udpPort2, if_sync[F("port1")]); // 65506
|
||||||
|
|
||||||
JsonObject if_sync_recv = if_sync[F("recv")];
|
JsonObject if_sync_recv = if_sync["recv"];
|
||||||
CJSON(receiveNotificationBrightness, if_sync_recv["bri"]);
|
CJSON(receiveNotificationBrightness, if_sync_recv["bri"]);
|
||||||
CJSON(receiveNotificationColor, if_sync_recv[F("col")]);
|
CJSON(receiveNotificationColor, if_sync_recv["col"]);
|
||||||
CJSON(receiveNotificationEffects, if_sync_recv[F("fx")]);
|
CJSON(receiveNotificationEffects, if_sync_recv[F("fx")]);
|
||||||
receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects);
|
receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects);
|
||||||
|
|
||||||
JsonObject if_sync_send = if_sync[F("send")];
|
JsonObject if_sync_send = if_sync["send"];
|
||||||
CJSON(notifyDirectDefault, if_sync_send[F("dir")]);
|
CJSON(notifyDirectDefault, if_sync_send[F("dir")]);
|
||||||
notifyDirect = notifyDirectDefault;
|
notifyDirect = notifyDirectDefault;
|
||||||
CJSON(notifyButton, if_sync_send[F("btn")]);
|
CJSON(notifyButton, if_sync_send[F("btn")]);
|
||||||
@ -190,9 +238,13 @@ void deserializeConfig() {
|
|||||||
CJSON(notifyMacro, if_sync_send[F("macro")]);
|
CJSON(notifyMacro, if_sync_send[F("macro")]);
|
||||||
CJSON(notifyTwice, if_sync_send[F("twice")]);
|
CJSON(notifyTwice, if_sync_send[F("twice")]);
|
||||||
|
|
||||||
JsonObject if_live = interfaces[F("live")];
|
JsonObject if_nodes = interfaces["nodes"];
|
||||||
CJSON(receiveDirect, if_live[F("en")]);
|
CJSON(nodeListEnabled, if_nodes[F("list")]);
|
||||||
CJSON(e131Port, if_live[F("port")]); // 5568
|
CJSON(nodeBroadcastEnabled, if_nodes[F("bcast")]);
|
||||||
|
|
||||||
|
JsonObject if_live = interfaces["live"];
|
||||||
|
CJSON(receiveDirect, if_live["en"]);
|
||||||
|
CJSON(e131Port, if_live["port"]); // 5568
|
||||||
CJSON(e131Multicast, if_live[F("mc")]);
|
CJSON(e131Multicast, if_live[F("mc")]);
|
||||||
|
|
||||||
JsonObject if_live_dmx = if_live[F("dmx")];
|
JsonObject if_live_dmx = if_live[F("dmx")];
|
||||||
@ -212,19 +264,19 @@ void deserializeConfig() {
|
|||||||
CJSON(macroAlexaOn, interfaces[F("va")][F("macros")][0]);
|
CJSON(macroAlexaOn, interfaces[F("va")][F("macros")][0]);
|
||||||
CJSON(macroAlexaOff, interfaces[F("va")][F("macros")][1]);
|
CJSON(macroAlexaOff, interfaces[F("va")][F("macros")][1]);
|
||||||
|
|
||||||
const char* apikey = interfaces[F("blynk")][F("token")] | "Hidden";
|
const char* apikey = interfaces["blynk"][F("token")] | "Hidden";
|
||||||
tdd = strnlen(apikey, 36);
|
tdd = strnlen(apikey, 36);
|
||||||
if (tdd > 20 || tdd == 0)
|
if (tdd > 20 || tdd == 0)
|
||||||
getStringFromJson(blynkApiKey, apikey, 36); //normally not present due to security
|
getStringFromJson(blynkApiKey, apikey, 36); //normally not present due to security
|
||||||
|
|
||||||
JsonObject if_blynk = interfaces[F("blynk")];
|
JsonObject if_blynk = interfaces["blynk"];
|
||||||
getStringFromJson(blynkHost, if_blynk[F("host")], 33);
|
getStringFromJson(blynkHost, if_blynk[F("host")], 33);
|
||||||
CJSON(blynkPort, if_blynk[F("port")]);
|
CJSON(blynkPort, if_blynk["port"]);
|
||||||
|
|
||||||
JsonObject if_mqtt = interfaces[F("mqtt")];
|
JsonObject if_mqtt = interfaces["mqtt"];
|
||||||
CJSON(mqttEnabled, if_mqtt[F("en")]);
|
CJSON(mqttEnabled, if_mqtt["en"]);
|
||||||
getStringFromJson(mqttServer, if_mqtt[F("broker")], 33);
|
getStringFromJson(mqttServer, if_mqtt[F("broker")], 33);
|
||||||
CJSON(mqttPort, if_mqtt[F("port")]); // 1883
|
CJSON(mqttPort, if_mqtt["port"]); // 1883
|
||||||
getStringFromJson(mqttUser, if_mqtt[F("user")], 41);
|
getStringFromJson(mqttUser, if_mqtt[F("user")], 41);
|
||||||
getStringFromJson(mqttPass, if_mqtt["psk"], 41); //normally not present due to security
|
getStringFromJson(mqttPass, if_mqtt["psk"], 41); //normally not present due to security
|
||||||
getStringFromJson(mqttClientID, if_mqtt[F("cid")], 41);
|
getStringFromJson(mqttClientID, if_mqtt[F("cid")], 41);
|
||||||
@ -233,23 +285,23 @@ void deserializeConfig() {
|
|||||||
getStringFromJson(mqttGroupTopic, if_mqtt[F("topics")][F("group")], 33); // ""
|
getStringFromJson(mqttGroupTopic, if_mqtt[F("topics")][F("group")], 33); // ""
|
||||||
|
|
||||||
JsonObject if_hue = interfaces[F("hue")];
|
JsonObject if_hue = interfaces[F("hue")];
|
||||||
CJSON(huePollingEnabled, if_hue[F("en")]);
|
CJSON(huePollingEnabled, if_hue["en"]);
|
||||||
CJSON(huePollLightId, if_hue[F("id")]);
|
CJSON(huePollLightId, if_hue["id"]);
|
||||||
tdd = if_hue[F("iv")] | -1;
|
tdd = if_hue[F("iv")] | -1;
|
||||||
if (tdd >= 2) huePollIntervalMs = tdd * 100;
|
if (tdd >= 2) huePollIntervalMs = tdd * 100;
|
||||||
|
|
||||||
JsonObject if_hue_recv = if_hue[F("recv")];
|
JsonObject if_hue_recv = if_hue["recv"];
|
||||||
CJSON(hueApplyOnOff, if_hue_recv["on"]);
|
CJSON(hueApplyOnOff, if_hue_recv["on"]);
|
||||||
CJSON(hueApplyBri, if_hue_recv["bri"]);
|
CJSON(hueApplyBri, if_hue_recv["bri"]);
|
||||||
CJSON(hueApplyColor, if_hue_recv[F("col")]);
|
CJSON(hueApplyColor, if_hue_recv["col"]);
|
||||||
|
|
||||||
JsonArray if_hue_ip = if_hue[F("ip")];
|
JsonArray if_hue_ip = if_hue["ip"];
|
||||||
|
|
||||||
for (byte i = 0; i < 4; i++)
|
for (byte i = 0; i < 4; i++)
|
||||||
CJSON(hueIP[i], if_hue_ip[i]);
|
CJSON(hueIP[i], if_hue_ip[i]);
|
||||||
|
|
||||||
JsonObject if_ntp = interfaces[F("ntp")];
|
JsonObject if_ntp = interfaces[F("ntp")];
|
||||||
CJSON(ntpEnabled, if_ntp[F("en")]);
|
CJSON(ntpEnabled, if_ntp["en"]);
|
||||||
getStringFromJson(ntpServerName, if_ntp[F("host")], 33); // "1.wled.pool.ntp.org"
|
getStringFromJson(ntpServerName, if_ntp[F("host")], 33); // "1.wled.pool.ntp.org"
|
||||||
CJSON(currentTimezone, if_ntp[F("tz")]);
|
CJSON(currentTimezone, if_ntp[F("tz")]);
|
||||||
CJSON(utcOffsetSecs, if_ntp[F("offset")]);
|
CJSON(utcOffsetSecs, if_ntp[F("offset")]);
|
||||||
@ -294,7 +346,7 @@ void deserializeConfig() {
|
|||||||
CJSON(timerWeekday[it], timer[F("dow")]);
|
CJSON(timerWeekday[it], timer[F("dow")]);
|
||||||
if (timerWeekday[it] != dowPrev) { //present in JSON
|
if (timerWeekday[it] != dowPrev) { //present in JSON
|
||||||
timerWeekday[it] <<= 1; //add active bit
|
timerWeekday[it] <<= 1; //add active bit
|
||||||
int act = timer[F("en")] | actPrev;
|
int act = timer["en"] | actPrev;
|
||||||
if (act) timerWeekday[it]++;
|
if (act) timerWeekday[it]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,7 +393,6 @@ void serializeConfig() {
|
|||||||
|
|
||||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||||
|
|
||||||
//{ //scope this to reduce stack size
|
|
||||||
JsonArray rev = doc.createNestedArray("rev");
|
JsonArray rev = doc.createNestedArray("rev");
|
||||||
rev.add(1); //major settings revision
|
rev.add(1); //major settings revision
|
||||||
rev.add(0); //minor settings revision
|
rev.add(0); //minor settings revision
|
||||||
@ -390,7 +441,7 @@ void serializeConfig() {
|
|||||||
|
|
||||||
#ifdef WLED_USE_ETHERNET
|
#ifdef WLED_USE_ETHERNET
|
||||||
JsonObject ethernet = doc.createNestedObject("eth");
|
JsonObject ethernet = doc.createNestedObject("eth");
|
||||||
ethernet[F("type")] = ethernetType;
|
ethernet["type"] = ethernetType;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JsonObject hw = doc.createNestedObject("hw");
|
JsonObject hw = doc.createNestedObject("hw");
|
||||||
@ -399,83 +450,69 @@ void serializeConfig() {
|
|||||||
hw_led[F("total")] = ledCount;
|
hw_led[F("total")] = ledCount;
|
||||||
hw_led[F("maxpwr")] = strip.ablMilliampsMax;
|
hw_led[F("maxpwr")] = strip.ablMilliampsMax;
|
||||||
hw_led[F("ledma")] = strip.milliampsPerLed;
|
hw_led[F("ledma")] = strip.milliampsPerLed;
|
||||||
hw_led[F("rev")] = strip.reverseMode;
|
hw_led["rev"] = strip.reverseMode;
|
||||||
hw_led[F("rgbwm")] = strip.rgbwMode;
|
hw_led[F("rgbwm")] = strip.rgbwMode;
|
||||||
|
|
||||||
JsonArray hw_led_ins = hw_led.createNestedArray("ins");
|
JsonArray hw_led_ins = hw_led.createNestedArray("ins");
|
||||||
|
|
||||||
JsonObject hw_led_ins_0 = hw_led_ins.createNestedObject();
|
for (uint8_t s = 0; s < busses.getNumBusses(); s++) {
|
||||||
hw_led_ins_0[F("en")] = true;
|
Bus *bus = busses.getBus(s);
|
||||||
hw_led_ins_0[F("start")] = 0;
|
if (!bus || bus->getLength()==0) break;
|
||||||
hw_led_ins_0[F("len")] = ledCount;
|
JsonObject ins = hw_led_ins.createNestedObject();
|
||||||
JsonArray hw_led_ins_0_pin = hw_led_ins_0.createNestedArray("pin");
|
ins["en"] = true;
|
||||||
hw_led_ins_0_pin.add(LEDPIN);
|
ins[F("start")] = bus->getStart();
|
||||||
#ifdef DATAPIN
|
ins[F("len")] = bus->getLength();
|
||||||
hw_led_ins_0_pin.add(DATAPIN);
|
JsonArray ins_pin = ins.createNestedArray("pin");
|
||||||
#endif
|
uint8_t pins[5];
|
||||||
hw_led_ins_0[F("order")] = strip.getColorOrder();
|
uint8_t nPins = bus->getPins(pins);
|
||||||
hw_led_ins_0[F("rev")] = false;
|
for (uint8_t i = 0; i < nPins; i++) ins_pin.add(pins[i]);
|
||||||
hw_led_ins_0[F("skip")] = skipFirstLed ? 1 : 0;
|
ins[F("order")] = bus->getColorOrder();
|
||||||
|
ins["rev"] = bus->reversed;
|
||||||
//this is very crude and temporary
|
ins[F("skip")] = (skipFirstLed && s == 0) ? 1 : 0;
|
||||||
byte ledType = TYPE_WS2812_RGB;
|
ins["type"] = bus->getType();
|
||||||
if (useRGBW) ledType = TYPE_SK6812_RGBW;
|
}
|
||||||
#ifdef USE_WS2801
|
|
||||||
ledType = TYPE_WS2801;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_APA102
|
|
||||||
ledType = TYPE_APA102;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_LPD8806
|
|
||||||
ledType = TYPE_LPD8806;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_P9813
|
|
||||||
ledType = TYPE_P9813;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_TM1814
|
|
||||||
ledType = TYPE_TM1814;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
hw_led_ins_0[F("type")] = ledType;
|
|
||||||
|
|
||||||
JsonObject hw_btn = hw.createNestedObject("btn");
|
JsonObject hw_btn = hw.createNestedObject("btn");
|
||||||
|
|
||||||
JsonArray hw_btn_ins = hw_btn.createNestedArray("ins");
|
JsonArray hw_btn_ins = hw_btn.createNestedArray("ins");
|
||||||
|
|
||||||
#if defined(BTNPIN) && BTNPIN > -1
|
// button BTNPIN
|
||||||
JsonObject hw_btn_ins_0 = hw_btn_ins.createNestedObject();
|
JsonObject hw_btn_ins_0 = hw_btn_ins.createNestedObject();
|
||||||
hw_btn_ins_0[F("type")] = (buttonEnabled) ? BTN_TYPE_PUSH : BTN_TYPE_NONE;
|
hw_btn_ins_0["type"] = (buttonEnabled) ? BTN_TYPE_PUSH : BTN_TYPE_NONE;
|
||||||
|
|
||||||
JsonArray hw_btn_ins_0_pin = hw_btn_ins_0.createNestedArray("pin");
|
JsonArray hw_btn_ins_0_pin = hw_btn_ins_0.createNestedArray("pin");
|
||||||
hw_btn_ins_0_pin.add(BTNPIN);
|
hw_btn_ins_0_pin.add(btnPin);
|
||||||
|
|
||||||
JsonArray hw_btn_ins_0_macros = hw_btn_ins_0.createNestedArray("macros");
|
JsonArray hw_btn_ins_0_macros = hw_btn_ins_0.createNestedArray("macros");
|
||||||
hw_btn_ins_0_macros.add(macroButton);
|
hw_btn_ins_0_macros.add(macroButton);
|
||||||
hw_btn_ins_0_macros.add(macroLongPress);
|
hw_btn_ins_0_macros.add(macroLongPress);
|
||||||
hw_btn_ins_0_macros.add(macroDoublePress);
|
hw_btn_ins_0_macros.add(macroDoublePress);
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(IRPIN) && IRPIN > -1
|
#ifndef WLED_DISABLE_INFRARED
|
||||||
|
if (irPin>=0) {
|
||||||
JsonObject hw_ir = hw.createNestedObject("ir");
|
JsonObject hw_ir = hw.createNestedObject("ir");
|
||||||
hw_ir[F("pin")] = IRPIN;
|
hw_ir["pin"] = irPin;
|
||||||
hw_ir[F("type")] = irEnabled; // the byte 'irEnabled' does contain the IR-Remote Type ( 0=disabled )
|
hw_ir[F("type"] = irEnabled; // the byte 'irEnabled' does contain the IR-Remote Type ( 0=disabled )
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(RLYPIN) && RLYPIN > -1
|
JsonObject hw_relay = hw.createNestedObject(F("relay"));
|
||||||
JsonObject hw_relay = hw.createNestedObject("relay");
|
hw_relay["pin"] = rlyPin;
|
||||||
hw_relay[F("pin")] = RLYPIN;
|
hw_relay["rev"] = !rlyMde;
|
||||||
hw_relay[F("rev")] = (RLYMDE) ? false : true;
|
|
||||||
JsonObject hw_status = hw.createNestedObject("status");
|
|
||||||
hw_status[F("pin")] = -1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
JsonObject light = doc.createNestedObject("light");
|
//JsonObject hw_status = hw.createNestedObject("status");
|
||||||
|
//hw_status["pin"] = -1;
|
||||||
|
|
||||||
|
JsonObject hw_aux = hw.createNestedObject("aux");
|
||||||
|
hw_aux["pin"] = auxPin;
|
||||||
|
|
||||||
|
JsonObject light = doc.createNestedObject(F("light"));
|
||||||
light[F("scale-bri")] = briMultiplier;
|
light[F("scale-bri")] = briMultiplier;
|
||||||
light[F("pal-mode")] = strip.paletteBlend;
|
light[F("pal-mode")] = strip.paletteBlend;
|
||||||
|
|
||||||
JsonObject light_gc = light.createNestedObject("gc");
|
JsonObject light_gc = light.createNestedObject("gc");
|
||||||
light_gc["bri"] = (strip.gammaCorrectBri) ? 2.8 : 1.0;
|
light_gc["bri"] = (strip.gammaCorrectBri) ? 2.8 : 1.0;
|
||||||
light_gc[F("col")] = (strip.gammaCorrectCol) ? 2.8 : 1.0;
|
light_gc["col"] = (strip.gammaCorrectCol) ? 2.8 : 1.0;
|
||||||
|
|
||||||
JsonObject light_tr = light.createNestedObject("tr");
|
JsonObject light_tr = light.createNestedObject("tr");
|
||||||
light_tr[F("mode")] = fadeTransition;
|
light_tr[F("mode")] = fadeTransition;
|
||||||
@ -498,7 +535,7 @@ void serializeConfig() {
|
|||||||
JsonObject def_cy = def.createNestedObject("cy");
|
JsonObject def_cy = def.createNestedObject("cy");
|
||||||
def_cy["on"] = presetCyclingEnabled;
|
def_cy["on"] = presetCyclingEnabled;
|
||||||
|
|
||||||
JsonArray def_cy_range = def_cy.createNestedArray("range");
|
JsonArray def_cy_range = def_cy.createNestedArray(F("range"));
|
||||||
def_cy_range.add(presetCycleMin);
|
def_cy_range.add(presetCycleMin);
|
||||||
def_cy_range.add(presetCycleMax);
|
def_cy_range.add(presetCycleMax);
|
||||||
def_cy[F("dur")] = presetCycleTime;
|
def_cy[F("dur")] = presetCycleTime;
|
||||||
@ -512,7 +549,7 @@ void serializeConfig() {
|
|||||||
|
|
||||||
JsonObject if_sync_recv = if_sync.createNestedObject("recv");
|
JsonObject if_sync_recv = if_sync.createNestedObject("recv");
|
||||||
if_sync_recv["bri"] = receiveNotificationBrightness;
|
if_sync_recv["bri"] = receiveNotificationBrightness;
|
||||||
if_sync_recv[F("col")] = receiveNotificationColor;
|
if_sync_recv["col"] = receiveNotificationColor;
|
||||||
if_sync_recv[F("fx")] = receiveNotificationEffects;
|
if_sync_recv[F("fx")] = receiveNotificationEffects;
|
||||||
|
|
||||||
JsonObject if_sync_send = if_sync.createNestedObject("send");
|
JsonObject if_sync_send = if_sync.createNestedObject("send");
|
||||||
@ -523,9 +560,13 @@ void serializeConfig() {
|
|||||||
if_sync_send[F("macro")] = notifyMacro;
|
if_sync_send[F("macro")] = notifyMacro;
|
||||||
if_sync_send[F("twice")] = notifyTwice;
|
if_sync_send[F("twice")] = notifyTwice;
|
||||||
|
|
||||||
|
JsonObject if_nodes = interfaces.createNestedObject("nodes");
|
||||||
|
if_nodes[F("list")] = nodeListEnabled;
|
||||||
|
if_nodes[F("bcast")] = nodeBroadcastEnabled;
|
||||||
|
|
||||||
JsonObject if_live = interfaces.createNestedObject("live");
|
JsonObject if_live = interfaces.createNestedObject("live");
|
||||||
if_live[F("en")] = receiveDirect;
|
if_live["en"] = receiveDirect;
|
||||||
if_live[F("port")] = e131Port;
|
if_live["port"] = e131Port;
|
||||||
if_live[F("mc")] = e131Multicast;
|
if_live[F("mc")] = e131Multicast;
|
||||||
|
|
||||||
JsonObject if_live_dmx = if_live.createNestedObject("dmx");
|
JsonObject if_live_dmx = if_live.createNestedObject("dmx");
|
||||||
@ -547,29 +588,29 @@ void serializeConfig() {
|
|||||||
JsonObject if_blynk = interfaces.createNestedObject("blynk");
|
JsonObject if_blynk = interfaces.createNestedObject("blynk");
|
||||||
if_blynk[F("token")] = strlen(blynkApiKey) ? "Hidden":"";
|
if_blynk[F("token")] = strlen(blynkApiKey) ? "Hidden":"";
|
||||||
if_blynk[F("host")] = blynkHost;
|
if_blynk[F("host")] = blynkHost;
|
||||||
if_blynk[F("port")] = blynkPort;
|
if_blynk["port"] = blynkPort;
|
||||||
|
|
||||||
JsonObject if_mqtt = interfaces.createNestedObject("mqtt");
|
JsonObject if_mqtt = interfaces.createNestedObject("mqtt");
|
||||||
if_mqtt[F("en")] = mqttEnabled;
|
if_mqtt["en"] = mqttEnabled;
|
||||||
if_mqtt[F("broker")] = mqttServer;
|
if_mqtt[F("broker")] = mqttServer;
|
||||||
if_mqtt[F("port")] = mqttPort;
|
if_mqtt["port"] = mqttPort;
|
||||||
if_mqtt[F("user")] = mqttUser;
|
if_mqtt[F("user")] = mqttUser;
|
||||||
if_mqtt[F("pskl")] = strlen(mqttPass);
|
if_mqtt[F("pskl")] = strlen(mqttPass);
|
||||||
if_mqtt[F("cid")] = mqttClientID;
|
if_mqtt[F("cid")] = mqttClientID;
|
||||||
|
|
||||||
JsonObject if_mqtt_topics = if_mqtt.createNestedObject("topics");
|
JsonObject if_mqtt_topics = if_mqtt.createNestedObject(F("topics"));
|
||||||
if_mqtt_topics[F("device")] = mqttDeviceTopic;
|
if_mqtt_topics[F("device")] = mqttDeviceTopic;
|
||||||
if_mqtt_topics[F("group")] = mqttGroupTopic;
|
if_mqtt_topics[F("group")] = mqttGroupTopic;
|
||||||
|
|
||||||
JsonObject if_hue = interfaces.createNestedObject("hue");
|
JsonObject if_hue = interfaces.createNestedObject("hue");
|
||||||
if_hue[F("en")] = huePollingEnabled;
|
if_hue["en"] = huePollingEnabled;
|
||||||
if_hue[F("id")] = huePollLightId;
|
if_hue["id"] = huePollLightId;
|
||||||
if_hue[F("iv")] = huePollIntervalMs / 100;
|
if_hue[F("iv")] = huePollIntervalMs / 100;
|
||||||
|
|
||||||
JsonObject if_hue_recv = if_hue.createNestedObject("recv");
|
JsonObject if_hue_recv = if_hue.createNestedObject("recv");
|
||||||
if_hue_recv["on"] = hueApplyOnOff;
|
if_hue_recv["on"] = hueApplyOnOff;
|
||||||
if_hue_recv["bri"] = hueApplyBri;
|
if_hue_recv["bri"] = hueApplyBri;
|
||||||
if_hue_recv[F("col")] = hueApplyColor;
|
if_hue_recv["col"] = hueApplyColor;
|
||||||
|
|
||||||
JsonArray if_hue_ip = if_hue.createNestedArray("ip");
|
JsonArray if_hue_ip = if_hue.createNestedArray("ip");
|
||||||
for (byte i = 0; i < 4; i++) {
|
for (byte i = 0; i < 4; i++) {
|
||||||
@ -577,7 +618,7 @@ void serializeConfig() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JsonObject if_ntp = interfaces.createNestedObject("ntp");
|
JsonObject if_ntp = interfaces.createNestedObject("ntp");
|
||||||
if_ntp[F("en")] = ntpEnabled;
|
if_ntp["en"] = ntpEnabled;
|
||||||
if_ntp[F("host")] = ntpServerName;
|
if_ntp[F("host")] = ntpServerName;
|
||||||
if_ntp[F("tz")] = currentTimezone;
|
if_ntp[F("tz")] = currentTimezone;
|
||||||
if_ntp[F("offset")] = utcOffsetSecs;
|
if_ntp[F("offset")] = utcOffsetSecs;
|
||||||
@ -593,10 +634,10 @@ void serializeConfig() {
|
|||||||
ol[F("o5m")] = analogClock5MinuteMarks;
|
ol[F("o5m")] = analogClock5MinuteMarks;
|
||||||
ol[F("osec")] = analogClockSecondsTrail;
|
ol[F("osec")] = analogClockSecondsTrail;
|
||||||
|
|
||||||
JsonObject timers = doc.createNestedObject("timers");
|
JsonObject timers = doc.createNestedObject(F("timers"));
|
||||||
|
|
||||||
JsonObject cntdwn = timers.createNestedObject("cntdwn");
|
JsonObject cntdwn = timers.createNestedObject(F("cntdwn"));
|
||||||
JsonArray goal = cntdwn.createNestedArray("goal");
|
JsonArray goal = cntdwn.createNestedArray(F("goal"));
|
||||||
goal.add(countdownYear); goal.add(countdownMonth); goal.add(countdownDay);
|
goal.add(countdownYear); goal.add(countdownMonth); goal.add(countdownDay);
|
||||||
goal.add(countdownHour); goal.add(countdownMin); goal.add(countdownSec);
|
goal.add(countdownHour); goal.add(countdownMin); goal.add(countdownSec);
|
||||||
cntdwn[F("macro")] = macroCountdown;
|
cntdwn[F("macro")] = macroCountdown;
|
||||||
@ -606,7 +647,7 @@ void serializeConfig() {
|
|||||||
for (byte i = 0; i < 8; i++) {
|
for (byte i = 0; i < 8; i++) {
|
||||||
if (timerMacro[i] == 0 && timerHours[i] == 0 && timerMinutes[i] == 0) continue;
|
if (timerMacro[i] == 0 && timerHours[i] == 0 && timerMinutes[i] == 0) continue;
|
||||||
JsonObject timers_ins0 = timers_ins.createNestedObject();
|
JsonObject timers_ins0 = timers_ins.createNestedObject();
|
||||||
timers_ins0[F("en")] = (timerWeekday[i] & 0x01);
|
timers_ins0["en"] = (timerWeekday[i] & 0x01);
|
||||||
timers_ins0[F("hour")] = timerHours[i];
|
timers_ins0[F("hour")] = timerHours[i];
|
||||||
timers_ins0[F("min")] = timerMinutes[i];
|
timers_ins0[F("min")] = timerMinutes[i];
|
||||||
timers_ins0[F("macro")] = timerMacro[i];
|
timers_ins0[F("macro")] = timerMacro[i];
|
||||||
@ -626,7 +667,7 @@ void serializeConfig() {
|
|||||||
dmx[F("start")] = DMXStart;
|
dmx[F("start")] = DMXStart;
|
||||||
dmx[F("start-led")] = DMXStartLED;
|
dmx[F("start-led")] = DMXStartLED;
|
||||||
|
|
||||||
JsonArray dmx_fixmap = dmx.createNestedArray("fixmap");
|
JsonArray dmx_fixmap = dmx.createNestedArray(F("fixmap"));
|
||||||
for (byte i = 0; i < 15; i++)
|
for (byte i = 0; i < 15; i++)
|
||||||
dmx_fixmap.add(DMXFixtureMap[i]);
|
dmx_fixmap.add(DMXFixtureMap[i]);
|
||||||
#endif
|
#endif
|
||||||
@ -652,7 +693,7 @@ bool deserializeConfigSec() {
|
|||||||
JsonObject nw_ins_0 = doc["nw"][F("ins")][0];
|
JsonObject nw_ins_0 = doc["nw"][F("ins")][0];
|
||||||
getStringFromJson(clientPass, nw_ins_0["psk"], 65);
|
getStringFromJson(clientPass, nw_ins_0["psk"], 65);
|
||||||
|
|
||||||
JsonObject ap = doc[F("ap")];
|
JsonObject ap = doc["ap"];
|
||||||
getStringFromJson(apPass, ap["psk"] , 65);
|
getStringFromJson(apPass, ap["psk"] , 65);
|
||||||
|
|
||||||
JsonObject interfaces = doc["if"];
|
JsonObject interfaces = doc["if"];
|
||||||
@ -662,7 +703,7 @@ bool deserializeConfigSec() {
|
|||||||
if (tdd > 20 || tdd == 0)
|
if (tdd > 20 || tdd == 0)
|
||||||
getStringFromJson(blynkApiKey, apikey, 36);
|
getStringFromJson(blynkApiKey, apikey, 36);
|
||||||
|
|
||||||
JsonObject if_mqtt = interfaces[F("mqtt")];
|
JsonObject if_mqtt = interfaces["mqtt"];
|
||||||
getStringFromJson(mqttPass, if_mqtt["psk"], 41);
|
getStringFromJson(mqttPass, if_mqtt["psk"], 41);
|
||||||
|
|
||||||
getStringFromJson(hueApiKey, interfaces[F("hue")][F("key")], 47);
|
getStringFromJson(hueApiKey, interfaces[F("hue")][F("key")], 47);
|
||||||
|
@ -13,6 +13,12 @@
|
|||||||
//increase if you need more
|
//increase if you need more
|
||||||
#define WLED_MAX_USERMODS 4
|
#define WLED_MAX_USERMODS 4
|
||||||
|
|
||||||
|
#ifdef ESP8266
|
||||||
|
#define WLED_MAX_BUSSES 3
|
||||||
|
#else
|
||||||
|
#define WLED_MAX_BUSSES 10
|
||||||
|
#endif
|
||||||
|
|
||||||
//Usermod IDs
|
//Usermod IDs
|
||||||
#define USERMOD_ID_RESERVED 0 //Unused. Might indicate no usermod present
|
#define USERMOD_ID_RESERVED 0 //Unused. Might indicate no usermod present
|
||||||
#define USERMOD_ID_UNSPECIFIED 1 //Default value for a general user mod that does not specify a custom ID
|
#define USERMOD_ID_UNSPECIFIED 1 //Default value for a general user mod that does not specify a custom ID
|
||||||
@ -95,6 +101,7 @@
|
|||||||
#define TYPE_GS8608 23 //same driver as WS2812, but will require signal 2x per second (else displays test pattern)
|
#define TYPE_GS8608 23 //same driver as WS2812, but will require signal 2x per second (else displays test pattern)
|
||||||
#define TYPE_WS2811_400KHZ 24 //half-speed WS2812 protocol, used by very old WS2811 units
|
#define TYPE_WS2811_400KHZ 24 //half-speed WS2812 protocol, used by very old WS2811 units
|
||||||
#define TYPE_SK6812_RGBW 30
|
#define TYPE_SK6812_RGBW 30
|
||||||
|
#define TYPE_TM1814 31
|
||||||
//"Analog" types (PWM) (32-47)
|
//"Analog" types (PWM) (32-47)
|
||||||
#define TYPE_ONOFF 40 //binary output (relays etc.)
|
#define TYPE_ONOFF 40 //binary output (relays etc.)
|
||||||
#define TYPE_ANALOG_1CH 41 //single channel PWM. Uses value of brightest RGBW channel
|
#define TYPE_ANALOG_1CH 41 //single channel PWM. Uses value of brightest RGBW channel
|
||||||
@ -107,8 +114,11 @@
|
|||||||
#define TYPE_APA102 51
|
#define TYPE_APA102 51
|
||||||
#define TYPE_LPD8806 52
|
#define TYPE_LPD8806 52
|
||||||
#define TYPE_P9813 53
|
#define TYPE_P9813 53
|
||||||
#define TYPE_TM1814 54
|
|
||||||
|
|
||||||
|
#define IS_DIGITAL(t) (t & 0x10) //digital are 16-31 and 48-63
|
||||||
|
#define IS_PWM(t) (t > 40 && t < 46)
|
||||||
|
#define NUM_PWM_PINS(t) (t - 40) //for analog PWM 41-45 only
|
||||||
|
#define IS_2PIN(t) (t > 47)
|
||||||
|
|
||||||
//Color orders
|
//Color orders
|
||||||
#define COL_ORDER_GRB 0 //GRB(w),defaut
|
#define COL_ORDER_GRB 0 //GRB(w),defaut
|
||||||
@ -128,10 +138,13 @@
|
|||||||
#define BTN_TYPE_SWITCH_ACT_HIGH 5 //not implemented
|
#define BTN_TYPE_SWITCH_ACT_HIGH 5 //not implemented
|
||||||
|
|
||||||
//Ethernet board types
|
//Ethernet board types
|
||||||
|
#define WLED_NUM_ETH_TYPES 5
|
||||||
|
|
||||||
#define WLED_ETH_NONE 0
|
#define WLED_ETH_NONE 0
|
||||||
#define WLED_ETH_WT32_ETH01 1
|
#define WLED_ETH_WT32_ETH01 1
|
||||||
#define WLED_ETH_ESP32_POE 2
|
#define WLED_ETH_ESP32_POE 2
|
||||||
#define WLED_ETH_WESP32 3
|
#define WLED_ETH_WESP32 3
|
||||||
|
#define WLED_ETH_QUINLED 4
|
||||||
|
|
||||||
//Hue error codes
|
//Hue error codes
|
||||||
#define HUE_ERROR_INACTIVE 0
|
#define HUE_ERROR_INACTIVE 0
|
||||||
@ -159,6 +172,9 @@
|
|||||||
#define ERR_FS_QUOTA 11 // The FS is full or the maximum file size is reached
|
#define ERR_FS_QUOTA 11 // The FS is full or the maximum file size is reached
|
||||||
#define ERR_FS_PLOAD 12 // It was attempted to load a preset that does not exist
|
#define ERR_FS_PLOAD 12 // It was attempted to load a preset that does not exist
|
||||||
#define ERR_FS_GENERAL 19 // A general unspecified filesystem error occured
|
#define ERR_FS_GENERAL 19 // A general unspecified filesystem error occured
|
||||||
|
#define ERR_OVERTEMP 30 // An attached temperature sensor has measured above threshold temperature (not implemented)
|
||||||
|
#define ERR_OVERCURRENT 31 // An attached current sensor has measured a current above the threshold (not implemented)
|
||||||
|
#define ERR_UNDERVOLT 32 // An attached voltmeter has measured a voltage below the threshold (not implemented)
|
||||||
|
|
||||||
//Timer mode types
|
//Timer mode types
|
||||||
#define NL_MODE_SET 0 //After nightlight time elapsed, set to target brightness
|
#define NL_MODE_SET 0 //After nightlight time elapsed, set to target brightness
|
||||||
@ -171,18 +187,40 @@
|
|||||||
|
|
||||||
// maximum number of LEDs - more than 1500 LEDs (or 500 DMA "LEDPIN 3" driven ones) will cause a low memory condition on ESP8266
|
// maximum number of LEDs - more than 1500 LEDs (or 500 DMA "LEDPIN 3" driven ones) will cause a low memory condition on ESP8266
|
||||||
#ifndef MAX_LEDS
|
#ifndef MAX_LEDS
|
||||||
#define MAX_LEDS 1500
|
#ifdef ESP8266
|
||||||
|
#define MAX_LEDS 8192 //rely on memory limit to limit this to 1600 LEDs
|
||||||
|
#else
|
||||||
|
#define MAX_LEDS 8192
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_LEDS_DMA 500
|
#ifndef MAX_LED_MEMORY
|
||||||
|
#ifdef ESP8266
|
||||||
|
#define MAX_LED_MEMORY 5000
|
||||||
|
#else
|
||||||
|
#define MAX_LED_MEMORY 64000
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAX_LEDS_PER_BUS
|
||||||
|
#define MAX_LEDS_PER_BUS 4096
|
||||||
|
#endif
|
||||||
|
|
||||||
// string temp buffer (now stored in stack locally)
|
// string temp buffer (now stored in stack locally)
|
||||||
#define OMAX 2048
|
#define OMAX 2048
|
||||||
|
|
||||||
#define E131_MAX_UNIVERSE_COUNT 9
|
#define E131_MAX_UNIVERSE_COUNT 9
|
||||||
|
|
||||||
#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
|
||||||
|
|
||||||
|
// PWM settings
|
||||||
|
#ifndef WLED_PWM_FREQ
|
||||||
|
#ifdef ESP8266
|
||||||
|
#define WLED_PWM_FREQ 880 //PWM frequency proven as good for LEDs
|
||||||
|
#else
|
||||||
|
#define WLED_PWM_FREQ 19531
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#define TOUCH_THRESHOLD 32 // limit to recognize a touch, higher value means more sensitive
|
#define TOUCH_THRESHOLD 32 // limit to recognize a touch, higher value means more sensitive
|
||||||
|
|
||||||
@ -193,4 +231,24 @@
|
|||||||
#define JSON_BUFFER_SIZE 16384
|
#define JSON_BUFFER_SIZE 16384
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Maximum size of node map (list of other WLED instances)
|
||||||
|
#ifdef ESP8266
|
||||||
|
#define WLED_MAX_NODES 15
|
||||||
|
#else
|
||||||
|
#define WLED_MAX_NODES 150
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//this is merely a default now and can be changed at runtime
|
||||||
|
#ifndef LEDPIN
|
||||||
|
#define LEDPIN 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WLED_ENABLE_DMX
|
||||||
|
#if (LEDPIN == 2)
|
||||||
|
#undef LEDPIN
|
||||||
|
#define LEDPIN 3
|
||||||
|
#warning "Pin conflict compiling with DMX and LEDs on pin 2. The default LED pin has been changed to pin 3."
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -90,9 +90,10 @@ button {
|
|||||||
|
|
||||||
#namelabel {
|
#namelabel {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: calc(var(--bh) + 5px);
|
bottom: calc(var(--bh) + 6px);
|
||||||
right: 4px;
|
right: 4px;
|
||||||
color: var(--c-6);
|
color: var(--c-6);
|
||||||
|
cursor: pointer;
|
||||||
writing-mode: vertical-rl;
|
writing-mode: vertical-rl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,6 +166,14 @@ button {
|
|||||||
color: var(--c-d);
|
color: var(--c-d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-cancel-icon {
|
||||||
|
position: absolute;
|
||||||
|
right: 8px;
|
||||||
|
top: 9px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.flr {
|
.flr {
|
||||||
float: right;
|
float: right;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -298,7 +307,7 @@ button {
|
|||||||
top: -1px;
|
top: -1px;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
margin-top: 1px;
|
margin-top: 1px;
|
||||||
width: 274px;
|
width: 272px;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
border-radius: 25px;
|
border-radius: 25px;
|
||||||
}
|
}
|
||||||
@ -307,10 +316,6 @@ button {
|
|||||||
top: 28px;
|
top: 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#staytop2 {
|
|
||||||
top: 56px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#fxb0 {
|
#fxb0 {
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
filter: drop-shadow(0 0 1px #000);
|
filter: drop-shadow(0 0 1px #000);
|
||||||
@ -366,10 +371,18 @@ button {
|
|||||||
z-index: 3;
|
z-index: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
#rover {
|
#rover, #nodes {
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ndlt {
|
||||||
|
margin: 12px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.valtd i {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
#roverstar {
|
#roverstar {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: calc(var(--th) + 5px);
|
top: calc(var(--th) + 5px);
|
||||||
@ -394,11 +407,15 @@ button {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
#kv {
|
#kv, #kn {
|
||||||
max-width: 490px;
|
max-width: 490px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#kn td {
|
||||||
|
padding-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
#lv {
|
#lv {
|
||||||
max-width: 600px;
|
max-width: 600px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@ -535,6 +552,7 @@ input[type=range]:active + .sliderbubble {
|
|||||||
font-size: 19px;
|
font-size: 19px;
|
||||||
background-color: var(--c-3);
|
background-color: var(--c-3);
|
||||||
color: var(--c-f);
|
color: var(--c-f);
|
||||||
|
cursor: pointer;
|
||||||
border: 0px solid white;
|
border: 0px solid white;
|
||||||
border-radius: 25px;
|
border-radius: 25px;
|
||||||
transition-duration: 0.5s;
|
transition-duration: 0.5s;
|
||||||
@ -751,7 +769,7 @@ input[type=number]::-webkit-outer-spin-button {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.check {
|
.check, .radio {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-bottom: 32px;
|
padding-bottom: 32px;
|
||||||
@ -761,7 +779,7 @@ input[type=number]::-webkit-outer-spin-button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.schkl {
|
.schkl {
|
||||||
padding: 2px 22px 0px 35px;
|
padding: 2px 5px 0px 35px;
|
||||||
margin: 0 0 0 2px;
|
margin: 0 0 0 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -771,7 +789,13 @@ input[type=number]::-webkit-outer-spin-button {
|
|||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.check input {
|
.fxchkl {
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.check input, .radio input {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -779,7 +803,7 @@ input[type=number]::-webkit-outer-spin-button {
|
|||||||
width: 0;
|
width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkmark {
|
.checkmark, .radiomark {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
@ -789,6 +813,13 @@ input[type=number]::-webkit-outer-spin-button {
|
|||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.radiomark {
|
||||||
|
height: 24px;
|
||||||
|
width: 24px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
.schk {
|
.schk {
|
||||||
top: 0;
|
top: 0;
|
||||||
}
|
}
|
||||||
@ -815,13 +846,13 @@ input[type=number]::-webkit-outer-spin-button {
|
|||||||
background-color: var(--c-6);
|
background-color: var(--c-6);
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkmark:after {
|
.checkmark:after, .radiomark:after {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.check input:checked ~ .checkmark:after {
|
.check input:checked ~ .checkmark:after, .radio input:checked ~ .radiomark:after {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -837,6 +868,16 @@ input[type=number]::-webkit-outer-spin-button {
|
|||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.radio .radiomark:after {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
margin: -6px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: var(--c-f);
|
||||||
|
}
|
||||||
|
|
||||||
.h {
|
.h {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@ -863,6 +904,92 @@ input[type=number]::-webkit-outer-spin-button {
|
|||||||
filter: brightness(1);
|
filter: brightness(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.list {
|
||||||
|
position: relative;
|
||||||
|
transition: background-color 0.5s;
|
||||||
|
margin: auto auto 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
width: 230px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lstI {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fxbtn {
|
||||||
|
margin: 20px auto;
|
||||||
|
padding: 8px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lstI:hover {
|
||||||
|
background: var(--c-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.lstI:last-child {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lstI.sticky, .lstI.selected {
|
||||||
|
position: sticky;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#selectPalette .lstI.selected {
|
||||||
|
top: 27px;
|
||||||
|
bottom: -11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#selectPalette .lstI.sticky {
|
||||||
|
top: -11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lstI.selected {
|
||||||
|
background: var(--c-5);
|
||||||
|
top: 95px;
|
||||||
|
bottom: -11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lstI.sticky {
|
||||||
|
top: 57px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lstIname {
|
||||||
|
margin: 3px 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 19px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lstIprev {
|
||||||
|
width: 100%;
|
||||||
|
height: 5px;
|
||||||
|
margin: auto;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0px;
|
||||||
|
left: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"].search {
|
||||||
|
display: block;
|
||||||
|
width: 230px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 8px 8px 9px 38px;
|
||||||
|
margin: 6px auto 0 auto;
|
||||||
|
text-align: left;
|
||||||
|
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' stroke='white'><ellipse fill-opacity='0' stroke-width='10' cx='35' cy='35' id='svg_1' rx='25' ry='25' /><line stroke-width='10' x1='48.5' y1='70.75' x2='92.5' y2='70.75' transform='rotate(45, 70.5, 70.75)' /></svg>")
|
||||||
|
no-repeat 10px 10px;
|
||||||
|
background-size: 20px;
|
||||||
|
background-color: var(--c-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"].search:focus {
|
||||||
|
background-color: var(--c-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"].search:not(:placeholder-shown) {
|
||||||
|
background-color: var(--c-5);
|
||||||
|
}
|
||||||
|
|
||||||
.pres {
|
.pres {
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
<button id="buttonSync" onclick="toggleSync()"><i class="icons"></i><p class="tab-label">Sync</p></button>
|
<button id="buttonSync" onclick="toggleSync()"><i class="icons"></i><p class="tab-label">Sync</p></button>
|
||||||
<button id="buttonSr" onclick="toggleLiveview()"><i class="icons"></i><p class="tab-label">Peek</p></button>
|
<button id="buttonSr" onclick="toggleLiveview()"><i class="icons"></i><p class="tab-label">Peek</p></button>
|
||||||
<button id="buttonI" onclick="toggleInfo()"><i class="icons"></i><p class="tab-label">Info</p></button>
|
<button id="buttonI" onclick="toggleInfo()"><i class="icons"></i><p class="tab-label">Info</p></button>
|
||||||
|
<button id="buttonNodes" onclick="toggleNodes()"><i class="icons"></i><p class="tab-label">Nodes</p></button></div>
|
||||||
<button onclick="window.location.href = '/settings';"><i class="icons"></i><p class="tab-label">Config</p></button>
|
<button onclick="window.location.href = '/settings';"><i class="icons"></i><p class="tab-label">Config</p></button>
|
||||||
<button id="buttonPcm" onclick="togglePcMode(true)"><i class="icons"></i><p class="tab-label">PC Mode</p></button>
|
<button id="buttonPcm" onclick="togglePcMode(true)"><i class="icons"></i><p class="tab-label">PC Mode</p></button>
|
||||||
</div>
|
</div>
|
||||||
@ -66,17 +67,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="qcs-w">
|
<div id="qcs-w">
|
||||||
<div class="qcs" onclick="pC('#ff0000');" style="background-color:#ff0000;"></div>
|
<div class="qcs" onclick="pC('#ff0000');" title="Red" style="background-color:#ff0000;"></div>
|
||||||
<div class="qcs" onclick="pC('#ffa000');" style="background-color:#ffa000;"></div>
|
<div class="qcs" onclick="pC('#ffa000');" title="Orange" style="background-color:#ffa000;"></div>
|
||||||
<div class="qcs" onclick="pC('#ffc800');" style="background-color:#ffc800;"></div>
|
<div class="qcs" onclick="pC('#ffc800');" title="Yellow" style="background-color:#ffc800;"></div>
|
||||||
<div class="qcs" onclick="pC('#ffe0a0');" style="background-color:#ffe0a0;"></div>
|
<div class="qcs" onclick="pC('#ffe0a0');" title="Warm White" style="background-color:#ffe0a0;"></div>
|
||||||
<div class="qcs" onclick="pC('#ffffff');" style="background-color:#ffffff;"></div>
|
<div class="qcs" onclick="pC('#ffffff');" title="White" style="background-color:#ffffff;"></div>
|
||||||
<div class="qcs qcsb" onclick="pC('#000000');" style="background-color:#000000;"></div><br>
|
<div class="qcs qcsb" onclick="pC('#000000');" title="Black" style="background-color:#000000;"></div><br>
|
||||||
<div class="qcs" onclick="pC('#ff00ff');" style="background-color:#ff00ff;"></div>
|
<div class="qcs" onclick="pC('#ff00ff');" title="Pink" style="background-color:#ff00ff;"></div>
|
||||||
<div class="qcs" onclick="pC('#0000ff');" style="background-color:#0000ff;"></div>
|
<div class="qcs" onclick="pC('#0000ff');" title="Blue" style="background-color:#0000ff;"></div>
|
||||||
<div class="qcs" onclick="pC('#00ffc8');" style="background-color:#00ffc8;"></div>
|
<div class="qcs" onclick="pC('#00ffc8');" title="Cyan" style="background-color:#00ffc8;"></div>
|
||||||
<div class="qcs" onclick="pC('#08ff00');" style="background-color:#08ff00;"></div>
|
<div class="qcs" onclick="pC('#08ff00');" title="Green" style="background-color:#08ff00;"></div>
|
||||||
<div class="qcs" onclick="pC('rnd');" style="background-color:var(--c-3); padding: 4px 8px; transform: translateY(-10px);">R</div>
|
<div class="qcs" onclick="pC('rnd');" title="Random" style="background-color:var(--c-3); padding: 4px 8px; transform: translateY(-10px);">R</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="csl">
|
<div id="csl">
|
||||||
<button class="xxs cl btn" onclick="selectSlot(0);">1</button>
|
<button class="xxs cl btn" onclick="selectSlot(0);">1</button>
|
||||||
@ -87,13 +88,33 @@
|
|||||||
<input id="hexc" type="text" class="noslide" onkeydown="hexEnter(this)" autocomplete="off" maxlength="8" />
|
<input id="hexc" type="text" class="noslide" onkeydown="hexEnter(this)" autocomplete="off" maxlength="8" />
|
||||||
<button id="hexcnf" class="xxs btn" onclick="fromHex();"><i class="icons btna-icon"></i></button>
|
<button id="hexcnf" class="xxs btn" onclick="fromHex();"><i class="icons btna-icon"></i></button>
|
||||||
</div>
|
</div>
|
||||||
<p class="labels">Color palette</p>
|
<p class="labels">
|
||||||
<div class="il">
|
|
||||||
<i class="icons sel-icon" onclick="tglHex()"></i>
|
<i class="icons sel-icon" onclick="tglHex()"></i>
|
||||||
<select class="btn sel" id="selectPalette" onchange="setPalette()">
|
Color palette
|
||||||
<option>Default</option>
|
</p>
|
||||||
<option>Error!</option>
|
<div class="il">
|
||||||
</select>
|
<div id="selectPalette" class="list">
|
||||||
|
<div class="lstI" data-id="0">
|
||||||
|
<label class="check schkl">
|
||||||
|
|
||||||
|
<input type="radio" value="${palettes[i].id}" name="palette" onChange="setPalette()">
|
||||||
|
<span class="checkmark schk"></span>
|
||||||
|
</label>
|
||||||
|
<div class="lstIcontent">
|
||||||
|
<span class="lstIname">
|
||||||
|
Default
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="lstI">
|
||||||
|
<div class="lstIcontent">
|
||||||
|
<span class="lstIname">
|
||||||
|
Loading...
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -117,13 +138,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p class="labels">Effect mode</p>
|
<p class="labels">Effect mode</p>
|
||||||
<div class="staytop" id="staytop2">
|
<div id="fxlist" class="list">
|
||||||
<button class="btn" id="fxb0" onclick="setX(0);">Solid</button>
|
|
||||||
</div>
|
|
||||||
<div id="fxlist">
|
|
||||||
Loading...
|
Loading...
|
||||||
</div>
|
</div>
|
||||||
<br>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="Segments" class="tabcontent">
|
<div id="Segments" class="tabcontent">
|
||||||
@ -169,7 +186,7 @@
|
|||||||
|
|
||||||
<div id="connind"></div>
|
<div id="connind"></div>
|
||||||
<div id="toast"></div>
|
<div id="toast"></div>
|
||||||
<div id="namelabel"></div>
|
<div id="namelabel" onclick="toggleNodes()"></div>
|
||||||
<div id="info" class="modal">
|
<div id="info" class="modal">
|
||||||
<div id="imgw">
|
<div id="imgw">
|
||||||
<img alt="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAggAAACMCAYAAAAZQlGEAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAKLSURBVHhe7dgxjtwwEADBpf//5zUDwklnpzFAnKoSTigNFTT0AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGDcOieX+G5nvNLaznil6f1Nv+/tz3c7+3tmen/Tpu/jbe877c85AQD+EQgAQAgEACAEAgAQAgEACIEAAIRAAABCIAAAIRAAgBAIAEAIBAAgBAIAEAIBAAiBAACEQAAAQiAAACEQAIAQCABACAQAINY5+aHvdsYRazvjK9jfM7fvz/0+Y3+/2+336w8CABACAQAIgQAAhEAAAEIgAAAhEACAEAgAQAgEACAEAgAQAgEACIEAAIRAAABCIAAAIRAAgBAIAEAIBAAgBAIAEAIBAAiBAADEOudrfLczXmltZ3yF6fuwv2em9+d+n5ne3zT3cZfp+/AHAQAIgQAAhEAAAEIgAAAhEACAEAgAQAgEACAEAgAQAgEACIEAAIRAAABCIAAAIRAAgBAIAEAIBAAgBAIAEAIBAAiBAACEQAAAYp3zNb7bGUes7Yz8wO334fmeuf35bmd/z9y+v9ufzx8EACAEAgAQAgEACIEAAIRAAABCIAAAIRAAgBAIAEAIBAAgBAIAEAIBAAiBAACEQAAAQiAAACEQAIAQCABACAQAIAQCABACAQCIdc4x3+2MV1rbGfmFpr+/6e/l9ue73fT+pt1+H2/bn+/lGX8QAIAQCABACAQAIAQCABACAQAIgQAAhEAAAEIgAAAhEACAEAgAQAgEACAEAgAQAgEACIEAAIRAAABCIAAAIRAAgBAIAEAIBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgP/u8/kLYCqAxINTyZkAAAAASUVORK5CYII=">
|
<img alt="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAggAAACMCAYAAAAZQlGEAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAKLSURBVHhe7dgxjtwwEADBpf//5zUDwklnpzFAnKoSTigNFTT0AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGDcOieX+G5nvNLaznil6f1Nv+/tz3c7+3tmen/Tpu/jbe877c85AQD+EQgAQAgEACAEAgAQAgEACIEAAIRAAABCIAAAIRAAgBAIAEAIBAAgBAIAEAIBAAiBAACEQAAAQiAAACEQAIAQCABACAQAINY5+aHvdsYRazvjK9jfM7fvz/0+Y3+/2+336w8CABACAQAIgQAAhEAAAEIgAAAhEACAEAgAQAgEACAEAgAQAgEACIEAAIRAAABCIAAAIRAAgBAIAEAIBAAgBAIAEAIBAAiBAADEOudrfLczXmltZ3yF6fuwv2em9+d+n5ne3zT3cZfp+/AHAQAIgQAAhEAAAEIgAAAhEACAEAgAQAgEACAEAgAQAgEACIEAAIRAAABCIAAAIRAAgBAIAEAIBAAgBAIAEAIBAAiBAACEQAAAYp3zNb7bGUes7Yz8wO334fmeuf35bmd/z9y+v9ufzx8EACAEAgAQAgEACIEAAIRAAABCIAAAIRAAgBAIAEAIBAAgBAIAEAIBAAiBAACEQAAAQiAAACEQAIAQCABACAQAIAQCABACAQCIdc4x3+2MV1rbGfmFpr+/6e/l9ue73fT+pt1+H2/bn+/lGX8QAIAQCABACAQAIAQCABACAQAIgQAAhEAAAEIgAAAhEACAEAgAQAgEACAEAgAQAgEACIEAAIRAAABCIAAAIRAAgBAIAEAIBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgP/u8/kLYCqAxINTyZkAAAAASUVORK5CYII=">
|
||||||
@ -177,11 +194,18 @@
|
|||||||
<div id="kv">Loading...</div><br>
|
<div id="kv">Loading...</div><br>
|
||||||
<button class="btn infobtn" onclick="requestJson(null)">Refresh</button>
|
<button class="btn infobtn" onclick="requestJson(null)">Refresh</button>
|
||||||
<button class="btn infobtn" onclick="toggleInfo()">Close Info</button><br>
|
<button class="btn infobtn" onclick="toggleInfo()">Close Info</button><br>
|
||||||
<button class="btn infobtn" onclick="openGH()">WLED Wiki</button>
|
<button class="btn infobtn" onclick="toggleNodes()">Instance List</button>
|
||||||
<button class="btn infobtn" id="resetbtn" onclick="cnfReset()">Reboot WLED</button><br>
|
<button class="btn infobtn" id="resetbtn" onclick="cnfReset()">Reboot WLED</button><br>
|
||||||
<span class="h">Made with <span id="heart">❤︎</span> by Aircoookie and the WLED community</span>
|
<span class="h">Made with <span id="heart">❤︎</span> by Aircoookie and the WLED community</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="nodes" class="modal">
|
||||||
|
<div id="ndlt">WLED instances</div>
|
||||||
|
<div id="kn">Loading...</div><br>
|
||||||
|
<button class="btn infobtn" onclick="loadNodes()">Refresh</button>
|
||||||
|
<button class="btn infobtn" onclick="toggleNodes()">Close list</button><br>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="rover" class="modal">
|
<div id="rover" class="modal">
|
||||||
<i class="icons huge"></i><br>
|
<i class="icons huge"></i><br>
|
||||||
<div id="lv">?</div><br><br>
|
<div id="lv">?</div><br><br>
|
||||||
@ -191,6 +215,7 @@
|
|||||||
<button class="btn" onclick="setLor(2)">Override until reboot</button><br>
|
<button class="btn" onclick="setLor(2)">Override until reboot</button><br>
|
||||||
<span class="h">For best performance, it is recommended to turn off the streaming source when not in use.</span>
|
<span class="h">For best performance, it is recommended to turn off the streaming source when not in use.</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<i id="roverstar" class="icons huge" onclick="setLor(0)"></i><br>
|
<i id="roverstar" class="icons huge" onclick="setLor(0)"></i><br>
|
||||||
<script src="iro.js"></script>
|
<script src="iro.js"></script>
|
||||||
<script src="rangetouch.js"></script>
|
<script src="rangetouch.js"></script>
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
//page js
|
//page js
|
||||||
var loc = false, locip;
|
var loc = false, locip;
|
||||||
var noNewSegs = false;
|
var noNewSegs = false;
|
||||||
var isOn = false, nlA = false, isLv = false, isInfo = false, syncSend = false, syncTglRecv = true, isRgbw = false;
|
var isOn = false, nlA = false, isLv = false, isInfo = false, isNodes = false, syncSend = false, syncTglRecv = true, isRgbw = false;
|
||||||
var whites = [0,0,0];
|
var whites = [0,0,0];
|
||||||
|
var selColors;
|
||||||
var expanded = [false];
|
var expanded = [false];
|
||||||
var powered = [true];
|
var powered = [true];
|
||||||
var nlDur = 60, nlTar = 0;
|
var nlDur = 60, nlTar = 0;
|
||||||
@ -15,6 +16,7 @@ var segCount = 0, ledCount = 0, lowestUnused = 0, maxSeg = 0, lSeg = 0;
|
|||||||
var pcMode = false, pcModeA = false, lastw = 0;
|
var pcMode = false, pcModeA = false, lastw = 0;
|
||||||
var d = document;
|
var d = document;
|
||||||
const ranges = RangeTouch.setup('input[type="range"]', {});
|
const ranges = RangeTouch.setup('input[type="range"]', {});
|
||||||
|
var palettesData;
|
||||||
var pJson = {};
|
var pJson = {};
|
||||||
var pN = "", pI = 0;
|
var pN = "", pI = 0;
|
||||||
var pmt = 1, pmtLS = 0, pmtLast = 0;
|
var pmt = 1, pmtLS = 0, pmtLast = 0;
|
||||||
@ -51,7 +53,7 @@ var cpick = new iro.ColorPicker("#picker", {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function handleVisibilityChange() {
|
function handleVisibilityChange() {
|
||||||
if (!document.hidden && new Date () - lastUpdate > 3000) {
|
if (!d.hidden && new Date () - lastUpdate > 3000) {
|
||||||
requestJson(null);
|
requestJson(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -148,8 +150,8 @@ function cTheme(light) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadBg(iUrl) {
|
function loadBg(iUrl) {
|
||||||
let bg = document.getElementById('bg');
|
let bg = d.getElementById('bg');
|
||||||
let img = document.createElement("img");
|
let img = d.createElement("img");
|
||||||
img.src = iUrl;
|
img.src = iUrl;
|
||||||
if (iUrl == "") {
|
if (iUrl == "") {
|
||||||
var today = new Date();
|
var today = new Date();
|
||||||
@ -157,7 +159,6 @@ function loadBg(iUrl) {
|
|||||||
}
|
}
|
||||||
img.addEventListener('load', (event) => {
|
img.addEventListener('load', (event) => {
|
||||||
var a = parseFloat(cfg.theme.alpha.bg);
|
var a = parseFloat(cfg.theme.alpha.bg);
|
||||||
d.getElementById('staytop2').style.background = "transparent";
|
|
||||||
if (isNaN(a)) a = 0.6;
|
if (isNaN(a)) a = 0.6;
|
||||||
bg.style.opacity = a;
|
bg.style.opacity = a;
|
||||||
bg.style.backgroundImage = `url(${img.src})`;
|
bg.style.backgroundImage = `url(${img.src})`;
|
||||||
@ -305,12 +306,11 @@ function qlName(i) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function cpBck() {
|
function cpBck() {
|
||||||
var copyText = document.getElementById("bck");
|
var copyText = d.getElementById("bck");
|
||||||
|
|
||||||
copyText.select();
|
copyText.select();
|
||||||
copyText.setSelectionRange(0, 999999);
|
copyText.setSelectionRange(0, 999999);
|
||||||
|
d.execCommand("copy");
|
||||||
document.execCommand("copy");
|
|
||||||
|
|
||||||
showToast("Copied to clipboard!");
|
showToast("Copied to clipboard!");
|
||||||
}
|
}
|
||||||
@ -463,8 +463,9 @@ function populateInfo(i)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var vcn = "Kuuhaku";
|
var vcn = "Kuuhaku";
|
||||||
if (i.ver.startsWith("0.11.")) vcn = "Mirai";
|
if (i.ver.startsWith("0.12.")) vcn = "Hikari";
|
||||||
if (i.cn) vcn = i.cn;
|
if (i.cn) vcn = i.cn;
|
||||||
|
|
||||||
cn += `v${i.ver} "${vcn}"<br><br><table class="infot">
|
cn += `v${i.ver} "${vcn}"<br><br><table class="infot">
|
||||||
@ -474,6 +475,7 @@ function populateInfo(i)
|
|||||||
${inforow("Uptime",getRuntimeStr(i.uptime))}
|
${inforow("Uptime",getRuntimeStr(i.uptime))}
|
||||||
${inforow("Free heap",heap," kB")}
|
${inforow("Free heap",heap," kB")}
|
||||||
${inforow("Estimated current",pwru)}
|
${inforow("Estimated current",pwru)}
|
||||||
|
${inforow("Frames / second",i.leds.fps)}
|
||||||
${inforow("MAC address",i.mac)}
|
${inforow("MAC address",i.mac)}
|
||||||
${inforow("Filesystem",i.fs.u + "/" + i.fs.t + " kB (" +Math.round(i.fs.u*100/i.fs.t) + "%)")}
|
${inforow("Filesystem",i.fs.u + "/" + i.fs.t + " kB (" +Math.round(i.fs.u*100/i.fs.t) + "%)")}
|
||||||
${inforow("Environment",i.arch + " " + i.core + " (" + i.lwip + ")")}
|
${inforow("Environment",i.arch + " " + i.core + " (" + i.lwip + ")")}
|
||||||
@ -565,6 +567,214 @@ function populateSegments(s)
|
|||||||
d.getElementById('rsbtn').style.display = (segCount > 1) ? "inline":"none";
|
d.getElementById('rsbtn').style.display = (segCount > 1) ? "inline":"none";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function populateEffects(effects)
|
||||||
|
{
|
||||||
|
var html = `<div class="searchbar"><input type="text" class="search" placeholder="Search" oninput="search(this)" />
|
||||||
|
<i class="icons search-cancel-icon" onclick="cancelSearch(this)"></i></div>`;
|
||||||
|
|
||||||
|
effects.shift(); //remove solid
|
||||||
|
for (let i = 0; i < effects.length; i++) {
|
||||||
|
effects[i] = {id: parseInt(i)+1, name:effects[i]};
|
||||||
|
}
|
||||||
|
effects.sort(compare);
|
||||||
|
|
||||||
|
effects.unshift({
|
||||||
|
"id": 0,
|
||||||
|
"name": "Solid",
|
||||||
|
"class": "sticky"
|
||||||
|
});
|
||||||
|
|
||||||
|
for (let i = 0; i < effects.length; i++) {
|
||||||
|
html += generateListItemHtml(
|
||||||
|
'fx',
|
||||||
|
effects[i].id,
|
||||||
|
effects[i].name,
|
||||||
|
'setX',
|
||||||
|
'',
|
||||||
|
effects[i].class,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
d.getElementById('fxlist').innerHTML=html;
|
||||||
|
}
|
||||||
|
|
||||||
|
function populatePalettes(palettes)
|
||||||
|
{
|
||||||
|
palettes.shift(); //remove default
|
||||||
|
for (let i = 0; i < palettes.length; i++) {
|
||||||
|
palettes[i] = {
|
||||||
|
"id": parseInt(i)+1,
|
||||||
|
"name": palettes[i]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
palettes.sort(compare);
|
||||||
|
|
||||||
|
palettes.unshift({
|
||||||
|
"id": 0,
|
||||||
|
"name": "Default",
|
||||||
|
"class": "sticky"
|
||||||
|
});
|
||||||
|
|
||||||
|
var html = `<div class="searchbar"><input type="text" class="search" placeholder="Search" oninput="search(this)" />
|
||||||
|
<i class="icons search-cancel-icon" onclick="cancelSearch(this)"></i></div>`;
|
||||||
|
for (let i = 0; i < palettes.length; i++) {
|
||||||
|
let previewCss = genPalPrevCss(palettes[i].id);
|
||||||
|
html += generateListItemHtml(
|
||||||
|
'palette',
|
||||||
|
palettes[i].id,
|
||||||
|
palettes[i].name,
|
||||||
|
'setPalette',
|
||||||
|
`<div class="lstIprev" style="${previewCss}"></div>`,
|
||||||
|
palettes[i].class,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
d.getElementById('selectPalette').innerHTML=html;
|
||||||
|
}
|
||||||
|
|
||||||
|
function redrawPalPrev()
|
||||||
|
{
|
||||||
|
let palettes = d.querySelectorAll('#selectPalette .lstI');
|
||||||
|
for (let i = 0; i < palettes.length; i++) {
|
||||||
|
let id = palettes[i].dataset.id;
|
||||||
|
let lstPrev = palettes[i].querySelector('.lstIprev');
|
||||||
|
if (lstPrev) {
|
||||||
|
lstPrev.style = genPalPrevCss(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function genPalPrevCss(id)
|
||||||
|
{
|
||||||
|
if (!palettesData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var paletteData = palettesData[id];
|
||||||
|
var previewCss = "";
|
||||||
|
|
||||||
|
if (!paletteData) {
|
||||||
|
return 'display: none';
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need at least two colors for a gradient
|
||||||
|
if (paletteData.length == 1) {
|
||||||
|
paletteData[1] = paletteData[0];
|
||||||
|
if (Array.isArray(paletteData[1])) {
|
||||||
|
paletteData[1][0] = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var gradient = [];
|
||||||
|
for (let j = 0; j < paletteData.length; j++) {
|
||||||
|
const element = paletteData[j];
|
||||||
|
let r;
|
||||||
|
let g;
|
||||||
|
let b;
|
||||||
|
let index = false;
|
||||||
|
if (Array.isArray(element)) {
|
||||||
|
index = element[0]/255*100;
|
||||||
|
r = element[1];
|
||||||
|
g = element[2];
|
||||||
|
b = element[3];
|
||||||
|
} else if (element == 'r') {
|
||||||
|
r = Math.random() * 255;
|
||||||
|
g = Math.random() * 255;
|
||||||
|
b = Math.random() * 255;
|
||||||
|
} else {
|
||||||
|
if (selColors) {
|
||||||
|
let pos = element[1] - 1;
|
||||||
|
r = selColors[pos][0];
|
||||||
|
g = selColors[pos][1];
|
||||||
|
b = selColors[pos][2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (index === false) {
|
||||||
|
index = j / paletteData.length * 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
gradient.push(`rgb(${r},${g},${b}) ${index}%`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return `background: linear-gradient(to right,${gradient.join()});`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateListItemHtml(listName, id, name, clickAction, extraHtml = '', extraClass = '')
|
||||||
|
{
|
||||||
|
return `<div class="lstI btn fxbtn ${extraClass}" data-id="${id}" onClick="${clickAction}(${id})">
|
||||||
|
<label class="radio fxchkl">
|
||||||
|
<input type="radio" value="${id}" name="${listName}">
|
||||||
|
<span class="radiomark"></span>
|
||||||
|
</label>
|
||||||
|
<span class="lstIname">
|
||||||
|
${name}
|
||||||
|
</span>
|
||||||
|
${extraHtml}
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function btype(b){
|
||||||
|
switch (b) {
|
||||||
|
case 32: return "ESP32";
|
||||||
|
case 82: return "ESP8266";
|
||||||
|
}
|
||||||
|
return "?";
|
||||||
|
}
|
||||||
|
function bname(o){
|
||||||
|
if (o.name=="WLED") return o.ip;
|
||||||
|
return o.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
function populateNodes(i,n)
|
||||||
|
{
|
||||||
|
var cn="";
|
||||||
|
var urows="";
|
||||||
|
var nnodes = 0;
|
||||||
|
if (n.nodes) {
|
||||||
|
n.nodes.sort((a,b) => (a.name).localeCompare(b.name));
|
||||||
|
for (var x=0;x<n.nodes.length;x++) {
|
||||||
|
var o = n.nodes[x];
|
||||||
|
if (o.name) {
|
||||||
|
var url = `<button class="btn btna-icon tab" onclick="location.assign('http://${o.ip}');">${bname(o)}</button>`;
|
||||||
|
urows += inforow(url,`${btype(o.type)}<br><i>${o.vid==0?"N/A":o.vid}</i>`);
|
||||||
|
nnodes++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i.ndc < 0) cn += `Instance List is disabled.`;
|
||||||
|
else if (nnodes == 0) cn += `No other instances found.`;
|
||||||
|
cn += `<table class="infot">
|
||||||
|
${urows}
|
||||||
|
${inforow("Current instance:",i.name)}
|
||||||
|
</table>`;
|
||||||
|
d.getElementById('kn').innerHTML = cn;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadNodes()
|
||||||
|
{
|
||||||
|
var url = '/json/nodes';
|
||||||
|
if (loc) {
|
||||||
|
url = `http://${locip}/json/nodes`;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch
|
||||||
|
(url, {
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (!res.ok) {
|
||||||
|
showToast('Could not load Node list!', true);
|
||||||
|
}
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then(json => {
|
||||||
|
populateNodes(lastinfo, json);
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
showToast(error, true);
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function updateTrail(e, slidercol)
|
function updateTrail(e, slidercol)
|
||||||
{
|
{
|
||||||
if (e==null) return;
|
if (e==null) return;
|
||||||
@ -646,15 +856,12 @@ function updateUI()
|
|||||||
d.getElementById('buttonNl').className = (nlA) ? "active":"";
|
d.getElementById('buttonNl').className = (nlA) ? "active":"";
|
||||||
d.getElementById('buttonSync').className = (syncSend) ? "active":"";
|
d.getElementById('buttonSync').className = (syncSend) ? "active":"";
|
||||||
|
|
||||||
d.getElementById('fxb' + selectedFx).style.backgroundColor = "var(--c-6)";
|
|
||||||
updateTrail(d.getElementById('sliderBri'));
|
updateTrail(d.getElementById('sliderBri'));
|
||||||
updateTrail(d.getElementById('sliderSpeed'));
|
updateTrail(d.getElementById('sliderSpeed'));
|
||||||
updateTrail(d.getElementById('sliderIntensity'));
|
updateTrail(d.getElementById('sliderIntensity'));
|
||||||
updateTrail(d.getElementById('sliderW'));
|
updateTrail(d.getElementById('sliderW'));
|
||||||
if (isRgbw) d.getElementById('wwrap').style.display = "block";
|
if (isRgbw) d.getElementById('wwrap').style.display = "block";
|
||||||
|
|
||||||
var spal = d.getElementById("selectPalette");
|
|
||||||
spal.style.backgroundColor = (spal.selectedIndex > 0) ? "var(--c-6)":"var(--c-3)";
|
|
||||||
updatePA();
|
updatePA();
|
||||||
updateHex();
|
updateHex();
|
||||||
updateRgb();
|
updateRgb();
|
||||||
@ -718,53 +925,63 @@ function requestJson(command, rinfo = true, verbose = true) {
|
|||||||
jsonTimeout = null;
|
jsonTimeout = null;
|
||||||
clearErrorToast();
|
clearErrorToast();
|
||||||
d.getElementById('connind').style.backgroundColor = "#070";
|
d.getElementById('connind').style.backgroundColor = "#070";
|
||||||
if (!json) showToast('Empty response', true);
|
if (!json) {
|
||||||
if (json.success) return;
|
showToast('Empty response', true);
|
||||||
|
}
|
||||||
|
if (json.success) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
var s = json;
|
var s = json;
|
||||||
|
|
||||||
if (!command || rinfo) {
|
if (!command || rinfo) {
|
||||||
if (!rinfo) {
|
if (!rinfo) {
|
||||||
pmt = json.info.fs.pmt;
|
pmt = json.info.fs.pmt;
|
||||||
if (pmt != pmtLS || pmt == 0) {
|
if (pmt != pmtLS || pmt == 0) {
|
||||||
setTimeout(loadPresets,99);
|
setTimeout(loadPresets,99);
|
||||||
}
|
}
|
||||||
else populatePresets(true);
|
else {
|
||||||
|
populatePresets(true);
|
||||||
|
}
|
||||||
pmtLast = pmt;
|
pmtLast = pmt;
|
||||||
var x='',y='<option value="0">Default</option>';
|
|
||||||
json.effects.shift(); //remove solid
|
|
||||||
for (let i = 0; i < json.effects.length; i++) json.effects[i] = {id: parseInt(i)+1, name:json.effects[i]};
|
|
||||||
json.effects.sort(compare);
|
|
||||||
for (let i = 0; i < json.effects.length; i++) {
|
|
||||||
x += `<button class="btn${(i==0)?" first":""}" id="fxb${json.effects[i].id}" onclick="setX(${json.effects[i].id});">${json.effects[i].name}</button><br>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
json.palettes.shift(); //remove default
|
populateEffects(json.effects);
|
||||||
for (let i = 0; i < json.palettes.length; i++) json.palettes[i] = {"id": parseInt(i)+1, "name":json.palettes[i]};
|
populatePalettes(json.palettes);
|
||||||
json.palettes.sort(compare);
|
|
||||||
for (let i = 0; i < json.palettes.length; i++) {
|
|
||||||
y += `<option value="${json.palettes[i].id}">${json.palettes[i].name}</option>`;
|
|
||||||
}
|
|
||||||
e1.innerHTML=x; e2.innerHTML=y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var info = json.info;
|
var info = json.info;
|
||||||
var name = info.name;
|
var name = info.name;
|
||||||
d.getElementById('namelabel').innerHTML = name;
|
d.getElementById('namelabel').innerHTML = name;
|
||||||
if (name === "Dinnerbone") d.documentElement.style.transform = "rotate(180deg)";
|
if (name === "Dinnerbone") {
|
||||||
if (info.live) name = "(Live) " + name;
|
d.documentElement.style.transform = "rotate(180deg)";
|
||||||
if (loc) name = "(L) " + name;
|
}
|
||||||
|
if (info.live) {
|
||||||
|
name = "(Live) " + name;
|
||||||
|
}
|
||||||
|
if (loc) {
|
||||||
|
name = "(L) " + name;
|
||||||
|
}
|
||||||
d.title = name;
|
d.title = name;
|
||||||
isRgbw = info.leds.wv;
|
isRgbw = info.leds.wv;
|
||||||
ledCount = info.leds.count;
|
ledCount = info.leds.count;
|
||||||
syncTglRecv = info.str;
|
syncTglRecv = info.str;
|
||||||
maxSeg = info.leds.maxseg;
|
maxSeg = info.leds.maxseg;
|
||||||
pmt = info.fs.pmt;
|
pmt = info.fs.pmt;
|
||||||
if (!command && pmt != pmtLast) setTimeout(loadPresets,99);
|
|
||||||
|
if (!command && pmt != pmtLast) {
|
||||||
|
setTimeout(loadPresets,99);
|
||||||
|
}
|
||||||
pmtLast = pmt;
|
pmtLast = pmt;
|
||||||
|
d.getElementById('buttonNodes').style.display = (info.ndc > 0 && window.innerWidth > 770) ? "block":"none";
|
||||||
lastinfo = info;
|
lastinfo = info;
|
||||||
if (isInfo) populateInfo(info);
|
if (isInfo) {
|
||||||
|
populateInfo(info);
|
||||||
|
}
|
||||||
s = json.state;
|
s = json.state;
|
||||||
displayRover(info, s);
|
displayRover(info, s);
|
||||||
|
|
||||||
|
if (!rinfo) loadPalettesData();
|
||||||
}
|
}
|
||||||
|
|
||||||
isOn = s.on;
|
isOn = s.on;
|
||||||
d.getElementById('sliderBri').value= s.bri;
|
d.getElementById('sliderBri').value= s.bri;
|
||||||
nlA = s.nl.on;
|
nlA = s.nl.on;
|
||||||
@ -773,7 +990,7 @@ function requestJson(command, rinfo = true, verbose = true) {
|
|||||||
nlFade = s.nl.fade;
|
nlFade = s.nl.fade;
|
||||||
syncSend = s.udpn.send;
|
syncSend = s.udpn.send;
|
||||||
currentPreset = s.ps;
|
currentPreset = s.ps;
|
||||||
d.getElementById('cyToggle').checked = (s.pl < 0) ? false : true;
|
d.getElementById('cyToggle').checked = (s.pl >= 0);
|
||||||
d.getElementById('cycs').value = s.ccnf.min;
|
d.getElementById('cycs').value = s.ccnf.min;
|
||||||
d.getElementById('cyce').value = s.ccnf.max;
|
d.getElementById('cyce').value = s.ccnf.max;
|
||||||
d.getElementById('cyct').value = s.ccnf.time /10;
|
d.getElementById('cyct').value = s.ccnf.time /10;
|
||||||
@ -791,6 +1008,8 @@ function requestJson(command, rinfo = true, verbose = true) {
|
|||||||
updateUI();
|
updateUI();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selColors = i.col;
|
||||||
var cd = d.getElementById('csl').children;
|
var cd = d.getElementById('csl').children;
|
||||||
for (let e = 2; e >= 0; e--)
|
for (let e = 2; e >= 0; e--)
|
||||||
{
|
{
|
||||||
@ -803,18 +1022,46 @@ function requestJson(command, rinfo = true, verbose = true) {
|
|||||||
d.getElementById('sliderSpeed').value = i.sx;
|
d.getElementById('sliderSpeed').value = i.sx;
|
||||||
d.getElementById('sliderIntensity').value = i.ix;
|
d.getElementById('sliderIntensity').value = i.ix;
|
||||||
|
|
||||||
d.getElementById('fxb' + selectedFx).style.backgroundColor = "var(--c-3)";
|
// Effects
|
||||||
|
e1.querySelector(`input[name="fx"][value="${i.fx}"]`).checked = true;
|
||||||
|
var selElement = e1.querySelector('.selected');
|
||||||
|
if (selElement) {
|
||||||
|
selElement.classList.remove('selected')
|
||||||
|
}
|
||||||
|
var selectedEffect = e1.querySelector(`.lstI[data-id="${i.fx}"]`);
|
||||||
|
selectedEffect.classList.add('selected');
|
||||||
selectedFx = i.fx;
|
selectedFx = i.fx;
|
||||||
e2.value = i.pal;
|
|
||||||
if (!command) d.getElementById('Effects').scrollTop = d.getElementById('fxb' + selectedFx).offsetTop - d.getElementById('Effects').clientHeight/1.8;
|
// Palettes
|
||||||
|
e2.querySelector(`input[name="palette"][value="${i.pal}"]`).checked = true;
|
||||||
|
selElement = e2.querySelector('.selected');
|
||||||
|
if (selElement) {
|
||||||
|
selElement.classList.remove('selected')
|
||||||
|
}
|
||||||
|
e2.querySelector(`.lstI[data-id="${i.pal}"]`).classList.add('selected');
|
||||||
|
|
||||||
|
if (!command) {
|
||||||
|
selectedEffect.scrollIntoView({
|
||||||
|
behavior: 'smooth',
|
||||||
|
block: 'nearest',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (s.error && s.error != 0) {
|
if (s.error && s.error != 0) {
|
||||||
var errstr = "";
|
var errstr = "";
|
||||||
switch (s.error) {
|
switch (s.error) {
|
||||||
case 10: errstr = "Could not mount filesystem!"; break;
|
case 10:
|
||||||
case 11: errstr = "Not enough space to save preset!"; break;
|
errstr = "Could not mount filesystem!";
|
||||||
case 12: errstr = "The requested preset does not exist."; break;
|
break;
|
||||||
case 19: errstr = "A filesystem error has occured."; break;
|
case 11:
|
||||||
|
errstr = "Not enough space to save preset!";
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
errstr = "The requested preset does not exist.";
|
||||||
|
break;
|
||||||
|
case 19:
|
||||||
|
errstr = "A filesystem error has occured.";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
showToast('Error ' + s.error + ": " + errstr, true);
|
showToast('Error ' + s.error + ": " + errstr, true);
|
||||||
}
|
}
|
||||||
@ -868,12 +1115,21 @@ function toggleLiveview() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function toggleInfo() {
|
function toggleInfo() {
|
||||||
|
if (isNodes) toggleNodes();
|
||||||
isInfo = !isInfo;
|
isInfo = !isInfo;
|
||||||
if (isInfo) populateInfo(lastinfo);
|
if (isInfo) populateInfo(lastinfo);
|
||||||
d.getElementById('info').style.transform = (isInfo) ? "translateY(0px)":"translateY(100%)";
|
d.getElementById('info').style.transform = (isInfo) ? "translateY(0px)":"translateY(100%)";
|
||||||
d.getElementById('buttonI').className = (isInfo) ? "active":"";
|
d.getElementById('buttonI').className = (isInfo) ? "active":"";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleNodes() {
|
||||||
|
if (isInfo) toggleInfo();
|
||||||
|
isNodes = !isNodes;
|
||||||
|
d.getElementById('nodes').style.transform = (isNodes) ? "translateY(0px)":"translateY(100%)";
|
||||||
|
d.getElementById('buttonNodes').className = (isNodes) ? "active":"";
|
||||||
|
if (isNodes) loadNodes();
|
||||||
|
}
|
||||||
|
|
||||||
function makeSeg() {
|
function makeSeg() {
|
||||||
var ns = 0;
|
var ns = 0;
|
||||||
if (lowestUnused > 0) {
|
if (lowestUnused > 0) {
|
||||||
@ -1029,14 +1285,35 @@ function setSegBri(s){
|
|||||||
requestJson(obj);
|
requestJson(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setX(ind) {
|
function setX(ind = null) {
|
||||||
|
if (ind === null) {
|
||||||
|
ind = parseInt(d.querySelector('#fxlist input[name="fx"]:checked').value);
|
||||||
|
} else {
|
||||||
|
d.querySelector(`#fxlist input[name="fx"][value="${ind}`).checked = true;
|
||||||
|
}
|
||||||
|
var selElement = d.querySelector('#fxlist .selected');
|
||||||
|
if (selElement) {
|
||||||
|
selElement.classList.remove('selected')
|
||||||
|
}
|
||||||
|
d.querySelector(`#fxlist .lstI[data-id="${ind}"]`).classList.add('selected');
|
||||||
|
|
||||||
var obj = {"seg": {"fx": parseInt(ind)}};
|
var obj = {"seg": {"fx": parseInt(ind)}};
|
||||||
requestJson(obj);
|
requestJson(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setPalette()
|
function setPalette(paletteId = null)
|
||||||
{
|
{
|
||||||
var obj = {"seg": {"pal": parseInt(d.getElementById('selectPalette').value)}};
|
if (paletteId === null) {
|
||||||
|
paletteId = parseInt(d.querySelector('#selectPalette input[name="palette"]:checked').value);
|
||||||
|
} else {
|
||||||
|
d.querySelector(`#selectPalette input[name="palette"][value="${paletteId}`).checked = true;
|
||||||
|
}
|
||||||
|
var selElement = d.querySelector('#selectPalette .selected');
|
||||||
|
if (selElement) {
|
||||||
|
selElement.classList.remove('selected')
|
||||||
|
}
|
||||||
|
d.querySelector(`#selectPalette .lstI[data-id="${paletteId}"]`).classList.add('selected');
|
||||||
|
var obj = {"seg": {"pal": paletteId}};
|
||||||
requestJson(obj);
|
requestJson(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1152,6 +1429,7 @@ function selectSlot(b) {
|
|||||||
updateTrail(d.getElementById('sliderW'));
|
updateTrail(d.getElementById('sliderW'));
|
||||||
updateHex();
|
updateHex();
|
||||||
updateRgb();
|
updateRgb();
|
||||||
|
redrawPalPrev();
|
||||||
}
|
}
|
||||||
|
|
||||||
var lasth = 0;
|
var lasth = 0;
|
||||||
@ -1278,6 +1556,88 @@ function rSegs()
|
|||||||
requestJson(obj);
|
requestJson(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadPalettesData()
|
||||||
|
{
|
||||||
|
if (palettesData) return;
|
||||||
|
const lsKey = "wledPalx";
|
||||||
|
var palettesDataJson = localStorage.getItem(lsKey);
|
||||||
|
if (palettesDataJson) {
|
||||||
|
try {
|
||||||
|
palettesDataJson = JSON.parse(palettesDataJson);
|
||||||
|
var d = new Date();
|
||||||
|
if (palettesDataJson && palettesDataJson.vid == lastinfo.vid) {
|
||||||
|
palettesData = palettesDataJson.p;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
palettesData = {};
|
||||||
|
getPalettesData(0, function() {
|
||||||
|
localStorage.setItem(lsKey, JSON.stringify({
|
||||||
|
p: palettesData,
|
||||||
|
vid: lastinfo.vid
|
||||||
|
}));
|
||||||
|
redrawPalPrev();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPalettesData(page, callback)
|
||||||
|
{
|
||||||
|
var url = `/json/palx?page=${page}`;
|
||||||
|
if (loc) {
|
||||||
|
url = `http://${locip}${url}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch(url, {
|
||||||
|
method: 'get',
|
||||||
|
headers: {
|
||||||
|
"Content-type": "application/json; charset=UTF-8"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (!res.ok) {
|
||||||
|
showErrorToast();
|
||||||
|
}
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then(json => {
|
||||||
|
palettesData = Object.assign({}, palettesData, json.p);
|
||||||
|
if (page < json.m) {
|
||||||
|
getPalettesData(page + 1, callback);
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
showToast(error, true);
|
||||||
|
console.log(error);
|
||||||
|
presetError(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function search(searchField) {
|
||||||
|
var searchText = searchField.value.toUpperCase();
|
||||||
|
searchField.parentElement.getElementsByClassName('search-cancel-icon')[0].style.display = (searchText.length < 1)?"none":"inline";
|
||||||
|
var elements = searchField.parentElement.parentElement.querySelectorAll('.lstI');
|
||||||
|
for (i = 0; i < elements.length; i++) {
|
||||||
|
var item = elements[i];
|
||||||
|
var itemText = item.querySelector('.lstIname').innerText.toUpperCase();
|
||||||
|
if (itemText.indexOf(searchText) > -1) {
|
||||||
|
item.style.display = "";
|
||||||
|
} else {
|
||||||
|
item.style.display = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelSearch(ic) {
|
||||||
|
var searchField = ic.parentElement.getElementsByClassName('search')[0];
|
||||||
|
searchField.value = "";
|
||||||
|
search(searchField);
|
||||||
|
searchField.focus();
|
||||||
|
}
|
||||||
|
|
||||||
function expand(i,a)
|
function expand(i,a)
|
||||||
{
|
{
|
||||||
if (!a) expanded[i] = !expanded[i];
|
if (!a) expanded[i] = !expanded[i];
|
||||||
@ -1303,7 +1663,7 @@ function unfocusSliders() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//sliding UI
|
//sliding UI
|
||||||
const _C = document.querySelector('.container'), N = 4;
|
const _C = d.querySelector('.container'), N = 4;
|
||||||
|
|
||||||
let iSlide = 0, x0 = null, scrollS = 0, locked = false, w;
|
let iSlide = 0, x0 = null, scrollS = 0, locked = false, w;
|
||||||
|
|
||||||
@ -1354,6 +1714,7 @@ function move(e) {
|
|||||||
|
|
||||||
function size() {
|
function size() {
|
||||||
w = window.innerWidth;
|
w = window.innerWidth;
|
||||||
|
d.getElementById('buttonNodes').style.display = (lastinfo.ndc > 0 && w > 770) ? "block":"none";
|
||||||
var h = d.getElementById('top').clientHeight;
|
var h = d.getElementById('top').clientHeight;
|
||||||
sCol('--th', h + "px");
|
sCol('--th', h + "px");
|
||||||
sCol('--bh', d.getElementById('bot').clientHeight + "px");
|
sCol('--bh', d.getElementById('bot').clientHeight + "px");
|
||||||
|
62
wled00/data/liveviewws.htm
Normal file
62
wled00/data/liveviewws.htm
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="theme-color" content="#222222">
|
||||||
|
<title>WLED Live Preview</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
#canv {
|
||||||
|
background: black;
|
||||||
|
filter: brightness(175%);
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="canv" />
|
||||||
|
<script>
|
||||||
|
console.info("Live-Preview websocket opening");
|
||||||
|
var socket = new WebSocket("ws://"+document.location.host+"/ws");
|
||||||
|
|
||||||
|
socket.onopen = function () {
|
||||||
|
console.info("Live-Preview websocket is opened");
|
||||||
|
socket.send("{'lv':true}");
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.onclose = function () { console.info("Live-Preview websocket is closing"); }
|
||||||
|
|
||||||
|
socket.onerror = function (event) { console.error("Live-Preview websocket error:", event); }
|
||||||
|
|
||||||
|
function updatePreview(leds) {
|
||||||
|
var str = "linear-gradient(90deg,";
|
||||||
|
var len = leds.length;
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
var leddata = leds[i];
|
||||||
|
if (leddata.length > 6) leddata = leddata.substring(2);
|
||||||
|
str += "#" + leddata;
|
||||||
|
if (i < len -1) str += ","
|
||||||
|
}
|
||||||
|
str += ")";
|
||||||
|
document.getElementById("canv").style.background = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.onmessage = function (event) {
|
||||||
|
try {
|
||||||
|
var json = JSON.parse(event.data);
|
||||||
|
if (json && json.leds) {
|
||||||
|
requestAnimationFrame(function () {updatePreview(json.leds);});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.error("Live-Preview websocket error:",err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -5,7 +5,7 @@
|
|||||||
<meta name="viewport" content="width=500">
|
<meta name="viewport" content="width=500">
|
||||||
<title>LED Settings</title>
|
<title>LED Settings</title>
|
||||||
<script>
|
<script>
|
||||||
var d=document,laprev=55;
|
var d=document,laprev=55,maxB=1,maxM=5000,maxPB=4096,bquot=0; //maximum bytes for LED allocation: 5kB for 8266, 32kB for 32
|
||||||
function H()
|
function H()
|
||||||
{
|
{
|
||||||
window.open("https://github.com/Aircoookie/WLED/wiki/Settings#led-settings");
|
window.open("https://github.com/Aircoookie/WLED/wiki/Settings#led-settings");
|
||||||
@ -13,6 +13,30 @@
|
|||||||
function B()
|
function B()
|
||||||
{
|
{
|
||||||
window.open("/settings","_self");
|
window.open("/settings","_self");
|
||||||
|
}
|
||||||
|
function bLimits(b,p,m) {
|
||||||
|
maxB = b; maxM = m; maxPB = p;
|
||||||
|
}
|
||||||
|
function trySubmit() {
|
||||||
|
var LCs = d.getElementsByTagName("input");
|
||||||
|
for (i=0; i<LCs.length; i++) {
|
||||||
|
var nm = LCs[i].name.substring(0,2);
|
||||||
|
|
||||||
|
//check for pin conflicts
|
||||||
|
if (nm=="L0" || nm=="L1" || nm=="RL" || nm=="BT" || nm=="IR" || nm=="AX")
|
||||||
|
if (LCs[i].value!="" && LCs[i].value!="-1") {
|
||||||
|
if (LCs[i].value > 5 && LCs[i].value < 12) {alert("Sorry, pins 6-11 can not be used.");LCs[i].focus();return;}
|
||||||
|
if (d.um_p && d.um_p.some((e)=>e==parseInt(LCs[i].value,10))) {alert("Usermod pin conflict!");LCs[i].focus();return;}
|
||||||
|
for (j=i+1; j<LCs.length; j++)
|
||||||
|
{
|
||||||
|
var n2 = LCs[j].name.substring(0,2);
|
||||||
|
if (n2=="L0" || n2=="L1" || n2=="RL" || n2=="BT" || n2=="IR" || n2=="AX")
|
||||||
|
if (LCs[j].value!="" && LCs[i].value==LCs[j].value) {alert("Pin conflict!");LCs[i].focus();return;}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bquot > 100) {var msg = "Too many LEDs for me to handle!"; if (maxM < 10000) msg += " Consider using an ESP32."; alert(msg); return;}
|
||||||
|
if (d.Sf.reportValidity()) d.Sf.submit();
|
||||||
}
|
}
|
||||||
function S(){GetV();setABL();}
|
function S(){GetV();setABL();}
|
||||||
function enABL()
|
function enABL()
|
||||||
@ -42,23 +66,97 @@
|
|||||||
case 255: d.Sf.LAsel.value = 255; break;
|
case 255: d.Sf.LAsel.value = 255; break;
|
||||||
default: d.getElementById('LAdis').style.display = 'inline';
|
default: d.getElementById('LAdis').style.display = 'inline';
|
||||||
}
|
}
|
||||||
|
d.getElementById('m1').innerHTML = maxM;
|
||||||
UI();
|
UI();
|
||||||
|
}
|
||||||
|
//returns mem usage
|
||||||
|
function getMem(type, len, p0) {
|
||||||
|
//len = parseInt(len);
|
||||||
|
if (type < 32) {
|
||||||
|
if (maxM < 10000 && p0 ==3) { //8266 DMA uses 5x the mem
|
||||||
|
if (type > 29) return len*20; //RGBW
|
||||||
|
return len*15;
|
||||||
|
} else if (maxM >= 10000) //ESP32 RMT uses double buffer?
|
||||||
|
{
|
||||||
|
if (type > 29) return len*8; //RGBW
|
||||||
|
return len*6;
|
||||||
|
}
|
||||||
|
if (type > 29) return len*4; //RGBW
|
||||||
|
return len*3;
|
||||||
|
}
|
||||||
|
if (type > 31 && type < 48) return 5;
|
||||||
|
if (type == 44 || type == 45) return len*4; //RGBW
|
||||||
|
return len*3;
|
||||||
}
|
}
|
||||||
function UI()
|
function UI()
|
||||||
{
|
{
|
||||||
var myC = d.querySelectorAll('.wc'),
|
var isRGBW = false, memu = 0;
|
||||||
l = myC.length;
|
|
||||||
for (i = 0; i < l; i++) {
|
|
||||||
myC[i].style.display = (d.getElementById('rgbw').checked) ? 'inline':'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
d.getElementById('ledwarning').style.display = (d.Sf.LC.value > 1000) ? 'inline':'none';
|
|
||||||
d.getElementById('ampwarning').style.display = (d.Sf.MA.value > 7200) ? 'inline':'none';
|
d.getElementById('ampwarning').style.display = (d.Sf.MA.value > 7200) ? 'inline':'none';
|
||||||
|
|
||||||
if (d.Sf.LA.value == 255) laprev = 12;
|
if (d.Sf.LA.value == 255) laprev = 12;
|
||||||
else if (d.Sf.LA.value > 0) laprev = d.Sf.LA.value;
|
else if (d.Sf.LA.value > 0) laprev = d.Sf.LA.value;
|
||||||
|
|
||||||
var val = Math.ceil((100 + d.Sf.LC.value * laprev)/500)/2;
|
var s = d.getElementsByTagName("select");
|
||||||
|
for (i=0; i<s.length; i++) {
|
||||||
|
if (s[i].name.substring(0,2)=="LT") {
|
||||||
|
n=s[i].name.substring(2);
|
||||||
|
var type = s[i].value;
|
||||||
|
d.getElementById("p0d"+n).innerHTML = (type > 49) ? "Data pin:" : (type >41) ? "Pins:" : "Pin:";
|
||||||
|
d.getElementById("p1d"+n).innerHTML = (type > 49) ? "Clk:" : "";
|
||||||
|
var LK = d.getElementsByName("L1"+n)[0];
|
||||||
|
|
||||||
|
memu += getMem(type, d.getElementsByName("LC"+n)[0].value, d.getElementsByName("L0"+n)[0].value);
|
||||||
|
|
||||||
|
for (p=1; p<5; p++) {
|
||||||
|
var LK = d.getElementsByName("L"+p+n)[0];
|
||||||
|
if (!LK) continue;
|
||||||
|
if ((type>49 && p==1) || (type>41 && type < 50 && (p+40 < type))) // TYPE_xxxx values from const.h
|
||||||
|
{
|
||||||
|
LK.style.display = "inline";
|
||||||
|
LK.required = true;
|
||||||
|
} else {
|
||||||
|
LK.style.display = "none";
|
||||||
|
LK.required = false;
|
||||||
|
LK.value="";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (type == 30 || type == 31 || (type > 40 && type < 46 && type != 43)) isRGBW = true;
|
||||||
|
d.getElementById("dig"+n).style.display = (type > 31 && type < 48) ? "none":"inline";
|
||||||
|
d.getElementById("psd"+n).innerHTML = (type > 31 && type < 48) ? "Index:":"Start:";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var myC = d.querySelectorAll('.wc'),
|
||||||
|
l = myC.length;
|
||||||
|
for (i = 0; i < l; i++) {
|
||||||
|
myC[i].style.display = (isRGBW) ? 'inline':'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d.activeElement == d.getElementsByName("LC")[0]) {
|
||||||
|
var o = d.getElementsByClassName("iST");
|
||||||
|
var i = o.length;
|
||||||
|
if (i == 1) d.getElementsByName("LC0")[0].value = d.getElementsByName("LC")[0].value;
|
||||||
|
}
|
||||||
|
|
||||||
|
var LCs = d.getElementsByTagName("input");
|
||||||
|
var sLC = 0, maxLC = 0;
|
||||||
|
for (i=0; i<LCs.length; i++) {
|
||||||
|
var nm = LCs[i].name.substring(0,2);
|
||||||
|
if (nm=="LC" && LCs[i].name != "LC") {var c = parseInt(LCs[i].value,10); if (c) {sLC+=c; if (c>maxLC) maxLC = c;} continue;}
|
||||||
|
}
|
||||||
|
|
||||||
|
d.getElementById('m0').innerHTML = memu;
|
||||||
|
bquot = memu / maxM * 100;
|
||||||
|
d.getElementById('dbar').style.background = `linear-gradient(90deg, ${bquot > 60 ? bquot > 90 ? "red":"orange":"#ccc"} 0 ${bquot}%%, #444 ${bquot}%% 100%%)`;
|
||||||
|
d.getElementById('ledwarning').style.display = (maxLC > 800 || bquot > 80) ? 'inline':'none';
|
||||||
|
//TODO add warning "Recommended pins on ESP8266 are 1 and 2 (3 only with low LED count)"
|
||||||
|
//TODO add overmemory warning
|
||||||
|
//TODO block disallowed pins 6-11
|
||||||
|
d.getElementById('wreason').innerHTML = (bquot > 80) ? "than 60%% of max. LED memory" : "800 LEDs per pin";
|
||||||
|
|
||||||
|
//var val = Math.ceil((100 + d.Sf.LC.value * laprev)/500)/2;
|
||||||
|
var val = Math.ceil((100 + sLC * laprev)/500)/2;
|
||||||
val = (val > 5) ? Math.ceil(val) : val;
|
val = (val > 5) ? Math.ceil(val) : val;
|
||||||
var s = "";
|
var s = "";
|
||||||
var is12V = (d.Sf.LAsel.value == 30);
|
var is12V = (d.Sf.LAsel.value == 30);
|
||||||
@ -72,17 +170,84 @@
|
|||||||
s += val;
|
s += val;
|
||||||
s += "A supply connected to LEDs";
|
s += "A supply connected to LEDs";
|
||||||
}
|
}
|
||||||
var val2 = Math.ceil((100 + d.Sf.LC.value * laprev)/1500)/2;
|
var val2 = Math.ceil((100 + sLC * laprev)/1500)/2;
|
||||||
val2 = (val2 > 5) ? Math.ceil(val2) : val2;
|
val2 = (val2 > 5) ? Math.ceil(val2) : val2;
|
||||||
var s2 = "(for most effects, ~";
|
var s2 = "(for most effects, ~";
|
||||||
s2 += val2;
|
s2 += val2;
|
||||||
s2 += "A is enough)<br>";
|
s2 += "A is enough)<br>";
|
||||||
d.getElementById('psu').innerHTML = s;
|
d.getElementById('psu').innerHTML = s;
|
||||||
d.getElementById('psu2').innerHTML = isWS2815 ? "" : s2;
|
d.getElementById('psu2').innerHTML = isWS2815 ? "" : s2;
|
||||||
|
}
|
||||||
|
function lastEnd(i) {
|
||||||
|
if (i<1) return 0;
|
||||||
|
v = parseInt(d.getElementsByName("LS"+(i-1))[0].value) + parseInt(d.getElementsByName("LC"+(i-1))[0].value);
|
||||||
|
if (isNaN(v)) return 0;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
function addLEDs(n)
|
||||||
|
{
|
||||||
|
if (n>1) {maxB=n; d.getElementById("+").style.display="inline"; return;}
|
||||||
|
|
||||||
|
var o = d.getElementsByClassName("iST");
|
||||||
|
var i = o.length;
|
||||||
|
|
||||||
|
if ((n==1 && i>=maxB) || (n==-1 && i==0)) return;
|
||||||
|
|
||||||
|
var f = d.getElementById("mLC");
|
||||||
|
if (n==1) {
|
||||||
|
var cn = `<div class="iST">
|
||||||
|
${i>0?'<hr style="width:260px">':''}
|
||||||
|
${i+1}:
|
||||||
|
<select name="LT${i}" onchange="UI()">
|
||||||
|
<option value="22">WS281x</option>
|
||||||
|
<option value="30">SK6812 RGBW</option>
|
||||||
|
<option value="31">TM1814</option>
|
||||||
|
<option value="24">400kHz</option>
|
||||||
|
<option value="50">WS2801</option>
|
||||||
|
<option value="51">APA102</option>
|
||||||
|
<option value="52">LPD8806</option>
|
||||||
|
<option value="53">P9813</option>
|
||||||
|
<option value="41">PWM White</option>
|
||||||
|
<option value="42">PWM WWCW</option>
|
||||||
|
<option value="43">PWM RGB</option>
|
||||||
|
<option value="44">PWM RGBW</option>
|
||||||
|
<option value="45">PWM RGBWC</option>
|
||||||
|
</select>
|
||||||
|
Color Order:
|
||||||
|
<select name="CO${i}">
|
||||||
|
<option value="0">GRB</option>
|
||||||
|
<option value="1">RGB</option>
|
||||||
|
<option value="2">BRG</option>
|
||||||
|
<option value="3">RBG</option>
|
||||||
|
<option value="4">BGR</option>
|
||||||
|
<option value="5">GBR</option>
|
||||||
|
</select><br>
|
||||||
|
<span id="p0d${i}">Pin:</span> <input type="number" name="L0${i}" min="0" max="40" required style="width:35px" oninput="UI()"/>
|
||||||
|
<span id="p1d${i}">Clock:</span> <input type="number" name="L1${i}" min="0" max="40" style="width:35px"/>
|
||||||
|
<span id="p2d${i}"></span><input type="number" name="L2${i}" min="0" max="40" style="width:35px"/>
|
||||||
|
<span id="p3d${i}"></span><input type="number" name="L3${i}" min="0" max="40" style="width:35px"/>
|
||||||
|
<span id="p4d${i}"></span><input type="number" name="L4${i}" min="0" max="40" style="width:35px"/>
|
||||||
|
<br>
|
||||||
|
<span id="psd${i}">Start:</span> <input type="number" name="LS${i}" min="0" max="8191" value="${lastEnd(i)}" required />
|
||||||
|
<div id="dig${i}" style="display:inline">
|
||||||
|
Count: <input type="number" name="LC${i}" min="0" max="${maxPB}" value="1" required oninput="UI()" /><br>
|
||||||
|
Reverse: <input type="checkbox" name="CV${i}"></div><br>
|
||||||
|
</div>`;
|
||||||
|
f.insertAdjacentHTML("beforeend", cn);
|
||||||
|
}
|
||||||
|
if (n==-1) {
|
||||||
|
o[--i].remove();--i;
|
||||||
|
}
|
||||||
|
|
||||||
|
d.getElementById("+").style.display = (i<maxB-1) ? "inline":"none";
|
||||||
|
d.getElementById("-").style.display = (i>0) ? "inline":"none";
|
||||||
|
|
||||||
|
UI();
|
||||||
}
|
}
|
||||||
function GetV()
|
function GetV()
|
||||||
{
|
{
|
||||||
//values injected by server while sending HTML
|
//values injected by server while sending HTML
|
||||||
|
//d.um_p=[];addLEDs(3);d.Sf.LC.value=250;addLEDs(1);d.Sf.L00.value=2;d.Sf.L10.value=0;d.Sf.LC0.value=250;d.Sf.LT0.value=22;d.Sf.CO0.value=0;d.Sf.LS0.value=0;d.Sf.LS0.checked=0;d.Sf.MA.value=5400;d.Sf.LA.value=55;d.getElementsByClassName("pow")[0].innerHTML="350mA";d.Sf.CA.value=40;d.Sf.AW.value=3;d.Sf.BO.checked=0;d.Sf.BP.value=3;d.Sf.GB.checked=0;d.Sf.GC.checked=1;d.Sf.TF.checked=1;d.Sf.TD.value=700;d.Sf.PF.checked=0;d.Sf.BF.value=64;d.Sf.TB.value=0;d.Sf.TL.value=60;d.Sf.TW.value=1;d.Sf.PB.selectedIndex=0;d.Sf.RV.checked=0;d.Sf.SL.checked=0;d.Sf.RL.value=12;d.Sf.RM.checked=0;d.Sf.BT.value=-1;d.Sf.IR.value=-1;d.Sf.AX.value=-1;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
@ -92,13 +257,9 @@
|
|||||||
<body onload="S()">
|
<body onload="S()">
|
||||||
<form id="form_s" name="Sf" method="post">
|
<form id="form_s" name="Sf" method="post">
|
||||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
<button type="button" onclick="B()">Back</button><button type="button" onclick="trySubmit()">Save</button><hr>
|
||||||
<h2>LED setup</h2>
|
<h2>LED & Hardware setup</h2>
|
||||||
LED count: <input name="LC" type="number" min="1" max="1500" oninput="UI()" required><br>
|
Total LED count: <input name="LC" type="number" min="1" max="8192" oninput="UI()" required><br>
|
||||||
<div id="ledwarning" style="color: orange; display: none;">
|
|
||||||
⚠ You might run into stability or lag issues.<br>
|
|
||||||
Use less than 1000 LEDs per ESP for the best experience!<br>
|
|
||||||
</div>
|
|
||||||
<i>Recommended power supply for brightest white:</i><br>
|
<i>Recommended power supply for brightest white:</i><br>
|
||||||
<b><span id="psu">?</span></b><br>
|
<b><span id="psu">?</span></b><br>
|
||||||
<span id="psu2"><br></span>
|
<span id="psu2"><br></span>
|
||||||
@ -127,27 +288,20 @@
|
|||||||
<span id="LAdis" style="display: none;">Custom max. current per LED: <input name="LA" type="number" min="0" max="255" id="la" oninput="UI()" required> mA<br></span>
|
<span id="LAdis" style="display: none;">Custom max. current per LED: <input name="LA" type="number" min="0" max="255" id="la" oninput="UI()" required> mA<br></span>
|
||||||
<i>Keep at default if you are unsure about your type of LEDs.</i><br>
|
<i>Keep at default if you are unsure about your type of LEDs.</i><br>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<h3>Hardware setup</h3>
|
||||||
LEDs are 4-channel type (RGBW): <input type="checkbox" name="EW" onchange=UI() id="rgbw"><br>
|
<div id="mLC">LED outputs:</div>
|
||||||
<span class="wc">
|
<button type="button" id="+" onclick="addLEDs(1)" style="display:none;border-radius:20px;height:36px;">+</button>
|
||||||
Auto-calculate white channel from RGB:<br>
|
<button type="button" id="-" onclick="addLEDs(-1)" style="display:none;border-radius:20px;width:36px;height:36px;">-</button><br>
|
||||||
<select name=AW>
|
LED Memory Usage: <span id="m0">0</span> / <span id="m1">?</span> B<br>
|
||||||
<option value=0>None</option>
|
<div id="dbar" style="display:inline-block; width: 100px; height: 10px; border-radius: 20px;"></div><br>
|
||||||
<option value=1>Brighter</option>
|
<div id="ledwarning" style="color: orange; display: none;">
|
||||||
<option value=2>Accurate</option>
|
⚠ You might run into stability or lag issues.<br>
|
||||||
<option value=3>Dual</option>
|
Use less than <span id="wreason">800 LEDs per pin</span> for the best experience!<br>
|
||||||
<option value=4>Legacy</option>
|
</div><br>
|
||||||
</select>
|
Relay pin: <input type="number" min="-1" max="40" name="RL" onchange="UI()"> Active high <input type="checkbox" name="RM"><br>
|
||||||
<br></span>
|
Button pin: <input type="number" min="-1" max="40" name="BT" onchange="UI()"><br>
|
||||||
Color order:
|
IR pin: <input type="number" min="-1" max="40" name="IR" onchange="UI()"><br>
|
||||||
<select name="CO">
|
AUX pin: <input type="number" min="-1" max="40" name="AX" onchange="UI()">
|
||||||
<option value=0>GRB</option>
|
|
||||||
<option value=1>RGB</option>
|
|
||||||
<option value=2>BRG</option>
|
|
||||||
<option value=3>RBG</option>
|
|
||||||
<option value=4>BGR</option>
|
|
||||||
<option value=5>GBR</option>
|
|
||||||
</select>
|
|
||||||
<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>
|
||||||
Default brightness: <input name="CA" type="number" min="0" max="255" required> (0-255)<br><br>
|
Default brightness: <input name="CA" type="number" min="0" max="255" required> (0-255)<br><br>
|
||||||
@ -180,8 +334,18 @@
|
|||||||
<option value="3">None (not recommended)</option>
|
<option value="3">None (not recommended)</option>
|
||||||
</select><br>
|
</select><br>
|
||||||
Reverse LED order (rotate 180): <input type="checkbox" name="RV"><br>
|
Reverse LED order (rotate 180): <input type="checkbox" name="RV"><br>
|
||||||
Skip first LED: <input type="checkbox" name="SL"><hr>
|
Skip first LED: <input type="checkbox" name="SL"><br>
|
||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
<span class="wc">
|
||||||
|
Auto-calculate white channel from RGB:<br>
|
||||||
|
<select name="AW">
|
||||||
|
<option value=0>None</option>
|
||||||
|
<option value=1>Brighter</option>
|
||||||
|
<option value=2>Accurate</option>
|
||||||
|
<option value=3>Dual</option>
|
||||||
|
<option value=4>Legacy</option>
|
||||||
|
</select>
|
||||||
|
<br></span><hr>
|
||||||
|
<button type="button" onclick="B()">Back</button><button type="button" onclick="trySubmit()">Save</button>
|
||||||
</form>
|
</form>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -40,6 +40,9 @@ Send Philips Hue change notifications: <input type="checkbox" name="SH"><br>
|
|||||||
Send Macro notifications: <input type="checkbox" name="SM"><br>
|
Send Macro notifications: <input type="checkbox" name="SM"><br>
|
||||||
Send notifications twice: <input type="checkbox" name="S2"><br>
|
Send notifications twice: <input type="checkbox" name="S2"><br>
|
||||||
<i>Reboot required to apply changes. </i>
|
<i>Reboot required to apply changes. </i>
|
||||||
|
<h3>Instance List</h3>
|
||||||
|
Enable instance list: <input type="checkbox" name="NL"><br>
|
||||||
|
Make this instance discoverable: <input type="checkbox" name="NB"><br>
|
||||||
<h3>Realtime</h3>
|
<h3>Realtime</h3>
|
||||||
Receive UDP realtime: <input type="checkbox" name="RD"><br><br>
|
Receive UDP realtime: <input type="checkbox" name="RD"><br><br>
|
||||||
<i>Network DMX input</i><br>
|
<i>Network DMX input</i><br>
|
||||||
|
@ -68,9 +68,11 @@
|
|||||||
<h3>Ethernet Type</h3>
|
<h3>Ethernet Type</h3>
|
||||||
<select name="ETH">
|
<select name="ETH">
|
||||||
<option value="0">None</option>
|
<option value="0">None</option>
|
||||||
<option value="1">WT32-ETH01</option>
|
|
||||||
<option value="2">ESP32-POE</option>
|
<option value="2">ESP32-POE</option>
|
||||||
<option value="3">WESP32</option></select><br><br></div>
|
<option value="4">QuinLED-ESP32</option>
|
||||||
|
<option value="3">WESP32</option>
|
||||||
|
<option value="1">WT32-ETH01</option>
|
||||||
|
</select><br><br></div>
|
||||||
<hr>
|
<hr>
|
||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save & Connect</button>
|
<button type="button" onclick="B()">Back</button><button type="submit">Save & Connect</button>
|
||||||
</form>
|
</form>
|
||||||
|
@ -62,10 +62,6 @@ void initDMX() {
|
|||||||
dmx.init(512); // initialize with bus length
|
dmx.init(512); // initialize with bus length
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (LEDPIN == 2)
|
|
||||||
#pragma message "Pin conflict compiling with DMX and LEDs on pin 2. Please set a different LEDPIN."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
void handleDMX() {}
|
void handleDMX() {}
|
||||||
void initDMX() {}
|
void initDMX() {}
|
||||||
|
@ -35,7 +35,8 @@ void handleDDPPacket(e131_packet_t* p) {
|
|||||||
realtimeLock(realtimeTimeoutMs, REALTIME_MODE_DDP);
|
realtimeLock(realtimeTimeoutMs, REALTIME_MODE_DDP);
|
||||||
|
|
||||||
for (uint16_t i = start; i < stop; i++) {
|
for (uint16_t i = start; i < stop; i++) {
|
||||||
setRealtimePixel(i, data[c++], data[c++], data[c++], 0);
|
setRealtimePixel(i, data[c], data[c+1], data[c+2], 0);
|
||||||
|
c+=3;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool push = p->flags & DDP_PUSH_FLAG;
|
bool push = p->flags & DDP_PUSH_FLAG;
|
||||||
@ -187,11 +188,13 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, byte protocol){
|
|||||||
uint16_t ledsTotal = previousLeds + (dmxChannels - dmxOffset +1) / dmxChannelsPerLed;
|
uint16_t ledsTotal = previousLeds + (dmxChannels - dmxOffset +1) / dmxChannelsPerLed;
|
||||||
if (!is4Chan) {
|
if (!is4Chan) {
|
||||||
for (uint16_t i = previousLeds; i < ledsTotal; i++) {
|
for (uint16_t i = previousLeds; i < ledsTotal; i++) {
|
||||||
setRealtimePixel(i, e131_data[dmxOffset++], e131_data[dmxOffset++], e131_data[dmxOffset++], 0);
|
setRealtimePixel(i, e131_data[dmxOffset], e131_data[dmxOffset+1], e131_data[dmxOffset+2], 0);
|
||||||
|
dmxOffset+=3;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (uint16_t i = previousLeds; i < ledsTotal; i++) {
|
for (uint16_t i = previousLeds; i < ledsTotal; i++) {
|
||||||
setRealtimePixel(i, e131_data[dmxOffset++], e131_data[dmxOffset++], e131_data[dmxOffset++], e131_data[dmxOffset++]);
|
setRealtimePixel(i, e131_data[dmxOffset], e131_data[dmxOffset+1], e131_data[dmxOffset+2], e131_data[dmxOffset+3]);
|
||||||
|
dmxOffset+=4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -76,7 +76,6 @@ bool decodeIRCustom(uint32_t code);
|
|||||||
void applyRepeatActions();
|
void applyRepeatActions();
|
||||||
void relativeChange(byte* property, int8_t amount, byte lowerBoundary = 0, byte higherBoundary = 0xFF);
|
void relativeChange(byte* property, int8_t amount, byte lowerBoundary = 0, byte higherBoundary = 0xFF);
|
||||||
void changeEffectSpeed(int8_t amount);
|
void changeEffectSpeed(int8_t amount);
|
||||||
void changeBrightness(int8_t amount);
|
|
||||||
void changeEffectIntensity(int8_t amount);
|
void changeEffectIntensity(int8_t amount);
|
||||||
void decodeIR(uint32_t code);
|
void decodeIR(uint32_t code);
|
||||||
void decodeIR24(uint32_t code);
|
void decodeIR24(uint32_t code);
|
||||||
@ -149,23 +148,8 @@ void setCronixie();
|
|||||||
void _overlayCronixie();
|
void _overlayCronixie();
|
||||||
void _drawOverlayCronixie();
|
void _drawOverlayCronixie();
|
||||||
|
|
||||||
//pin_manager.cpp
|
|
||||||
class PinManagerClass {
|
|
||||||
private:
|
|
||||||
#ifdef ESP8266
|
|
||||||
uint8_t pinAlloc[3] = {0x00, 0x00, 0x00}; //24bit, 1 bit per pin, we use first 17bits
|
|
||||||
#else
|
|
||||||
uint8_t pinAlloc[5] = {0x00, 0x00, 0x00, 0x00, 0x00}; //40bit, 1 bit per pin, we use all bits
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
|
||||||
void deallocatePin(byte gpio);
|
|
||||||
bool allocatePin(byte gpio, bool output = true);
|
|
||||||
bool isPinAllocated(byte gpio);
|
|
||||||
bool isPinOk(byte gpio, bool output = true);
|
|
||||||
};
|
|
||||||
|
|
||||||
//playlist.cpp
|
//playlist.cpp
|
||||||
|
void unloadPlaylist();
|
||||||
void loadPlaylist(JsonObject playlistObject);
|
void loadPlaylist(JsonObject playlistObject);
|
||||||
void handlePlaylist();
|
void handlePlaylist();
|
||||||
|
|
||||||
@ -187,6 +171,8 @@ void notify(byte callMode, bool followUp=false);
|
|||||||
void realtimeLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC);
|
void realtimeLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC);
|
||||||
void handleNotifications();
|
void handleNotifications();
|
||||||
void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w);
|
void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w);
|
||||||
|
void refreshNodeList();
|
||||||
|
void sendSysInfoUDP();
|
||||||
|
|
||||||
//um_manager.cpp
|
//um_manager.cpp
|
||||||
class Usermod {
|
class Usermod {
|
||||||
|
@ -33,8 +33,10 @@ File f;
|
|||||||
|
|
||||||
//wrapper to find out how long closing takes
|
//wrapper to find out how long closing takes
|
||||||
void closeFile() {
|
void closeFile() {
|
||||||
|
#ifdef WLED_DEBUG_FS
|
||||||
DEBUGFS_PRINT(F("Close -> "));
|
DEBUGFS_PRINT(F("Close -> "));
|
||||||
uint32_t s = millis();
|
uint32_t s = millis();
|
||||||
|
#endif
|
||||||
f.close();
|
f.close();
|
||||||
DEBUGFS_PRINTF("took %d ms\n", millis() - s);
|
DEBUGFS_PRINTF("took %d ms\n", millis() - s);
|
||||||
doCloseFile = false;
|
doCloseFile = false;
|
||||||
@ -53,7 +55,6 @@ bool bufferedFind(const char *target, bool fromStart = true) {
|
|||||||
size_t targetLen = strlen(target);
|
size_t targetLen = strlen(target);
|
||||||
|
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
byte c;
|
|
||||||
uint16_t bufsize = 0, count = 0;
|
uint16_t bufsize = 0, count = 0;
|
||||||
byte buf[FS_BUFSIZE];
|
byte buf[FS_BUFSIZE];
|
||||||
if (fromStart) f.seek(0);
|
if (fromStart) f.seek(0);
|
||||||
|
@ -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.11.1<br>Download the latest binary: <a
|
Installed version: 0.12.0-a0<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" accept=".bin" required><br>
|
</a><br><input type="file" class="bt" name="update" accept=".bin" required><br>
|
||||||
@ -78,6 +78,17 @@ update();var tmout=null;function update(){if(document.hidden)return clearTimeout
|
|||||||
</script></body></html>)=====";
|
</script></body></html>)=====";
|
||||||
|
|
||||||
|
|
||||||
|
// Autogenerated from wled00/data/liveviewws.htm, do not edit!!
|
||||||
|
const char PAGE_liveviewws[] PROGMEM = R"=====(<!DOCTYPE html><html><head><meta name="viewport"
|
||||||
|
content="width=device-width,initial-scale=1,minimum-scale=1"><meta
|
||||||
|
charset="utf-8"><meta name="theme-color" content="#222222"><title>
|
||||||
|
WLED Live Preview</title><style>
|
||||||
|
body{margin:0}#canv{background:#000;filter:brightness(175%);width:100%;height:100%;position:absolute}
|
||||||
|
</style></head><body><div id="canv"><script>
|
||||||
|
console.info("Live-Preview websocket opening");var socket=new WebSocket("ws://"+document.location.host+"/ws");function updatePreview(e){var o="linear-gradient(90deg,",n=e.length;for(i=0;i<n;i++){var t=e[i];t.length>6&&(t=t.substring(2)),o+="#"+t,i<n-1&&(o+=",")}o+=")",document.getElementById("canv").style.background=o}socket.onopen=function(){console.info("Live-Preview websocket is opened"),socket.send("{'lv':true}")},socket.onclose=function(){console.info("Live-Preview websocket is closing")},socket.onerror=function(e){console.error("Live-Preview websocket error:",e)},socket.onmessage=function(e){try{var o=JSON.parse(e.data);o&&o.leds&&requestAnimationFrame((function(){updatePreview(o.leds)}))}catch(e){console.error("Live-Preview websocket error:",e)}}
|
||||||
|
</script></body></html>)=====";
|
||||||
|
|
||||||
|
|
||||||
// Autogenerated from wled00/data/404.htm, do not edit!!
|
// Autogenerated from wled00/data/404.htm, do not edit!!
|
||||||
const char PAGE_404[] PROGMEM = R"=====(<!DOCTYPE html><html><head><meta charset="utf-8"><meta
|
const char PAGE_404[] PROGMEM = R"=====(<!DOCTYPE html><html><head><meta charset="utf-8"><meta
|
||||||
content="width=device-width" name="viewport"><meta name="theme-color"
|
content="width=device-width" name="viewport"><meta name="theme-color"
|
||||||
|
File diff suppressed because one or more lines are too long
4218
wled00/html_ui.h
4218
wled00/html_ui.h
File diff suppressed because it is too large
Load Diff
@ -21,6 +21,54 @@ uint16_t irTimesRepeated = 0;
|
|||||||
uint8_t lastIR6ColourIdx = 0;
|
uint8_t lastIR6ColourIdx = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// brightnessSteps: a static array of brightness levels following a geometric
|
||||||
|
// progression. Can be generated from the following Python, adjusting the
|
||||||
|
// arbitrary 4.5 value to taste:
|
||||||
|
//
|
||||||
|
// def values(level):
|
||||||
|
// while level >= 5:
|
||||||
|
// yield int(level)
|
||||||
|
// level -= level / 4.5
|
||||||
|
// result = [v for v in reversed(list(values(255)))]
|
||||||
|
// print("%d values: %s" % (len(result), result))
|
||||||
|
//
|
||||||
|
// It would be hard to maintain repeatable steps if calculating this on the fly.
|
||||||
|
const byte brightnessSteps[] = {
|
||||||
|
5, 7, 9, 12, 16, 20, 26, 34, 43, 56, 72, 93, 119, 154, 198, 255
|
||||||
|
};
|
||||||
|
const size_t numBrightnessSteps = sizeof(brightnessSteps) / sizeof(uint8_t);
|
||||||
|
|
||||||
|
// increment `bri` to the next `brightnessSteps` value
|
||||||
|
void incBrightness()
|
||||||
|
{
|
||||||
|
// dumb incremental search is efficient enough for so few items
|
||||||
|
for (int index = 0; index < numBrightnessSteps; ++index)
|
||||||
|
{
|
||||||
|
if (brightnessSteps[index] > bri)
|
||||||
|
{
|
||||||
|
bri = brightnessSteps[index];
|
||||||
|
lastRepeatableAction = ACTION_BRIGHT_UP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// decrement `bri` to the next `brightnessSteps` value
|
||||||
|
void decBrightness()
|
||||||
|
{
|
||||||
|
// dumb incremental search is efficient enough for so few items
|
||||||
|
for (int index = numBrightnessSteps - 1; index >= 0; --index)
|
||||||
|
{
|
||||||
|
if (brightnessSteps[index] < bri)
|
||||||
|
{
|
||||||
|
bri = brightnessSteps[index];
|
||||||
|
lastRepeatableAction = ACTION_BRIGHT_DOWN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//Add what your custom IR codes should trigger here. Guide: https://github.com/Aircoookie/WLED/wiki/Infrared-Control
|
//Add what your custom IR codes should trigger here. Guide: https://github.com/Aircoookie/WLED/wiki/Infrared-Control
|
||||||
//IR codes themselves can be defined directly after "case" or in "ir_codes.h"
|
//IR codes themselves can be defined directly after "case" or in "ir_codes.h"
|
||||||
bool decodeIRCustom(uint32_t code)
|
bool decodeIRCustom(uint32_t code)
|
||||||
@ -47,16 +95,6 @@ void relativeChange(byte* property, int8_t amount, byte lowerBoundary, byte high
|
|||||||
*property = (byte)constrain(new_val,0.1,255.1);
|
*property = (byte)constrain(new_val,0.1,255.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void changeBrightness(int8_t amount)
|
|
||||||
{
|
|
||||||
int16_t new_val = bri + amount;
|
|
||||||
if (new_val < 5) new_val = 5; //minimum brightness A=5
|
|
||||||
bri = (byte)constrain(new_val,0.1,255.1);
|
|
||||||
if(amount > 0) lastRepeatableAction = ACTION_BRIGHT_UP;
|
|
||||||
if(amount < 0) lastRepeatableAction = ACTION_BRIGHT_DOWN;
|
|
||||||
lastRepeatableValue = amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
void changeEffectSpeed(int8_t amount)
|
void changeEffectSpeed(int8_t amount)
|
||||||
{
|
{
|
||||||
if (effectCurrent != 0) {
|
if (effectCurrent != 0) {
|
||||||
@ -142,11 +180,11 @@ void applyRepeatActions(){
|
|||||||
|
|
||||||
if (lastRepeatableAction == ACTION_BRIGHT_UP)
|
if (lastRepeatableAction == ACTION_BRIGHT_UP)
|
||||||
{
|
{
|
||||||
changeBrightness(lastRepeatableValue); colorUpdated(NOTIFIER_CALL_MODE_BUTTON);
|
incBrightness(); colorUpdated(NOTIFIER_CALL_MODE_BUTTON);
|
||||||
}
|
}
|
||||||
else if (lastRepeatableAction == ACTION_BRIGHT_DOWN )
|
else if (lastRepeatableAction == ACTION_BRIGHT_DOWN )
|
||||||
{
|
{
|
||||||
changeBrightness(lastRepeatableValue); colorUpdated(NOTIFIER_CALL_MODE_BUTTON);
|
decBrightness(); colorUpdated(NOTIFIER_CALL_MODE_BUTTON);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastRepeatableAction == ACTION_SPEED_UP)
|
if (lastRepeatableAction == ACTION_SPEED_UP)
|
||||||
@ -187,8 +225,8 @@ void applyRepeatActions(){
|
|||||||
void decodeIR24(uint32_t code)
|
void decodeIR24(uint32_t code)
|
||||||
{
|
{
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case IR24_BRIGHTER : changeBrightness(10); break;
|
case IR24_BRIGHTER : incBrightness(); break;
|
||||||
case IR24_DARKER : changeBrightness(-10); break;
|
case IR24_DARKER : decBrightness(); break;
|
||||||
case IR24_OFF : briLast = bri; bri = 0; break;
|
case IR24_OFF : briLast = bri; bri = 0; break;
|
||||||
case IR24_ON : bri = briLast; break;
|
case IR24_ON : bri = briLast; break;
|
||||||
case IR24_RED : colorFromUint32(COLOR_RED); break;
|
case IR24_RED : colorFromUint32(COLOR_RED); break;
|
||||||
@ -219,8 +257,8 @@ void decodeIR24(uint32_t code)
|
|||||||
void decodeIR24OLD(uint32_t code)
|
void decodeIR24OLD(uint32_t code)
|
||||||
{
|
{
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case IR24_OLD_BRIGHTER : changeBrightness(10); break;
|
case IR24_OLD_BRIGHTER : incBrightness(); break;
|
||||||
case IR24_OLD_DARKER : changeBrightness(-10); break;
|
case IR24_OLD_DARKER : decBrightness(); break;
|
||||||
case IR24_OLD_OFF : briLast = bri; bri = 0; break;
|
case IR24_OLD_OFF : briLast = bri; bri = 0; break;
|
||||||
case IR24_OLD_ON : bri = briLast; break;
|
case IR24_OLD_ON : bri = briLast; break;
|
||||||
case IR24_OLD_RED : colorFromUint32(COLOR_RED); break;
|
case IR24_OLD_RED : colorFromUint32(COLOR_RED); break;
|
||||||
@ -252,8 +290,8 @@ void decodeIR24OLD(uint32_t code)
|
|||||||
void decodeIR24CT(uint32_t code)
|
void decodeIR24CT(uint32_t code)
|
||||||
{
|
{
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case IR24_CT_BRIGHTER : changeBrightness(10); break;
|
case IR24_CT_BRIGHTER : incBrightness(); break;
|
||||||
case IR24_CT_DARKER : changeBrightness(-10); break;
|
case IR24_CT_DARKER : decBrightness(); break;
|
||||||
case IR24_CT_OFF : briLast = bri; bri = 0; break;
|
case IR24_CT_OFF : briLast = bri; bri = 0; break;
|
||||||
case IR24_CT_ON : bri = briLast; break;
|
case IR24_CT_ON : bri = briLast; break;
|
||||||
case IR24_CT_RED : colorFromUint32(COLOR_RED); break;
|
case IR24_CT_RED : colorFromUint32(COLOR_RED); break;
|
||||||
@ -287,8 +325,8 @@ void decodeIR24CT(uint32_t code)
|
|||||||
void decodeIR40(uint32_t code)
|
void decodeIR40(uint32_t code)
|
||||||
{
|
{
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case IR40_BPLUS : changeBrightness(10); break;
|
case IR40_BPLUS : incBrightness(); break;
|
||||||
case IR40_BMINUS : changeBrightness(-10); break;
|
case IR40_BMINUS : decBrightness(); break;
|
||||||
case IR40_OFF : briLast = bri; bri = 0; break;
|
case IR40_OFF : briLast = bri; bri = 0; break;
|
||||||
case IR40_ON : bri = briLast; break;
|
case IR40_ON : bri = briLast; break;
|
||||||
case IR40_RED : colorFromUint24(COLOR_RED); break;
|
case IR40_RED : colorFromUint24(COLOR_RED); break;
|
||||||
@ -344,8 +382,8 @@ void decodeIR40(uint32_t code)
|
|||||||
void decodeIR44(uint32_t code)
|
void decodeIR44(uint32_t code)
|
||||||
{
|
{
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case IR44_BPLUS : changeBrightness(10); break;
|
case IR44_BPLUS : incBrightness(); break;
|
||||||
case IR44_BMINUS : changeBrightness(-10); break;
|
case IR44_BMINUS : decBrightness(); break;
|
||||||
case IR44_OFF : briLast = bri; bri = 0; break;
|
case IR44_OFF : briLast = bri; bri = 0; break;
|
||||||
case IR44_ON : bri = briLast; break;
|
case IR44_ON : bri = briLast; break;
|
||||||
case IR44_RED : colorFromUint24(COLOR_RED); break;
|
case IR44_RED : colorFromUint24(COLOR_RED); break;
|
||||||
@ -407,8 +445,8 @@ void decodeIR44(uint32_t code)
|
|||||||
void decodeIR21(uint32_t code)
|
void decodeIR21(uint32_t code)
|
||||||
{
|
{
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case IR21_BRIGHTER: changeBrightness(10); break;
|
case IR21_BRIGHTER: incBrightness(); break;
|
||||||
case IR21_DARKER: changeBrightness(-10); break;
|
case IR21_DARKER: decBrightness(); break;
|
||||||
case IR21_OFF: briLast = bri; bri = 0; break;
|
case IR21_OFF: briLast = bri; bri = 0; break;
|
||||||
case IR21_ON: bri = briLast; break;
|
case IR21_ON: bri = briLast; break;
|
||||||
case IR21_RED: colorFromUint32(COLOR_RED); break;
|
case IR21_RED: colorFromUint32(COLOR_RED); break;
|
||||||
@ -437,8 +475,8 @@ void decodeIR6(uint32_t code)
|
|||||||
{
|
{
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case IR6_POWER: toggleOnOff(); break;
|
case IR6_POWER: toggleOnOff(); break;
|
||||||
case IR6_CHANNEL_UP: changeBrightness(10); break;
|
case IR6_CHANNEL_UP: incBrightness(); break;
|
||||||
case IR6_CHANNEL_DOWN: changeBrightness(-10); break;
|
case IR6_CHANNEL_DOWN: decBrightness(); break;
|
||||||
case IR6_VOLUME_UP: relativeChange(&effectCurrent, 1, 0, MODE_COUNT); break; // next effect
|
case IR6_VOLUME_UP: relativeChange(&effectCurrent, 1, 0, MODE_COUNT); break; // next effect
|
||||||
case IR6_VOLUME_DOWN: // next palette
|
case IR6_VOLUME_DOWN: // next palette
|
||||||
relativeChange(&effectPalette, 1, 0, strip.getPaletteCount() -1);
|
relativeChange(&effectPalette, 1, 0, strip.getPaletteCount() -1);
|
||||||
@ -472,8 +510,8 @@ void decodeIR9(uint32_t code)
|
|||||||
case IR9_A : if (!applyPreset(1)) effectCurrent = FX_MODE_COLORTWINKLE; break;
|
case IR9_A : if (!applyPreset(1)) effectCurrent = FX_MODE_COLORTWINKLE; break;
|
||||||
case IR9_B : if (!applyPreset(2)) effectCurrent = FX_MODE_RAINBOW_CYCLE; break;
|
case IR9_B : if (!applyPreset(2)) effectCurrent = FX_MODE_RAINBOW_CYCLE; break;
|
||||||
case IR9_C : if (!applyPreset(3)) effectCurrent = FX_MODE_BREATH; break;
|
case IR9_C : if (!applyPreset(3)) effectCurrent = FX_MODE_BREATH; break;
|
||||||
case IR9_UP : changeBrightness(16); break;
|
case IR9_UP : incBrightness(); break;
|
||||||
case IR9_DOWN : changeBrightness(-16); break;
|
case IR9_DOWN : decBrightness(); break;
|
||||||
//case IR9_UP : changeEffectIntensity(16); break;
|
//case IR9_UP : changeEffectIntensity(16); break;
|
||||||
//case IR9_DOWN : changeEffectIntensity(-16); break;
|
//case IR9_DOWN : changeEffectIntensity(-16); break;
|
||||||
case IR9_LEFT : changeEffectSpeed(-16); break;
|
case IR9_LEFT : changeEffectSpeed(-16); break;
|
||||||
@ -488,7 +526,7 @@ void initIR()
|
|||||||
{
|
{
|
||||||
if (irEnabled > 0)
|
if (irEnabled > 0)
|
||||||
{
|
{
|
||||||
irrecv = new IRrecv(IRPIN);
|
irrecv = new IRrecv(irPin);
|
||||||
irrecv->enableIRIn();
|
irrecv->enableIRIn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
213
wled00/json.cpp
213
wled00/json.cpp
@ -1,12 +1,14 @@
|
|||||||
#include "wled.h"
|
#include "wled.h"
|
||||||
|
|
||||||
|
#include "palettes.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* JSON API (De)serialization
|
* JSON API (De)serialization
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void deserializeSegment(JsonObject elem, byte it)
|
void deserializeSegment(JsonObject elem, byte it)
|
||||||
{
|
{
|
||||||
byte id = elem[F("id")] | it;
|
byte id = elem["id"] | it;
|
||||||
if (id < strip.getMaxSegments())
|
if (id < strip.getMaxSegments())
|
||||||
{
|
{
|
||||||
WS2812FX::Segment& seg = strip.getSegment(id);
|
WS2812FX::Segment& seg = strip.getSegment(id);
|
||||||
@ -31,7 +33,7 @@ void deserializeSegment(JsonObject elem, byte it)
|
|||||||
|
|
||||||
seg.setOption(SEG_OPTION_ON, elem["on"] | seg.getOption(SEG_OPTION_ON), id);
|
seg.setOption(SEG_OPTION_ON, elem["on"] | seg.getOption(SEG_OPTION_ON), id);
|
||||||
|
|
||||||
JsonArray colarr = elem[F("col")];
|
JsonArray colarr = elem["col"];
|
||||||
if (!colarr.isNull())
|
if (!colarr.isNull())
|
||||||
{
|
{
|
||||||
for (uint8_t i = 0; i < 3; i++)
|
for (uint8_t i = 0; i < 3; i++)
|
||||||
@ -57,7 +59,8 @@ void deserializeSegment(JsonObject elem, byte it)
|
|||||||
if (sz == 0) continue; //do nothing on empty array
|
if (sz == 0) continue; //do nothing on empty array
|
||||||
|
|
||||||
byte cp = copyArray(colX, rgbw, 4);
|
byte cp = copyArray(colX, rgbw, 4);
|
||||||
if (cp == 1 && rgbw[0] == 0) seg.setColor(i, 0, id);
|
if (cp == 1 && rgbw[0] == 0)
|
||||||
|
seg.setColor(i, 0, id);
|
||||||
colValid = true;
|
colValid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +90,7 @@ void deserializeSegment(JsonObject elem, byte it)
|
|||||||
|
|
||||||
//if (pal != seg.palette && pal < strip.getPaletteCount()) strip.setPalette(pal);
|
//if (pal != seg.palette && pal < strip.getPaletteCount()) strip.setPalette(pal);
|
||||||
seg.setOption(SEG_OPTION_SELECTED, elem[F("sel")] | seg.getOption(SEG_OPTION_SELECTED));
|
seg.setOption(SEG_OPTION_SELECTED, elem[F("sel")] | seg.getOption(SEG_OPTION_SELECTED));
|
||||||
seg.setOption(SEG_OPTION_REVERSED, elem[F("rev")] | seg.getOption(SEG_OPTION_REVERSED));
|
seg.setOption(SEG_OPTION_REVERSED, elem["rev"] | seg.getOption(SEG_OPTION_REVERSED));
|
||||||
seg.setOption(SEG_OPTION_MIRROR , elem[F("mi")] | seg.getOption(SEG_OPTION_MIRROR ));
|
seg.setOption(SEG_OPTION_MIRROR , elem[F("mi")] | seg.getOption(SEG_OPTION_MIRROR ));
|
||||||
|
|
||||||
//temporary, strip object gets updated via colorUpdated()
|
//temporary, strip object gets updated via colorUpdated()
|
||||||
@ -134,7 +137,7 @@ void deserializeSegment(JsonObject elem, byte it)
|
|||||||
if (sz == 0 && sz > 4) break;
|
if (sz == 0 && sz > 4) break;
|
||||||
|
|
||||||
int rgbw[] = {0,0,0,0};
|
int rgbw[] = {0,0,0,0};
|
||||||
byte cp = copyArray(icol, rgbw);
|
copyArray(icol, rgbw);
|
||||||
|
|
||||||
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++) {
|
||||||
@ -196,12 +199,12 @@ bool deserializeState(JsonObject root)
|
|||||||
nightlightTargetBri = nl[F("tbri")] | nightlightTargetBri;
|
nightlightTargetBri = nl[F("tbri")] | nightlightTargetBri;
|
||||||
|
|
||||||
JsonObject udpn = root["udpn"];
|
JsonObject udpn = root["udpn"];
|
||||||
notifyDirect = udpn[F("send")] | notifyDirect;
|
notifyDirect = udpn["send"] | notifyDirect;
|
||||||
receiveNotifications = udpn[F("recv")] | receiveNotifications;
|
receiveNotifications = udpn["recv"] | receiveNotifications;
|
||||||
bool noNotification = udpn[F("nn")]; //send no notification just for this request
|
bool noNotification = udpn[F("nn")]; //send no notification just for this request
|
||||||
|
|
||||||
unsigned long timein = root[F("time")] | -1;
|
unsigned long timein = root[F("time")] | UINT32_MAX;
|
||||||
if (timein != -1) {
|
if (timein != UINT32_MAX) {
|
||||||
if (millis() - ntpLastSyncTime > 50000000L) setTime(timein);
|
if (millis() - ntpLastSyncTime > 50000000L) setTime(timein);
|
||||||
if (presetsModifiedTime == 0) presetsModifiedTime = timein;
|
if (presetsModifiedTime == 0) presetsModifiedTime = timein;
|
||||||
}
|
}
|
||||||
@ -225,7 +228,7 @@ bool deserializeState(JsonObject root)
|
|||||||
JsonVariant segVar = root["seg"];
|
JsonVariant segVar = root["seg"];
|
||||||
if (segVar.is<JsonObject>())
|
if (segVar.is<JsonObject>())
|
||||||
{
|
{
|
||||||
int id = segVar[F("id")] | -1;
|
int id = segVar["id"] | -1;
|
||||||
|
|
||||||
if (id < 0) { //set all selected segments
|
if (id < 0) { //set all selected segments
|
||||||
bool didSet = false;
|
bool didSet = false;
|
||||||
@ -279,7 +282,8 @@ bool deserializeState(JsonObject root)
|
|||||||
|
|
||||||
JsonObject playlist = root[F("playlist")];
|
JsonObject playlist = root[F("playlist")];
|
||||||
if (!playlist.isNull()) {
|
if (!playlist.isNull()) {
|
||||||
loadPlaylist(playlist); return stateResponse;
|
loadPlaylist(playlist);
|
||||||
|
noNotification = true; //do not notify both for this request and the first playlist entry
|
||||||
}
|
}
|
||||||
|
|
||||||
colorUpdated(noNotification ? NOTIFIER_CALL_MODE_NO_NOTIFY : NOTIFIER_CALL_MODE_DIRECT_CHANGE);
|
colorUpdated(noNotification ? NOTIFIER_CALL_MODE_NO_NOTIFY : NOTIFIER_CALL_MODE_DIRECT_CHANGE);
|
||||||
@ -289,7 +293,7 @@ bool deserializeState(JsonObject root)
|
|||||||
|
|
||||||
void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool forPreset, bool segmentBounds)
|
void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool forPreset, bool segmentBounds)
|
||||||
{
|
{
|
||||||
root[F("id")] = id;
|
root["id"] = id;
|
||||||
if (segmentBounds) {
|
if (segmentBounds) {
|
||||||
root[F("start")] = seg.start;
|
root[F("start")] = seg.start;
|
||||||
root["stop"] = seg.stop;
|
root["stop"] = seg.stop;
|
||||||
@ -327,7 +331,7 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool fo
|
|||||||
root[F("ix")] = seg.intensity;
|
root[F("ix")] = seg.intensity;
|
||||||
root[F("pal")] = seg.palette;
|
root[F("pal")] = seg.palette;
|
||||||
root[F("sel")] = seg.isSelected();
|
root[F("sel")] = seg.isSelected();
|
||||||
root[F("rev")] = seg.getOption(SEG_OPTION_REVERSED);
|
root["rev"] = seg.getOption(SEG_OPTION_REVERSED);
|
||||||
root[F("mi")] = seg.getOption(SEG_OPTION_MIRROR);
|
root[F("mi")] = seg.getOption(SEG_OPTION_MIRROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,7 +347,6 @@ void serializeState(JsonObject root, bool forPreset, bool includeBri, bool segme
|
|||||||
if (errorFlag) root[F("error")] = errorFlag;
|
if (errorFlag) root[F("error")] = errorFlag;
|
||||||
|
|
||||||
root[F("ps")] = currentPreset;
|
root[F("ps")] = currentPreset;
|
||||||
root[F("pss")] = savedPresets;
|
|
||||||
root[F("pl")] = (presetCyclingEnabled) ? 0: -1;
|
root[F("pl")] = (presetCyclingEnabled) ? 0: -1;
|
||||||
|
|
||||||
usermods.addToJsonState(root);
|
usermods.addToJsonState(root);
|
||||||
@ -367,8 +370,8 @@ void serializeState(JsonObject root, bool forPreset, bool includeBri, bool segme
|
|||||||
}
|
}
|
||||||
|
|
||||||
JsonObject udpn = root.createNestedObject("udpn");
|
JsonObject udpn = root.createNestedObject("udpn");
|
||||||
udpn[F("send")] = notifyDirect;
|
udpn["send"] = notifyDirect;
|
||||||
udpn[F("recv")] = receiveNotifications;
|
udpn["recv"] = receiveNotifications;
|
||||||
|
|
||||||
root[F("lor")] = realtimeOverride;
|
root[F("lor")] = realtimeOverride;
|
||||||
}
|
}
|
||||||
@ -424,6 +427,7 @@ void serializeInfo(JsonObject root)
|
|||||||
leds_pin.add(LEDPIN);
|
leds_pin.add(LEDPIN);
|
||||||
|
|
||||||
leds[F("pwr")] = strip.currentMilliamps;
|
leds[F("pwr")] = strip.currentMilliamps;
|
||||||
|
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; //will be used in the future to prevent modifications to segment config
|
||||||
@ -474,6 +478,8 @@ void serializeInfo(JsonObject root)
|
|||||||
fs_info["t"] = fsBytesTotal / 1000;
|
fs_info["t"] = fsBytesTotal / 1000;
|
||||||
fs_info[F("pmt")] = presetsModifiedTime;
|
fs_info[F("pmt")] = presetsModifiedTime;
|
||||||
|
|
||||||
|
root[F("ndc")] = nodeListEnabled ? (int)Nodes.size() : -1;
|
||||||
|
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
#ifdef WLED_DEBUG
|
#ifdef WLED_DEBUG
|
||||||
wifi_info[F("txPower")] = (int) WiFi.getTxPower();
|
wifi_info[F("txPower")] = (int) WiFi.getTxPower();
|
||||||
@ -535,6 +541,171 @@ void serializeInfo(JsonObject root)
|
|||||||
root["mac"] = escapedMac;
|
root["mac"] = escapedMac;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setPaletteColors(JsonArray json, CRGBPalette16 palette)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
JsonArray colors = json.createNestedArray();
|
||||||
|
CRGB color = palette[i];
|
||||||
|
colors.add((((float)i / (float)16) * 255));
|
||||||
|
colors.add(color.red);
|
||||||
|
colors.add(color.green);
|
||||||
|
colors.add(color.blue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPaletteColors(JsonArray json, byte* tcp)
|
||||||
|
{
|
||||||
|
TRGBGradientPaletteEntryUnion* ent = (TRGBGradientPaletteEntryUnion*)(tcp);
|
||||||
|
TRGBGradientPaletteEntryUnion u;
|
||||||
|
|
||||||
|
// Count entries
|
||||||
|
uint16_t count = 0;
|
||||||
|
do {
|
||||||
|
u = *(ent + count);
|
||||||
|
count++;
|
||||||
|
} while ( u.index != 255);
|
||||||
|
|
||||||
|
u = *ent;
|
||||||
|
int indexstart = 0;
|
||||||
|
while( indexstart < 255) {
|
||||||
|
indexstart = u.index;
|
||||||
|
|
||||||
|
JsonArray colors = json.createNestedArray();
|
||||||
|
colors.add(u.index);
|
||||||
|
colors.add(u.r);
|
||||||
|
colors.add(u.g);
|
||||||
|
colors.add(u.b);
|
||||||
|
|
||||||
|
ent++;
|
||||||
|
u = *ent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void serializePalettes(JsonObject root, AsyncWebServerRequest* request)
|
||||||
|
{
|
||||||
|
#ifdef ESP8266
|
||||||
|
int itemPerPage = 5;
|
||||||
|
#else
|
||||||
|
int itemPerPage = 8;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int page = 0;
|
||||||
|
if (request->hasParam("page")) {
|
||||||
|
page = request->getParam("page")->value().toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
int palettesCount = strip.getPaletteCount();
|
||||||
|
|
||||||
|
int maxPage = (palettesCount -1) / itemPerPage;
|
||||||
|
if (page > maxPage) page = maxPage;
|
||||||
|
|
||||||
|
int start = itemPerPage * page;
|
||||||
|
int end = start + itemPerPage;
|
||||||
|
if (end >= palettesCount) end = palettesCount;
|
||||||
|
|
||||||
|
root[F("m")] = maxPage;
|
||||||
|
JsonObject palettes = root.createNestedObject("p");
|
||||||
|
|
||||||
|
for (int i = start; i < end; i++) {
|
||||||
|
JsonArray curPalette = palettes.createNestedArray(String(i));
|
||||||
|
CRGB prim;
|
||||||
|
CRGB sec;
|
||||||
|
CRGB ter;
|
||||||
|
switch (i) {
|
||||||
|
case 0: //default palette
|
||||||
|
setPaletteColors(curPalette, PartyColors_p);
|
||||||
|
break;
|
||||||
|
case 1: //random
|
||||||
|
curPalette.add("r");
|
||||||
|
curPalette.add("r");
|
||||||
|
curPalette.add("r");
|
||||||
|
curPalette.add("r");
|
||||||
|
break;
|
||||||
|
case 2: //primary color only
|
||||||
|
curPalette.add(F("c1"));
|
||||||
|
break;
|
||||||
|
case 3: //primary + secondary
|
||||||
|
curPalette.add(F("c1"));
|
||||||
|
curPalette.add(F("c1"));
|
||||||
|
curPalette.add(F("c2"));
|
||||||
|
curPalette.add(F("c2"));
|
||||||
|
break;
|
||||||
|
case 4: //primary + secondary + tertiary
|
||||||
|
curPalette.add(F("c3"));
|
||||||
|
curPalette.add(F("c2"));
|
||||||
|
curPalette.add(F("c1"));
|
||||||
|
break;
|
||||||
|
case 5: {//primary + secondary (+tert if not off), more distinct
|
||||||
|
|
||||||
|
curPalette.add(F("c1"));
|
||||||
|
curPalette.add(F("c1"));
|
||||||
|
curPalette.add(F("c1"));
|
||||||
|
curPalette.add(F("c1"));
|
||||||
|
curPalette.add(F("c1"));
|
||||||
|
curPalette.add(F("c2"));
|
||||||
|
curPalette.add(F("c2"));
|
||||||
|
curPalette.add(F("c2"));
|
||||||
|
curPalette.add(F("c2"));
|
||||||
|
curPalette.add(F("c2"));
|
||||||
|
curPalette.add(F("c3"));
|
||||||
|
curPalette.add(F("c3"));
|
||||||
|
curPalette.add(F("c3"));
|
||||||
|
curPalette.add(F("c3"));
|
||||||
|
curPalette.add(F("c3"));
|
||||||
|
curPalette.add(F("c1"));
|
||||||
|
break;}
|
||||||
|
case 6: //Party colors
|
||||||
|
setPaletteColors(curPalette, PartyColors_p);
|
||||||
|
break;
|
||||||
|
case 7: //Cloud colors
|
||||||
|
setPaletteColors(curPalette, CloudColors_p);
|
||||||
|
break;
|
||||||
|
case 8: //Lava colors
|
||||||
|
setPaletteColors(curPalette, LavaColors_p);
|
||||||
|
break;
|
||||||
|
case 9: //Ocean colors
|
||||||
|
setPaletteColors(curPalette, OceanColors_p);
|
||||||
|
break;
|
||||||
|
case 10: //Forest colors
|
||||||
|
setPaletteColors(curPalette, ForestColors_p);
|
||||||
|
break;
|
||||||
|
case 11: //Rainbow colors
|
||||||
|
setPaletteColors(curPalette, RainbowColors_p);
|
||||||
|
break;
|
||||||
|
case 12: //Rainbow stripe colors
|
||||||
|
setPaletteColors(curPalette, RainbowStripeColors_p);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (i < 13) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
byte tcp[72];
|
||||||
|
memcpy_P(tcp, (byte*)pgm_read_dword(&(gGradientPalettes[i - 13])), 72);
|
||||||
|
setPaletteColors(curPalette, tcp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void serializeNodes(JsonObject root)
|
||||||
|
{
|
||||||
|
JsonArray nodes = root.createNestedArray("nodes");
|
||||||
|
|
||||||
|
for (NodesMap::iterator it = Nodes.begin(); it != Nodes.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->second.ip[0] != 0)
|
||||||
|
{
|
||||||
|
JsonObject node = nodes.createNestedObject();
|
||||||
|
node[F("name")] = it->second.nodeName;
|
||||||
|
node["type"] = it->second.nodeType;
|
||||||
|
node["ip"] = it->second.ip.toString();
|
||||||
|
node[F("age")] = it->second.age;
|
||||||
|
node[F("vid")] = it->second.build;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void serveJson(AsyncWebServerRequest* request)
|
void serveJson(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
byte subJson = 0;
|
byte subJson = 0;
|
||||||
@ -542,6 +713,8 @@ void serveJson(AsyncWebServerRequest* request)
|
|||||||
if (url.indexOf("state") > 0) subJson = 1;
|
if (url.indexOf("state") > 0) subJson = 1;
|
||||||
else if (url.indexOf("info") > 0) subJson = 2;
|
else if (url.indexOf("info") > 0) subJson = 2;
|
||||||
else if (url.indexOf("si") > 0) subJson = 3;
|
else if (url.indexOf("si") > 0) subJson = 3;
|
||||||
|
else if (url.indexOf("nodes") > 0) subJson = 4;
|
||||||
|
else if (url.indexOf("palx") > 0) subJson = 5;
|
||||||
else if (url.indexOf("live") > 0) {
|
else if (url.indexOf("live") > 0) {
|
||||||
serveLiveLeds(request);
|
serveLiveLeds(request);
|
||||||
return;
|
return;
|
||||||
@ -568,6 +741,10 @@ void serveJson(AsyncWebServerRequest* request)
|
|||||||
serializeState(doc); break;
|
serializeState(doc); break;
|
||||||
case 2: //info
|
case 2: //info
|
||||||
serializeInfo(doc); break;
|
serializeInfo(doc); break;
|
||||||
|
case 4: //node list
|
||||||
|
serializeNodes(doc); break;
|
||||||
|
case 5: //palettes
|
||||||
|
serializePalettes(doc, request); break;
|
||||||
default: //all
|
default: //all
|
||||||
JsonObject state = doc.createNestedObject("state");
|
JsonObject state = doc.createNestedObject("state");
|
||||||
serializeState(state);
|
serializeState(state);
|
||||||
@ -588,7 +765,7 @@ void serveJson(AsyncWebServerRequest* request)
|
|||||||
|
|
||||||
bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient)
|
bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient)
|
||||||
{
|
{
|
||||||
AsyncWebSocketClient * wsc;
|
AsyncWebSocketClient * wsc = nullptr;
|
||||||
if (!request) { //not HTTP, use Websockets
|
if (!request) { //not HTTP, use Websockets
|
||||||
#ifdef WLED_ENABLE_WEBSOCKETS
|
#ifdef WLED_ENABLE_WEBSOCKETS
|
||||||
wsc = ws.client(wsClient);
|
wsc = ws.client(wsClient);
|
||||||
@ -605,7 +782,7 @@ bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient)
|
|||||||
|
|
||||||
for (uint16_t i= 0; i < used; i += n)
|
for (uint16_t i= 0; i < used; i += n)
|
||||||
{
|
{
|
||||||
olen += sprintf(obuf + olen, "\"%06X\",", strip.getPixelColor(i));
|
olen += sprintf(obuf + olen, "\"%06X\",", strip.getPixelColor(i) & 0xFFFFFF);
|
||||||
}
|
}
|
||||||
olen -= 1;
|
olen -= 1;
|
||||||
oappend((const char*)F("],\"n\":"));
|
oappend((const char*)F("],\"n\":"));
|
||||||
|
@ -30,6 +30,7 @@ void toggleOnOff()
|
|||||||
{
|
{
|
||||||
briLast = bri;
|
briLast = bri;
|
||||||
bri = 0;
|
bri = 0;
|
||||||
|
unloadPlaylist();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,10 +23,9 @@ bool parseLx(int lxValue, byte rgbw[4])
|
|||||||
ok = true;
|
ok = true;
|
||||||
float tmpBri = floor((lxValue - 200000000) / 10000); ;
|
float tmpBri = floor((lxValue - 200000000) / 10000); ;
|
||||||
uint16_t ct = (lxValue - 200000000) - (((uint8_t)tmpBri) * 10000);
|
uint16_t ct = (lxValue - 200000000) - (((uint8_t)tmpBri) * 10000);
|
||||||
float temp = 0;
|
|
||||||
|
|
||||||
tmpBri *= 2.55;
|
tmpBri *= 2.55;
|
||||||
constrain(tmpBri, 0, 255);
|
tmpBri = constrain(tmpBri, 0, 255);
|
||||||
|
|
||||||
colorKtoRGB(ct, rgbw);
|
colorKtoRGB(ct, rgbw);
|
||||||
lxRed = rgbw[0]; lxGreen = rgbw[1]; lxBlue = rgbw[2];
|
lxRed = rgbw[0]; lxGreen = rgbw[1]; lxBlue = rgbw[2];
|
||||||
|
@ -110,7 +110,7 @@ void publishMqtt()
|
|||||||
char s[10];
|
char s[10];
|
||||||
char subuf[38];
|
char subuf[38];
|
||||||
|
|
||||||
sprintf(s, "%ld", bri);
|
sprintf(s, "%u", bri);
|
||||||
strcpy(subuf, mqttDeviceTopic);
|
strcpy(subuf, mqttDeviceTopic);
|
||||||
strcat(subuf, "/g");
|
strcat(subuf, "/g");
|
||||||
mqtt->publish(subuf, 0, true, s);
|
mqtt->publish(subuf, 0, true, s);
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
|
#include "pin_manager.h"
|
||||||
#include "wled.h"
|
#include "wled.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* Registers pins so there is no attempt for two interfaces to use the same pin
|
|
||||||
*/
|
|
||||||
|
|
||||||
void PinManagerClass::deallocatePin(byte gpio)
|
void PinManagerClass::deallocatePin(byte gpio)
|
||||||
{
|
{
|
||||||
if (!isPinOk(gpio, false)) return;
|
if (!isPinOk(gpio, false)) return;
|
||||||
@ -52,3 +49,43 @@ bool PinManagerClass::isPinOk(byte gpio, bool output)
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
byte PinManagerClass::allocateLedc(byte channels)
|
||||||
|
{
|
||||||
|
if (channels > 16 || channels == 0) return 255;
|
||||||
|
byte ca = 0;
|
||||||
|
for (byte i = 0; i < 16; i++) {
|
||||||
|
byte by = i >> 3;
|
||||||
|
byte bi = i - 8*by;
|
||||||
|
if (bitRead(ledcAlloc[by], bi)) { //found occupied pin
|
||||||
|
ca = 0;
|
||||||
|
} else {
|
||||||
|
ca++;
|
||||||
|
}
|
||||||
|
if (ca >= channels) { //enough free channels
|
||||||
|
byte in = (i + 1) - ca;
|
||||||
|
for (byte j = 0; j < ca; j++) {
|
||||||
|
byte b = in + j;
|
||||||
|
byte by = b >> 3;
|
||||||
|
byte bi = b - 8*by;
|
||||||
|
bitWrite(ledcAlloc[by], bi, true);
|
||||||
|
}
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 255; //not enough consecutive free LEDC channels
|
||||||
|
}
|
||||||
|
|
||||||
|
void PinManagerClass::deallocateLedc(byte pos, byte channels)
|
||||||
|
{
|
||||||
|
for (byte j = pos; j < pos + channels; j++) {
|
||||||
|
if (j > 16) return;
|
||||||
|
byte by = j >> 3;
|
||||||
|
byte bi = j - 8*by;
|
||||||
|
bitWrite(ledcAlloc[by], bi, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PinManagerClass pinManager = PinManagerClass();
|
29
wled00/pin_manager.h
Normal file
29
wled00/pin_manager.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef WLED_PIN_MANAGER_H
|
||||||
|
#define WLED_PIN_MANAGER_H
|
||||||
|
/*
|
||||||
|
* Registers pins so there is no attempt for two interfaces to use the same pin
|
||||||
|
*/
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
class PinManagerClass {
|
||||||
|
private:
|
||||||
|
#ifdef ESP8266
|
||||||
|
uint8_t pinAlloc[3] = {0x00, 0x00, 0x00}; //24bit, 1 bit per pin, we use first 17bits
|
||||||
|
#else
|
||||||
|
uint8_t pinAlloc[5] = {0x00, 0x00, 0x00, 0x00, 0x00}; //40bit, 1 bit per pin, we use all bits
|
||||||
|
uint8_t ledcAlloc[2] = {0x00, 0x00}; //16 LEDC channels
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public:
|
||||||
|
void deallocatePin(byte gpio);
|
||||||
|
bool allocatePin(byte gpio, bool output = true);
|
||||||
|
bool isPinAllocated(byte gpio);
|
||||||
|
bool isPinOk(byte gpio, bool output = true);
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
byte allocateLedc(byte channels);
|
||||||
|
void deallocateLedc(byte pos, byte channels);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
extern PinManagerClass pinManager;
|
||||||
|
#endif
|
@ -10,19 +10,42 @@ typedef struct PlaylistEntry {
|
|||||||
uint16_t tr;
|
uint16_t tr;
|
||||||
} ple;
|
} ple;
|
||||||
|
|
||||||
byte playlistRepeat = 1;
|
int8_t playlistRepeat = 1;
|
||||||
byte playlistEndPreset = 0;
|
byte playlistEndPreset = 0;
|
||||||
|
byte *playlistEntries = nullptr;
|
||||||
uint8_t* playlistEntries;
|
|
||||||
|
|
||||||
byte playlistLen;
|
byte playlistLen;
|
||||||
int8_t playlistIndex = -1;
|
int8_t playlistIndex = -1;
|
||||||
|
|
||||||
uint16_t playlistEntryDur = 0;
|
uint16_t playlistEntryDur = 0;
|
||||||
|
|
||||||
|
|
||||||
|
void shufflePlaylist() {
|
||||||
|
int currentIndex = playlistLen, randomIndex;
|
||||||
|
|
||||||
|
PlaylistEntry temporaryValue, *entries = reinterpret_cast<PlaylistEntry*>(playlistEntries);
|
||||||
|
|
||||||
|
// While there remain elements to shuffle...
|
||||||
|
while (currentIndex--) {
|
||||||
|
// Pick a random element...
|
||||||
|
randomIndex = random(0, currentIndex);
|
||||||
|
// And swap it with the current element.
|
||||||
|
temporaryValue = entries[currentIndex];
|
||||||
|
entries[currentIndex] = entries[randomIndex];
|
||||||
|
entries[randomIndex] = temporaryValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void unloadPlaylist() {
|
||||||
|
if (playlistEntries != nullptr) {
|
||||||
|
delete[] playlistEntries;
|
||||||
|
playlistEntries = nullptr;
|
||||||
|
}
|
||||||
|
currentPlaylist = playlistIndex = -1;
|
||||||
|
playlistLen = playlistEntryDur = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void loadPlaylist(JsonObject playlistObj) {
|
void loadPlaylist(JsonObject playlistObj) {
|
||||||
delete playlistEntries;
|
unloadPlaylist();
|
||||||
playlistIndex = -1; playlistEntryDur = 0;
|
|
||||||
JsonArray presets = playlistObj["ps"];
|
JsonArray presets = playlistObj["ps"];
|
||||||
playlistLen = presets.size();
|
playlistLen = presets.size();
|
||||||
if (playlistLen == 0) return;
|
if (playlistLen == 0) return;
|
||||||
@ -72,26 +95,28 @@ void loadPlaylist(JsonObject playlistObj) {
|
|||||||
currentPlaylist = 0; //TODO here we need the preset ID where the playlist is saved
|
currentPlaylist = 0; //TODO here we need the preset ID where the playlist is saved
|
||||||
}
|
}
|
||||||
|
|
||||||
void handlePlaylist()
|
|
||||||
{
|
void handlePlaylist() {
|
||||||
if (currentPlaylist < 0 || playlistEntries == nullptr || presetCyclingEnabled) return;
|
if (currentPlaylist < 0 || playlistEntries == nullptr || presetCyclingEnabled) return;
|
||||||
|
|
||||||
if (millis() - presetCycledTime > (100*playlistEntryDur))
|
if (millis() - presetCycledTime > (100*playlistEntryDur)) {
|
||||||
{
|
|
||||||
presetCycledTime = millis();
|
presetCycledTime = millis();
|
||||||
if (bri == 0 || nightlightActive) return;
|
if (bri == 0 || nightlightActive) return;
|
||||||
|
|
||||||
playlistIndex++;
|
++playlistIndex %= playlistLen; // -1 at 1st run (limit to playlistLen)
|
||||||
if (playlistIndex >= playlistLen) {
|
|
||||||
playlistIndex = 0;
|
if (!playlistRepeat && !playlistIndex) { //stop if repeat == 0 and restart of playlist
|
||||||
if (playlistRepeat == 1) { //stop
|
unloadPlaylist();
|
||||||
currentPlaylist = -1;
|
|
||||||
delete playlistEntries;
|
|
||||||
playlistEntries = nullptr;
|
|
||||||
if (playlistEndPreset) applyPreset(playlistEndPreset);
|
if (playlistEndPreset) applyPreset(playlistEndPreset);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (playlistRepeat > 1) playlistRepeat--;
|
// playlist roll-over
|
||||||
|
if (!playlistIndex) {
|
||||||
|
if (playlistRepeat > 0) {// playlistRepeat < 0 => endless loop with shuffling presets
|
||||||
|
playlistRepeat--; // decrease repeat count on each index reset
|
||||||
|
} else {
|
||||||
|
shufflePlaylist(); // shuffle playlist and start over
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PlaylistEntry* entries = reinterpret_cast<PlaylistEntry*>(playlistEntries);
|
PlaylistEntry* entries = reinterpret_cast<PlaylistEntry*>(playlistEntries);
|
||||||
|
@ -75,18 +75,89 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
//LED SETTINGS
|
//LED SETTINGS
|
||||||
if (subPage == 2)
|
if (subPage == 2)
|
||||||
{
|
{
|
||||||
int t = request->arg(F("LC")).toInt();
|
int t = 0;
|
||||||
|
|
||||||
|
if (rlyPin>=0 && pinManager.isPinAllocated(rlyPin)) pinManager.deallocatePin(rlyPin);
|
||||||
|
#ifndef WLED_DISABLE_INFRARED
|
||||||
|
if (irPin>=0 && pinManager.isPinAllocated(irPin)) pinManager.deallocatePin(irPin);
|
||||||
|
#endif
|
||||||
|
if (btnPin>=0 && pinManager.isPinAllocated(btnPin)) pinManager.deallocatePin(btnPin);
|
||||||
|
//TODO remove all busses, but not in this system call
|
||||||
|
//busses->removeAll();
|
||||||
|
|
||||||
|
uint8_t colorOrder, type;
|
||||||
|
uint16_t length, start;
|
||||||
|
uint8_t pins[5] = {255, 255, 255, 255, 255};
|
||||||
|
|
||||||
|
for (uint8_t s = 0; s < WLED_MAX_BUSSES; s++) {
|
||||||
|
char lp[4] = "L0"; lp[2] = 48+s; lp[3] = 0; //ascii 0-9 //strip data pin
|
||||||
|
char lc[4] = "LC"; lc[2] = 48+s; lc[3] = 0; //strip length
|
||||||
|
char co[4] = "CO"; co[2] = 48+s; co[3] = 0; //strip color order
|
||||||
|
char lt[4] = "LT"; lt[2] = 48+s; lt[3] = 0; //strip type
|
||||||
|
char ls[4] = "LS"; ls[2] = 48+s; ls[3] = 0; //strip start LED
|
||||||
|
char cv[4] = "CV"; cv[2] = 48+s; cv[3] = 0; //strip reverse
|
||||||
|
if (!request->hasArg(lp)) {
|
||||||
|
DEBUG_PRINTLN("No data."); break;
|
||||||
|
}
|
||||||
|
for (uint8_t i = 0; i < 5; i++) {
|
||||||
|
lp[1] = 48+i;
|
||||||
|
if (!request->hasArg(lp)) break;
|
||||||
|
pins[i] = (request->arg(lp).length() > 0) ? request->arg(lp).toInt() : 255;
|
||||||
|
}
|
||||||
|
type = request->arg(lt).toInt();
|
||||||
|
|
||||||
|
if (request->hasArg(lc) && request->arg(lc).toInt() > 0) {
|
||||||
|
length = request->arg(lc).toInt();
|
||||||
|
} else {
|
||||||
|
break; // no parameter
|
||||||
|
}
|
||||||
|
colorOrder = request->arg(co).toInt();
|
||||||
|
start = (request->hasArg(ls)) ? request->arg(ls).toInt() : 0;
|
||||||
|
|
||||||
|
if (busConfigs[s] != nullptr) delete busConfigs[s];
|
||||||
|
busConfigs[s] = new BusConfig(type, pins, start, length, colorOrder, request->hasArg(cv));
|
||||||
|
}
|
||||||
|
|
||||||
|
ledCount = request->arg(F("LC")).toInt();
|
||||||
if (t > 0 && t <= MAX_LEDS) ledCount = t;
|
if (t > 0 && t <= MAX_LEDS) ledCount = t;
|
||||||
#ifdef ESP8266
|
|
||||||
#if LEDPIN == 3
|
// upate other pins
|
||||||
if (ledCount > MAX_LEDS_DMA) ledCount = MAX_LEDS_DMA; //DMA method uses too much ram
|
#ifndef WLED_DISABLE_INFRARED
|
||||||
#endif
|
int hw_ir_pin = request->arg(F("IR")).toInt();
|
||||||
|
if (pinManager.isPinOk(hw_ir_pin) && pinManager.allocatePin(hw_ir_pin,false)) {
|
||||||
|
irPin = hw_ir_pin;
|
||||||
|
} else {
|
||||||
|
irPin = -1;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int hw_rly_pin = request->arg(F("RL")).toInt();
|
||||||
|
if (pinManager.allocatePin(hw_rly_pin,true)) {
|
||||||
|
rlyPin = hw_rly_pin;
|
||||||
|
} else {
|
||||||
|
rlyPin = -1;
|
||||||
|
}
|
||||||
|
rlyMde = (bool)request->hasArg(F("RM"));
|
||||||
|
|
||||||
|
int hw_btn_pin = request->arg(F("BT")).toInt();
|
||||||
|
if (pinManager.allocatePin(hw_btn_pin,false)) {
|
||||||
|
btnPin = hw_btn_pin;
|
||||||
|
pinMode(btnPin, INPUT_PULLUP);
|
||||||
|
} else {
|
||||||
|
btnPin = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hw_aux_pin = request->arg(F("AX")).toInt();
|
||||||
|
if (pinManager.allocatePin(hw_aux_pin,true)) {
|
||||||
|
auxPin = hw_aux_pin;
|
||||||
|
} else {
|
||||||
|
auxPin = -1;
|
||||||
|
}
|
||||||
|
|
||||||
strip.ablMilliampsMax = request->arg(F("MA")).toInt();
|
strip.ablMilliampsMax = request->arg(F("MA")).toInt();
|
||||||
strip.milliampsPerLed = request->arg(F("LA")).toInt();
|
strip.milliampsPerLed = request->arg(F("LA")).toInt();
|
||||||
|
|
||||||
useRGBW = request->hasArg(F("EW"));
|
useRGBW = request->hasArg(F("EW"));
|
||||||
strip.setColorOrder(request->arg(F("CO")).toInt());
|
|
||||||
strip.rgbwMode = request->arg(F("AW")).toInt();
|
strip.rgbwMode = request->arg(F("AW")).toInt();
|
||||||
|
|
||||||
briS = request->arg(F("CA")).toInt();
|
briS = request->arg(F("CA")).toInt();
|
||||||
@ -146,6 +217,10 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
notifyMacro = request->hasArg(F("SM"));
|
notifyMacro = request->hasArg(F("SM"));
|
||||||
notifyTwice = request->hasArg(F("S2"));
|
notifyTwice = request->hasArg(F("S2"));
|
||||||
|
|
||||||
|
nodeListEnabled = request->hasArg(F("NL"));
|
||||||
|
if (!nodeListEnabled) Nodes.clear();
|
||||||
|
nodeBroadcastEnabled = request->hasArg(F("NB"));
|
||||||
|
|
||||||
receiveDirect = request->hasArg(F("RD"));
|
receiveDirect = request->hasArg(F("RD"));
|
||||||
e131SkipOutOfSequence = request->hasArg(F("ES"));
|
e131SkipOutOfSequence = request->hasArg(F("ES"));
|
||||||
e131Multicast = request->hasArg(F("EM"));
|
e131Multicast = request->hasArg(F("EM"));
|
||||||
@ -328,12 +403,9 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
DMXFixtureMap[i] = t;
|
DMXFixtureMap[i] = t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
if (subPage != 6 || !doReboot) serializeConfig(); //do not save if factory reset
|
|
||||||
if (subPage == 2) {
|
if (subPage != 2 && (subPage != 6 || !doReboot)) serializeConfig(); //do not save if factory reset or LED settings (which are saved after LED re-init)
|
||||||
strip.init(useRGBW,ledCount,skipFirstLed);
|
|
||||||
}
|
|
||||||
if (subPage == 4) alexaInit();
|
if (subPage == 4) alexaInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -646,15 +718,15 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
|||||||
}
|
}
|
||||||
if (nightlightMode > NL_MODE_SUN) nightlightMode = NL_MODE_SUN;
|
if (nightlightMode > NL_MODE_SUN) nightlightMode = NL_MODE_SUN;
|
||||||
|
|
||||||
#if AUXPIN >= 0
|
|
||||||
//toggle general purpose output
|
//toggle general purpose output
|
||||||
|
if (auxPin>=0) {
|
||||||
pos = req.indexOf(F("AX="));
|
pos = req.indexOf(F("AX="));
|
||||||
if (pos > 0) {
|
if (pos > 0) {
|
||||||
auxTime = getNumVal(&req, pos);
|
auxTime = getNumVal(&req, pos);
|
||||||
auxActive = true;
|
auxActive = true;
|
||||||
if (auxTime == 0) auxActive = false;
|
if (auxTime == 0) auxActive = false;
|
||||||
}
|
}
|
||||||
#endif
|
}
|
||||||
|
|
||||||
pos = req.indexOf(F("TT="));
|
pos = req.indexOf(F("TT="));
|
||||||
if (pos > 0) transitionDelay = getNumVal(&req, pos);
|
if (pos > 0) transitionDelay = getNumVal(&req, pos);
|
||||||
|
@ -37,10 +37,10 @@ AsyncMqttClient::AsyncMqttClient()
|
|||||||
_client.onPoll([](void* obj, AsyncClient* c) { (static_cast<AsyncMqttClient*>(obj))->_onPoll(c); }, this);
|
_client.onPoll([](void* obj, AsyncClient* c) { (static_cast<AsyncMqttClient*>(obj))->_onPoll(c); }, this);
|
||||||
|
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
sprintf(_generatedClientId, "esp32%06x", ESP.getEfuseMac());
|
sprintf(_generatedClientId, "esp32%06x", (uint32_t)ESP.getEfuseMac());
|
||||||
_xSemaphore = xSemaphoreCreateMutex();
|
_xSemaphore = xSemaphoreCreateMutex();
|
||||||
#elif defined(ESP8266)
|
#elif defined(ESP8266)
|
||||||
sprintf(_generatedClientId, "esp8266%06x", ESP.getChipId());
|
sprintf(_generatedClientId, "esp8266%06x", (uint32_t)ESP.getChipId());
|
||||||
#endif
|
#endif
|
||||||
_clientId = _generatedClientId;
|
_clientId = _generatedClientId;
|
||||||
|
|
||||||
|
@ -93,7 +93,9 @@ struct BlynkHeader
|
|||||||
}
|
}
|
||||||
BLYNK_ATTR_PACKED;
|
BLYNK_ATTR_PACKED;
|
||||||
|
|
||||||
#if !defined(htons) && (defined(ARDUINO) || defined(ESP8266) || defined(PARTICLE) || defined(__MBED__))
|
#if defined(ESP32)
|
||||||
|
#include <lwip/ip_addr.h>
|
||||||
|
#elif !defined(htons) && (defined(ARDUINO) || defined(ESP8266) || defined(PARTICLE) || defined(__MBED__))
|
||||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||||
#define htons(x) ( ((x)<<8) | (((x)>>8)&0xFF) )
|
#define htons(x) ( ((x)<<8) | (((x)>>8)&0xFF) )
|
||||||
#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \
|
#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \
|
||||||
|
@ -45,8 +45,7 @@ public:
|
|||||||
}
|
}
|
||||||
BLYNK_LOG1(BLYNK_F("Connected to WiFi"));
|
BLYNK_LOG1(BLYNK_F("Connected to WiFi"));
|
||||||
|
|
||||||
IPAddress myip = WiFi.localIP();
|
BLYNK_LOG_IP("IP: ", WiFi.localIP());
|
||||||
BLYNK_LOG_IP("IP: ", myip);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void config(const char* auth,
|
void config(const char* auth,
|
||||||
|
@ -77,10 +77,9 @@ void DMXESPSerial::write(int Channel, uint8_t value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DMXESPSerial::end() {
|
void DMXESPSerial::end() {
|
||||||
delete dmxData;
|
|
||||||
chanSize = 0;
|
chanSize = 0;
|
||||||
Serial1.end();
|
Serial1.end();
|
||||||
dmxStarted == false;
|
dmxStarted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DMXESPSerial::update() {
|
void DMXESPSerial::update() {
|
||||||
|
@ -101,8 +101,8 @@ private:
|
|||||||
case EspalexaDeviceType::whitespectrum: return PSTR("Color temperature light");
|
case EspalexaDeviceType::whitespectrum: return PSTR("Color temperature light");
|
||||||
case EspalexaDeviceType::color: return PSTR("Color light");
|
case EspalexaDeviceType::color: return PSTR("Color light");
|
||||||
case EspalexaDeviceType::extendedcolor: return PSTR("Extended color light");
|
case EspalexaDeviceType::extendedcolor: return PSTR("Extended color light");
|
||||||
|
default: return "";
|
||||||
}
|
}
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* modelidString(EspalexaDeviceType t)
|
const char* modelidString(EspalexaDeviceType t)
|
||||||
@ -113,8 +113,8 @@ private:
|
|||||||
case EspalexaDeviceType::whitespectrum: return "LWT010";
|
case EspalexaDeviceType::whitespectrum: return "LWT010";
|
||||||
case EspalexaDeviceType::color: return "LST001";
|
case EspalexaDeviceType::color: return "LST001";
|
||||||
case EspalexaDeviceType::extendedcolor: return "LCT015";
|
case EspalexaDeviceType::extendedcolor: return "LCT015";
|
||||||
|
default: return "";
|
||||||
}
|
}
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void encodeLightId(uint8_t idx, char* out)
|
void encodeLightId(uint8_t idx, char* out)
|
||||||
|
@ -112,7 +112,6 @@ uint32_t EspalexaDevice::getRGB()
|
|||||||
{
|
{
|
||||||
if (_rgb != 0) return _rgb; //color has not changed
|
if (_rgb != 0) return _rgb; //color has not changed
|
||||||
byte rgb[4]{0, 0, 0, 0};
|
byte rgb[4]{0, 0, 0, 0};
|
||||||
float r, g, b, w;
|
|
||||||
|
|
||||||
if (_mode == EspalexaColorMode::none) return 0;
|
if (_mode == EspalexaColorMode::none) return 0;
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ public:
|
|||||||
virtual void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override final {
|
virtual void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override final {
|
||||||
if (_onRequest) {
|
if (_onRequest) {
|
||||||
_contentLength = total;
|
_contentLength = total;
|
||||||
if (total > 0 && request->_tempObject == NULL && total < _maxContentLength) {
|
if (total > 0 && request->_tempObject == NULL && (int)total < _maxContentLength) {
|
||||||
request->_tempObject = malloc(total);
|
request->_tempObject = malloc(total);
|
||||||
}
|
}
|
||||||
if (request->_tempObject != NULL) {
|
if (request->_tempObject != NULL) {
|
||||||
|
114
wled00/udp.cpp
114
wled00/udp.cpp
@ -163,8 +163,40 @@ void handleNotifications()
|
|||||||
if (!isSupp && notifierUdp.remoteIP() == Network.localIP()) return; //don't process broadcasts we send ourselves
|
if (!isSupp && notifierUdp.remoteIP() == Network.localIP()) return; //don't process broadcasts we send ourselves
|
||||||
|
|
||||||
uint8_t udpIn[packetSize +1];
|
uint8_t udpIn[packetSize +1];
|
||||||
if (isSupp) notifier2Udp.read(udpIn, packetSize);
|
uint16_t len;
|
||||||
else notifierUdp.read(udpIn, packetSize);
|
if (isSupp) len = notifier2Udp.read(udpIn, packetSize);
|
||||||
|
else len = notifierUdp.read(udpIn, packetSize);
|
||||||
|
|
||||||
|
// WLED nodes info notifications
|
||||||
|
if (isSupp && udpIn[0] == 255 && udpIn[1] == 1 && len >= 40) {
|
||||||
|
if (!nodeListEnabled || notifier2Udp.remoteIP() == Network.localIP()) return;
|
||||||
|
|
||||||
|
uint8_t unit = udpIn[39];
|
||||||
|
NodesMap::iterator it = Nodes.find(unit);
|
||||||
|
if (it == Nodes.end() && Nodes.size() < WLED_MAX_NODES) { // Create a new element when not present
|
||||||
|
Nodes[unit].age = 0;
|
||||||
|
it = Nodes.find(unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (it != Nodes.end()) {
|
||||||
|
for (byte x = 0; x < 4; x++) {
|
||||||
|
it->second.ip[x] = udpIn[x + 2];
|
||||||
|
}
|
||||||
|
it->second.age = 0; // reset 'age counter'
|
||||||
|
char tmpNodeName[33] = { 0 };
|
||||||
|
memcpy(&tmpNodeName[0], reinterpret_cast<byte *>(&udpIn[6]), 32);
|
||||||
|
tmpNodeName[32] = 0;
|
||||||
|
it->second.nodeName = tmpNodeName;
|
||||||
|
it->second.nodeName.trim();
|
||||||
|
it->second.nodeType = udpIn[38];
|
||||||
|
uint32_t build = 0;
|
||||||
|
if (len >= 44)
|
||||||
|
for (byte i=0; i<sizeof(uint32_t); i++)
|
||||||
|
build |= udpIn[40+i]<<(8*i);
|
||||||
|
it->second.build = build;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//wled notifier, ignore if realtime packets active
|
//wled notifier, ignore if realtime packets active
|
||||||
if (udpIn[0] == 0 && !realtimeMode && receiveNotifications)
|
if (udpIn[0] == 0 && !realtimeMode && receiveNotifications)
|
||||||
@ -315,6 +347,15 @@ void handleNotifications()
|
|||||||
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0);
|
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0);
|
||||||
id++;
|
id++;
|
||||||
}
|
}
|
||||||
|
} else if (udpIn[0] == 5) //dnrgbw
|
||||||
|
{
|
||||||
|
uint16_t id = ((udpIn[3] << 0) & 0xFF) + ((udpIn[2] << 8) & 0xFF00);
|
||||||
|
for (uint16_t i = 4; i < packetSize -2; i += 4)
|
||||||
|
{
|
||||||
|
if (id >= ledCount) break;
|
||||||
|
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3]);
|
||||||
|
id++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
strip.show();
|
strip.show();
|
||||||
return;
|
return;
|
||||||
@ -349,3 +390,72 @@ void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
Refresh aging for remote units, drop if too old...
|
||||||
|
\*********************************************************************************************/
|
||||||
|
void refreshNodeList()
|
||||||
|
{
|
||||||
|
for (NodesMap::iterator it = Nodes.begin(); it != Nodes.end();) {
|
||||||
|
bool mustRemove = true;
|
||||||
|
|
||||||
|
if (it->second.ip[0] != 0) {
|
||||||
|
if (it->second.age < 10) {
|
||||||
|
it->second.age++;
|
||||||
|
mustRemove = false;
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mustRemove) {
|
||||||
|
it = Nodes.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
Broadcast system info to other nodes. (to update node lists)
|
||||||
|
\*********************************************************************************************/
|
||||||
|
void sendSysInfoUDP()
|
||||||
|
{
|
||||||
|
if (!udp2Connected) return;
|
||||||
|
|
||||||
|
IPAddress ip = Network.localIP();
|
||||||
|
|
||||||
|
// TODO: make a nice struct of it and clean up
|
||||||
|
// 0: 1 byte 'binary token 255'
|
||||||
|
// 1: 1 byte id '1'
|
||||||
|
// 2: 4 byte ip
|
||||||
|
// 6: 32 char name
|
||||||
|
// 38: 1 byte node type id
|
||||||
|
// 39: 1 byte node id
|
||||||
|
// 40: 4 byte version ID
|
||||||
|
// 44 bytes total
|
||||||
|
|
||||||
|
// send my info to the world...
|
||||||
|
uint8_t data[44] = {0};
|
||||||
|
data[0] = 255;
|
||||||
|
data[1] = 1;
|
||||||
|
|
||||||
|
for (byte x = 0; x < 4; x++) {
|
||||||
|
data[x + 2] = ip[x];
|
||||||
|
}
|
||||||
|
memcpy((byte *)data + 6, serverDescription, 32);
|
||||||
|
#ifdef ESP8266
|
||||||
|
data[38] = NODE_TYPE_ID_ESP8266;
|
||||||
|
#elif defined(ARDUINO_ARCH_ESP32)
|
||||||
|
data[38] = NODE_TYPE_ID_ESP32;
|
||||||
|
#else
|
||||||
|
data[38] = NODE_TYPE_ID_UNDEFINED;
|
||||||
|
#endif
|
||||||
|
data[39] = ip[3]; // unit ID == last IP number
|
||||||
|
|
||||||
|
uint32_t build = VERSION;
|
||||||
|
for (byte i=0; i<sizeof(uint32_t); i++)
|
||||||
|
data[40+i] = (build>>(8*i)) & 0xFF;
|
||||||
|
|
||||||
|
IPAddress broadcastIP(255, 255, 255, 255);
|
||||||
|
notifier2Udp.beginPacket(broadcastIP, udpPort2);
|
||||||
|
notifier2Udp.write(data, sizeof(data));
|
||||||
|
notifier2Udp.endPacket();
|
||||||
|
}
|
||||||
|
@ -32,6 +32,7 @@ bool UsermodManager::add(Usermod* um)
|
|||||||
if (numMods >= WLED_MAX_USERMODS || um == nullptr) return false;
|
if (numMods >= WLED_MAX_USERMODS || um == nullptr) return false;
|
||||||
ums[numMods] = um;
|
ums[numMods] = um;
|
||||||
numMods++;
|
numMods++;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte UsermodManager::getModCount() {return numMods;}
|
byte UsermodManager::getModCount() {return numMods;}
|
@ -13,7 +13,9 @@
|
|||||||
#ifdef USERMOD_DALLASTEMPERATURE
|
#ifdef USERMOD_DALLASTEMPERATURE
|
||||||
#include "../usermods/Temperature/usermod_temperature.h"
|
#include "../usermods/Temperature/usermod_temperature.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//#include "usermod_v2_empty.h"
|
//#include "usermod_v2_empty.h"
|
||||||
|
|
||||||
#ifdef USERMOD_BUZZER
|
#ifdef USERMOD_BUZZER
|
||||||
#include "../usermods/buzzer/usermod_v2_buzzer.h"
|
#include "../usermods/buzzer/usermod_v2_buzzer.h"
|
||||||
#endif
|
#endif
|
||||||
@ -24,6 +26,11 @@
|
|||||||
#ifdef USERMOD_MODE_SORT
|
#ifdef USERMOD_MODE_SORT
|
||||||
#include "../usermods/usermod_v2_mode_sort/usermod_v2_mode_sort.h"
|
#include "../usermods/usermod_v2_mode_sort/usermod_v2_mode_sort.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// BME280 v2 usermod. Define "USERMOD_BME280" in my_config.h
|
||||||
|
#ifdef USERMOD_BME280
|
||||||
|
#include "../usermods/BME280_v2/usermod_bme280.h"
|
||||||
|
#endif
|
||||||
#ifdef USERMOD_FOUR_LINE_DISLAY
|
#ifdef USERMOD_FOUR_LINE_DISLAY
|
||||||
#include "../usermods/usermod_v2_four_line_display/usermod_v2_four_line_display.h"
|
#include "../usermods/usermod_v2_four_line_display/usermod_v2_four_line_display.h"
|
||||||
#endif
|
#endif
|
||||||
@ -45,14 +52,21 @@ void registerUsermods()
|
|||||||
* || || ||
|
* || || ||
|
||||||
* \/ \/ \/
|
* \/ \/ \/
|
||||||
*/
|
*/
|
||||||
//usermods.add(new MyExampleUsermod());
|
//usermods.add(new MyExampleUsermod());
|
||||||
#ifdef USERMOD_DALLASTEMPERATURE
|
|
||||||
|
#ifdef USERMOD_DALLASTEMPERATURE
|
||||||
usermods.add(new UsermodTemperature());
|
usermods.add(new UsermodTemperature());
|
||||||
#endif
|
#endif
|
||||||
//usermods.add(new UsermodRenameMe());
|
|
||||||
#ifdef USERMOD_BUZZER
|
//usermods.add(new UsermodRenameMe());
|
||||||
|
|
||||||
|
#ifdef USERMOD_BUZZER
|
||||||
usermods.add(new BuzzerUsermod());
|
usermods.add(new BuzzerUsermod());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USERMOD_BME280
|
||||||
|
usermods.add(new UsermodBME280());
|
||||||
|
#endif
|
||||||
#ifdef USERMOD_SENSORSTOMQTT
|
#ifdef USERMOD_SENSORSTOMQTT
|
||||||
usermods.add(new UserMod_SensorsToMQTT());
|
usermods.add(new UserMod_SensorsToMQTT());
|
||||||
#endif
|
#endif
|
||||||
|
@ -58,6 +58,16 @@ ethernet_settings ethernetBoards[] = {
|
|||||||
17, // eth_mdio,
|
17, // eth_mdio,
|
||||||
ETH_PHY_LAN8720, // eth_type,
|
ETH_PHY_LAN8720, // eth_type,
|
||||||
ETH_CLOCK_GPIO0_IN // eth_clk_mode
|
ETH_CLOCK_GPIO0_IN // eth_clk_mode
|
||||||
|
},
|
||||||
|
|
||||||
|
// QuinLed-ESP32-Ethernet
|
||||||
|
{
|
||||||
|
0, // eth_address,
|
||||||
|
5, // eth_power,
|
||||||
|
23, // eth_mdc,
|
||||||
|
18, // eth_mdio,
|
||||||
|
ETH_PHY_LAN8720, // eth_type,
|
||||||
|
ETH_CLOCK_GPIO17_OUT // eth_clk_mode
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -126,7 +136,9 @@ void prepareHostname(char* hostname)
|
|||||||
//handle Ethernet connection event
|
//handle Ethernet connection event
|
||||||
void WiFiEvent(WiFiEvent_t event)
|
void WiFiEvent(WiFiEvent_t event)
|
||||||
{
|
{
|
||||||
|
#ifdef WLED_USE_ETHERNET
|
||||||
char hostname[25] = "wled-";
|
char hostname[25] = "wled-";
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
|
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
|
||||||
@ -205,10 +217,20 @@ void WLED::loop()
|
|||||||
handleHue();
|
handleHue();
|
||||||
handleBlynk();
|
handleBlynk();
|
||||||
|
|
||||||
/*if (presetToApply) {
|
//LED settings have been saved, re-init busses
|
||||||
applyPreset(presetToApply);
|
if (busConfigs[0] != nullptr) {
|
||||||
presetToApply = 0;
|
busses.removeAll();
|
||||||
}*/
|
uint32_t mem = 0;
|
||||||
|
for (uint8_t i = 0; i < WLED_MAX_BUSSES; i++) {
|
||||||
|
if (busConfigs[i] == nullptr) break;
|
||||||
|
mem += busses.memUsage(*busConfigs[i]);
|
||||||
|
if (mem <= MAX_LED_MEMORY) busses.add(*busConfigs[i]);
|
||||||
|
delete busConfigs[i]; busConfigs[i] = nullptr;
|
||||||
|
}
|
||||||
|
strip.finalizeInit(useRGBW, ledCount, skipFirstLed);
|
||||||
|
yield();
|
||||||
|
serializeConfig();
|
||||||
|
}
|
||||||
|
|
||||||
yield();
|
yield();
|
||||||
|
|
||||||
@ -226,6 +248,8 @@ void WLED::loop()
|
|||||||
if (millis() - lastMqttReconnectAttempt > 30000) {
|
if (millis() - lastMqttReconnectAttempt > 30000) {
|
||||||
if (lastMqttReconnectAttempt > millis()) rolloverMillis++; //millis() rolls over every 50 days
|
if (lastMqttReconnectAttempt > millis()) rolloverMillis++; //millis() rolls over every 50 days
|
||||||
initMqtt();
|
initMqtt();
|
||||||
|
refreshNodeList();
|
||||||
|
if (nodeBroadcastEnabled) sendSysInfoUDP();
|
||||||
}
|
}
|
||||||
yield();
|
yield();
|
||||||
handleWs();
|
handleWs();
|
||||||
@ -272,17 +296,16 @@ void WLED::setup()
|
|||||||
DEBUG_PRINT("esp8266 ");
|
DEBUG_PRINT("esp8266 ");
|
||||||
DEBUG_PRINTLN(ESP.getCoreVersion());
|
DEBUG_PRINTLN(ESP.getCoreVersion());
|
||||||
#endif
|
#endif
|
||||||
int heapPreAlloc = ESP.getFreeHeap();
|
|
||||||
DEBUG_PRINT("heap ");
|
DEBUG_PRINT("heap ");
|
||||||
DEBUG_PRINTLN(ESP.getFreeHeap());
|
DEBUG_PRINTLN(ESP.getFreeHeap());
|
||||||
registerUsermods();
|
registerUsermods();
|
||||||
|
|
||||||
//strip.init(EEPROM.read(372), ledCount, EEPROM.read(2204)); // init LEDs quickly
|
|
||||||
//strip.setBrightness(0);
|
|
||||||
|
|
||||||
//DEBUG_PRINT(F("LEDs inited. heap usage ~"));
|
//DEBUG_PRINT(F("LEDs inited. heap usage ~"));
|
||||||
//DEBUG_PRINTLN(heapPreAlloc - ESP.getFreeHeap());
|
//DEBUG_PRINTLN(heapPreAlloc - ESP.getFreeHeap());
|
||||||
|
|
||||||
|
#ifdef WLED_USE_DMX //reserve GPIO2 as hardcoded DMX pin
|
||||||
|
pinManager.allocatePin(2);
|
||||||
|
#endif
|
||||||
|
|
||||||
bool fsinit = false;
|
bool fsinit = false;
|
||||||
DEBUGFS_PRINTLN(F("Mount FS"));
|
DEBUGFS_PRINTLN(F("Mount FS"));
|
||||||
@ -298,7 +321,15 @@ void WLED::setup()
|
|||||||
updateFSInfo();
|
updateFSInfo();
|
||||||
deserializeConfig();
|
deserializeConfig();
|
||||||
|
|
||||||
#if STATUSLED && STATUSLED != LEDPIN
|
#if STATUSLED
|
||||||
|
bool lStatusLed = false;
|
||||||
|
for (uint8_t i=0; i<strip.numStrips; i++) {
|
||||||
|
if (strip.getStripPin(i)==STATUSLED) {
|
||||||
|
lStatusLed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!lStatusLed)
|
||||||
pinMode(STATUSLED, OUTPUT);
|
pinMode(STATUSLED, OUTPUT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -310,7 +341,9 @@ void WLED::setup()
|
|||||||
if (strcmp(clientSSID, DEFAULT_CLIENT_SSID) == 0)
|
if (strcmp(clientSSID, DEFAULT_CLIENT_SSID) == 0)
|
||||||
showWelcomePage = true;
|
showWelcomePage = true;
|
||||||
WiFi.persistent(false);
|
WiFi.persistent(false);
|
||||||
|
#ifdef WLED_USE_ETHERNET
|
||||||
WiFi.onEvent(WiFiEvent);
|
WiFi.onEvent(WiFiEvent);
|
||||||
|
#endif
|
||||||
|
|
||||||
Serial.println(F("Ada"));
|
Serial.println(F("Ada"));
|
||||||
|
|
||||||
@ -356,25 +389,14 @@ void WLED::setup()
|
|||||||
void WLED::beginStrip()
|
void WLED::beginStrip()
|
||||||
{
|
{
|
||||||
// Initialize NeoPixel Strip and button
|
// Initialize NeoPixel Strip and button
|
||||||
#ifdef ESP8266
|
|
||||||
#if LEDPIN == 3
|
|
||||||
if (ledCount > MAX_LEDS_DMA)
|
|
||||||
ledCount = MAX_LEDS_DMA; // DMA method uses too much ram
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (ledCount > MAX_LEDS || ledCount == 0)
|
if (ledCount > MAX_LEDS || ledCount == 0)
|
||||||
ledCount = 30;
|
ledCount = 30;
|
||||||
|
|
||||||
strip.init(useRGBW, ledCount, skipFirstLed);
|
strip.finalizeInit(useRGBW, ledCount, skipFirstLed);
|
||||||
strip.setBrightness(0);
|
strip.setBrightness(0);
|
||||||
strip.setShowCallback(handleOverlayDraw);
|
strip.setShowCallback(handleOverlayDraw);
|
||||||
|
|
||||||
#if defined(BTNPIN) && BTNPIN > -1
|
|
||||||
pinManager.allocatePin(BTNPIN, false);
|
|
||||||
pinMode(BTNPIN, INPUT_PULLUP);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (bootPreset > 0) applyPreset(bootPreset);
|
if (bootPreset > 0) applyPreset(bootPreset);
|
||||||
if (turnOnAtBoot) {
|
if (turnOnAtBoot) {
|
||||||
if (briS > 0) bri = briS;
|
if (briS > 0) bri = briS;
|
||||||
@ -384,24 +406,13 @@ void WLED::beginStrip()
|
|||||||
}
|
}
|
||||||
colorUpdated(NOTIFIER_CALL_MODE_INIT);
|
colorUpdated(NOTIFIER_CALL_MODE_INIT);
|
||||||
|
|
||||||
// init relay pin
|
// init relay pin
|
||||||
#if RLYPIN >= 0
|
if (rlyPin>=0)
|
||||||
pinManager.allocatePin(RLYPIN);
|
digitalWrite(rlyPin, (rlyMde ? bri : !bri));
|
||||||
pinMode(RLYPIN, OUTPUT);
|
|
||||||
#if RLYMDE
|
|
||||||
digitalWrite(RLYPIN, bri);
|
|
||||||
#else
|
|
||||||
digitalWrite(RLYPIN, !bri);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// disable button if it is "pressed" unintentionally
|
// disable button if it is "pressed" unintentionally
|
||||||
#if (defined(BTNPIN) && BTNPIN > -1) || defined(TOUCHPIN)
|
if (btnPin>=0 && isButtonPressed())
|
||||||
if (isButtonPressed())
|
|
||||||
buttonEnabled = false;
|
buttonEnabled = false;
|
||||||
#else
|
|
||||||
buttonEnabled = false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WLED::initAP(bool resetAP)
|
void WLED::initAP(bool resetAP)
|
||||||
@ -447,7 +458,7 @@ void WLED::initConnection()
|
|||||||
|
|
||||||
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
|
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
|
||||||
// Only initialize ethernet board if not NONE
|
// Only initialize ethernet board if not NONE
|
||||||
if (ethernetType != WLED_ETH_NONE) {
|
if (ethernetType != WLED_ETH_NONE && ethernetType < WLED_NUM_ETH_TYPES) {
|
||||||
ethernet_settings es = ethernetBoards[ethernetType];
|
ethernet_settings es = ethernetBoards[ethernetType];
|
||||||
ETH.begin(
|
ETH.begin(
|
||||||
(uint8_t) es.eth_address,
|
(uint8_t) es.eth_address,
|
||||||
@ -647,7 +658,13 @@ void WLED::handleConnection()
|
|||||||
|
|
||||||
void WLED::handleStatusLED()
|
void WLED::handleStatusLED()
|
||||||
{
|
{
|
||||||
#if STATUSLED && STATUSLED != LEDPIN
|
#if STATUSLED
|
||||||
|
for (uint8_t s=0; s<strip.numStrips; s++) {
|
||||||
|
if (strip.getStripPin(s)==STATUSLED) {
|
||||||
|
return; // pin used for strip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ledStatusType = WLED_CONNECTED ? 0 : 2;
|
ledStatusType = WLED_CONNECTED ? 0 : 2;
|
||||||
if (mqttEnabled && ledStatusType != 2) // Wi-Fi takes presendence over MQTT
|
if (mqttEnabled && ledStatusType != 2) // Wi-Fi takes presendence over MQTT
|
||||||
ledStatusType = WLED_MQTT_CONNECTED ? 0 : 4;
|
ledStatusType = WLED_MQTT_CONNECTED ? 0 : 4;
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
/*
|
/*
|
||||||
Main sketch, global variable declarations
|
Main sketch, global variable declarations
|
||||||
@title WLED project sketch
|
@title WLED project sketch
|
||||||
@version 0.11.1
|
@version 0.12.0-a0
|
||||||
@author Christian Schwinne
|
@author Christian Schwinne
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// version code in format yymmddb (b = daily build)
|
// version code in format yymmddb (b = daily build)
|
||||||
#define VERSION 2101130
|
#define VERSION 2103130
|
||||||
|
|
||||||
//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
|
||||||
@ -65,7 +65,9 @@
|
|||||||
#include <ESPmDNS.h>
|
#include <ESPmDNS.h>
|
||||||
#include <AsyncTCP.h>
|
#include <AsyncTCP.h>
|
||||||
//#include "SPIFFS.h"
|
//#include "SPIFFS.h"
|
||||||
|
#ifndef CONFIG_LITTLEFS_FOR_IDF_3_2
|
||||||
#define CONFIG_LITTLEFS_FOR_IDF_3_2
|
#define CONFIG_LITTLEFS_FOR_IDF_3_2
|
||||||
|
#endif
|
||||||
#include <LITTLEFS.h>
|
#include <LITTLEFS.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -115,6 +117,9 @@
|
|||||||
#include "FX.h"
|
#include "FX.h"
|
||||||
#include "ir_codes.h"
|
#include "ir_codes.h"
|
||||||
#include "const.h"
|
#include "const.h"
|
||||||
|
#include "NodeStruct.h"
|
||||||
|
#include "pin_manager.h"
|
||||||
|
#include "bus_manager.h"
|
||||||
|
|
||||||
#ifndef CLIENT_SSID
|
#ifndef CLIENT_SSID
|
||||||
#define CLIENT_SSID DEFAULT_CLIENT_SSID
|
#define CLIENT_SSID DEFAULT_CLIENT_SSID
|
||||||
@ -130,7 +135,7 @@
|
|||||||
Comment out this error message to build regardless.
|
Comment out this error message to build regardless.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if IRPIN < 0
|
#if !defined(IRPIN) || IRPIN < 0
|
||||||
#ifndef WLED_DISABLE_INFRARED
|
#ifndef WLED_DISABLE_INFRARED
|
||||||
#define WLED_DISABLE_INFRARED
|
#define WLED_DISABLE_INFRARED
|
||||||
#endif
|
#endif
|
||||||
@ -174,8 +179,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Global Variable definitions
|
// Global Variable definitions
|
||||||
WLED_GLOBAL char versionString[] _INIT("0.11.1");
|
WLED_GLOBAL char versionString[] _INIT("0.12.0-a0");
|
||||||
#define WLED_CODENAME "Mirai"
|
#define WLED_CODENAME "Hikari"
|
||||||
|
|
||||||
// AP and OTA default passwords (for maximum security change them!)
|
// AP and OTA default passwords (for maximum security change them!)
|
||||||
WLED_GLOBAL char apPass[65] _INIT(DEFAULT_AP_PASS);
|
WLED_GLOBAL char apPass[65] _INIT(DEFAULT_AP_PASS);
|
||||||
@ -183,13 +188,30 @@ WLED_GLOBAL char otaPass[33] _INIT(DEFAULT_OTA_PASS);
|
|||||||
|
|
||||||
// Hardware CONFIG (only changeble HERE, not at runtime)
|
// Hardware CONFIG (only changeble HERE, not at runtime)
|
||||||
// LED strip pin, button pin and IR pin changeable in NpbWrapper.h!
|
// LED strip pin, button pin and IR pin changeable in NpbWrapper.h!
|
||||||
|
#ifndef BTNPIN
|
||||||
|
WLED_GLOBAL int8_t btnPin _INIT(-1);
|
||||||
|
#else
|
||||||
|
WLED_GLOBAL int8_t btnPin _INIT(BTNPIN);
|
||||||
|
#endif
|
||||||
|
#ifndef RLYPIN
|
||||||
|
WLED_GLOBAL int8_t rlyPin _INIT(-1);
|
||||||
|
#else
|
||||||
|
WLED_GLOBAL int8_t rlyPin _INIT(RLYPIN);
|
||||||
|
#endif
|
||||||
|
//Relay mode (1 = active high, 0 = active low, flipped in cfg.json)
|
||||||
|
#ifndef RLYMDE
|
||||||
|
WLED_GLOBAL bool rlyMde _INIT(true);
|
||||||
|
#else
|
||||||
|
WLED_GLOBAL bool rlyMde _INIT(RLYMDE);
|
||||||
|
#endif
|
||||||
|
#ifndef IRPIN
|
||||||
|
WLED_GLOBAL int8_t irPin _INIT(-1);
|
||||||
|
#else
|
||||||
|
WLED_GLOBAL int8_t irPin _INIT(IRPIN);
|
||||||
|
#endif
|
||||||
|
|
||||||
//WLED_GLOBAL byte presetToApply _INIT(0);
|
//WLED_GLOBAL byte presetToApply _INIT(0);
|
||||||
|
|
||||||
#if AUXPIN >= 0
|
|
||||||
WLED_GLOBAL byte auxDefaultState _INIT(0); // 0: input 1: high 2: low
|
|
||||||
WLED_GLOBAL byte auxTriggeredState _INIT(0); // 0: input 1: high 2: low
|
|
||||||
#endif
|
|
||||||
WLED_GLOBAL char ntpServerName[33] _INIT("0.wled.pool.ntp.org"); // NTP server to use
|
WLED_GLOBAL char ntpServerName[33] _INIT("0.wled.pool.ntp.org"); // NTP server to use
|
||||||
|
|
||||||
// WiFi CONFIG (all these can be changed via web UI, no need to set them here)
|
// WiFi CONFIG (all these can be changed via web UI, no need to set them here)
|
||||||
@ -236,6 +258,10 @@ WLED_GLOBAL char serverDescription[33] _INIT("WLED"); // Name of module
|
|||||||
WLED_GLOBAL bool syncToggleReceive _INIT(false); // UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise
|
WLED_GLOBAL bool syncToggleReceive _INIT(false); // UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise
|
||||||
|
|
||||||
// Sync CONFIG
|
// Sync CONFIG
|
||||||
|
WLED_GLOBAL NodesMap Nodes;
|
||||||
|
WLED_GLOBAL bool nodeListEnabled _INIT(true);
|
||||||
|
WLED_GLOBAL bool nodeBroadcastEnabled _INIT(true);
|
||||||
|
|
||||||
WLED_GLOBAL bool buttonEnabled _INIT(true);
|
WLED_GLOBAL bool buttonEnabled _INIT(true);
|
||||||
WLED_GLOBAL byte irEnabled _INIT(0); // Infrared receiver
|
WLED_GLOBAL byte irEnabled _INIT(0); // Infrared receiver
|
||||||
|
|
||||||
@ -292,7 +318,7 @@ WLED_GLOBAL bool huePollingEnabled _INIT(false); // poll hue bridge fo
|
|||||||
WLED_GLOBAL uint16_t huePollIntervalMs _INIT(2500); // low values (< 1sec) may cause lag but offer quicker response
|
WLED_GLOBAL uint16_t huePollIntervalMs _INIT(2500); // low values (< 1sec) may cause lag but offer quicker response
|
||||||
WLED_GLOBAL char hueApiKey[47] _INIT("api"); // key token will be obtained from bridge
|
WLED_GLOBAL char hueApiKey[47] _INIT("api"); // key token will be obtained from bridge
|
||||||
WLED_GLOBAL byte huePollLightId _INIT(1); // ID of hue lamp to sync to. Find the ID in the hue app ("about" section)
|
WLED_GLOBAL byte huePollLightId _INIT(1); // ID of hue lamp to sync to. Find the ID in the hue app ("about" section)
|
||||||
WLED_GLOBAL IPAddress hueIP _INIT((0, 0, 0, 0)); // IP address of the bridge
|
WLED_GLOBAL IPAddress hueIP _INIT_N(((0, 0, 0, 0))); // IP address of the bridge
|
||||||
WLED_GLOBAL bool hueApplyOnOff _INIT(true);
|
WLED_GLOBAL bool hueApplyOnOff _INIT(true);
|
||||||
WLED_GLOBAL bool hueApplyBri _INIT(true);
|
WLED_GLOBAL bool hueApplyBri _INIT(true);
|
||||||
WLED_GLOBAL bool hueApplyColor _INIT(true);
|
WLED_GLOBAL bool hueApplyColor _INIT(true);
|
||||||
@ -455,23 +481,29 @@ WLED_GLOBAL int16_t currentPlaylist _INIT(0);
|
|||||||
// realtime
|
// realtime
|
||||||
WLED_GLOBAL byte realtimeMode _INIT(REALTIME_MODE_INACTIVE);
|
WLED_GLOBAL byte realtimeMode _INIT(REALTIME_MODE_INACTIVE);
|
||||||
WLED_GLOBAL byte realtimeOverride _INIT(REALTIME_OVERRIDE_NONE);
|
WLED_GLOBAL byte realtimeOverride _INIT(REALTIME_OVERRIDE_NONE);
|
||||||
WLED_GLOBAL IPAddress realtimeIP _INIT((0, 0, 0, 0));
|
WLED_GLOBAL IPAddress realtimeIP _INIT_N(((0, 0, 0, 0)));;
|
||||||
WLED_GLOBAL unsigned long realtimeTimeout _INIT(0);
|
WLED_GLOBAL unsigned long realtimeTimeout _INIT(0);
|
||||||
WLED_GLOBAL uint8_t tpmPacketCount _INIT(0);
|
WLED_GLOBAL uint8_t tpmPacketCount _INIT(0);
|
||||||
WLED_GLOBAL uint16_t tpmPayloadFrameSize _INIT(0);
|
WLED_GLOBAL uint16_t tpmPayloadFrameSize _INIT(0);
|
||||||
|
|
||||||
// mqtt
|
// mqtt
|
||||||
WLED_GLOBAL long lastMqttReconnectAttempt _INIT(0);
|
WLED_GLOBAL unsigned long lastMqttReconnectAttempt _INIT(0);
|
||||||
WLED_GLOBAL long lastInterfaceUpdate _INIT(0);
|
WLED_GLOBAL unsigned long lastInterfaceUpdate _INIT(0);
|
||||||
WLED_GLOBAL byte interfaceUpdateCallMode _INIT(NOTIFIER_CALL_MODE_INIT);
|
WLED_GLOBAL byte interfaceUpdateCallMode _INIT(NOTIFIER_CALL_MODE_INIT);
|
||||||
WLED_GLOBAL char mqttStatusTopic[40] _INIT(""); // this must be global because of async handlers
|
WLED_GLOBAL char mqttStatusTopic[40] _INIT(""); // this must be global because of async handlers
|
||||||
|
|
||||||
#if AUXPIN >= 0
|
// auxiliary debug pin
|
||||||
// auxiliary debug pin
|
#ifndef AUXPIN
|
||||||
WLED_GLOBAL byte auxTime _INIT(0);
|
WLED_GLOBAL int8_t auxPin _INIT(-1);
|
||||||
WLED_GLOBAL unsigned long auxStartTime _INIT(0);
|
#else
|
||||||
WLED_GLOBAL bool auxActive _INIT(false, auxActiveBefore _INIT(false);
|
WLED_GLOBAL int8_t auxPin _INIT(AUXPIN);
|
||||||
#endif
|
#endif
|
||||||
|
WLED_GLOBAL byte auxTime _INIT(0);
|
||||||
|
WLED_GLOBAL unsigned long auxStartTime _INIT(0);
|
||||||
|
WLED_GLOBAL bool auxActive _INIT(false);
|
||||||
|
WLED_GLOBAL bool auxActiveBefore _INIT(false);
|
||||||
|
WLED_GLOBAL byte auxDefaultState _INIT(0); // 0: input 1: high 2: low
|
||||||
|
WLED_GLOBAL byte auxTriggeredState _INIT(0); // 0: input 1: high 2: low
|
||||||
|
|
||||||
// alexa udp
|
// alexa udp
|
||||||
WLED_GLOBAL String escapedMac;
|
WLED_GLOBAL String escapedMac;
|
||||||
@ -504,7 +536,6 @@ WLED_GLOBAL JsonDocument* fileDoc;
|
|||||||
WLED_GLOBAL bool doCloseFile _INIT(false);
|
WLED_GLOBAL bool doCloseFile _INIT(false);
|
||||||
|
|
||||||
// presets
|
// presets
|
||||||
WLED_GLOBAL uint16_t savedPresets _INIT(0);
|
|
||||||
WLED_GLOBAL int16_t currentPreset _INIT(-1);
|
WLED_GLOBAL int16_t currentPreset _INIT(-1);
|
||||||
WLED_GLOBAL bool isPreset _INIT(false);
|
WLED_GLOBAL bool isPreset _INIT(false);
|
||||||
|
|
||||||
@ -531,15 +562,15 @@ WLED_GLOBAL ESPAsyncE131 e131 _INIT_N(((handleE131Packet)));
|
|||||||
WLED_GLOBAL bool e131NewData _INIT(false);
|
WLED_GLOBAL bool e131NewData _INIT(false);
|
||||||
|
|
||||||
// led fx library object
|
// led fx library object
|
||||||
|
WLED_GLOBAL BusManager busses _INIT(BusManager());
|
||||||
WLED_GLOBAL WS2812FX strip _INIT(WS2812FX());
|
WLED_GLOBAL WS2812FX strip _INIT(WS2812FX());
|
||||||
|
WLED_GLOBAL BusConfig* busConfigs[WLED_MAX_BUSSES]; //temporary, to remember values from network callback until after
|
||||||
|
|
||||||
// Usermod manager
|
// Usermod manager
|
||||||
WLED_GLOBAL UsermodManager usermods _INIT(UsermodManager());
|
WLED_GLOBAL UsermodManager usermods _INIT(UsermodManager());
|
||||||
|
|
||||||
WLED_GLOBAL PinManagerClass pinManager _INIT(PinManagerClass());
|
|
||||||
|
|
||||||
// Status LED
|
// Status LED
|
||||||
#if STATUSLED && STATUSLED != LEDPIN
|
#if STATUSLED
|
||||||
WLED_GLOBAL unsigned long ledStatusLastMillis _INIT(0);
|
WLED_GLOBAL unsigned long ledStatusLastMillis _INIT(0);
|
||||||
WLED_GLOBAL unsigned short ledStatusType _INIT(0); // current status type - corresponds to number of blinks per second
|
WLED_GLOBAL unsigned short ledStatusType _INIT(0); // current status type - corresponds to number of blinks per second
|
||||||
WLED_GLOBAL bool ledStatusState _INIT(0); // the current LED state
|
WLED_GLOBAL bool ledStatusState _INIT(0); // the current LED state
|
||||||
|
@ -39,9 +39,15 @@ void initServer()
|
|||||||
DefaultHeaders::Instance().addHeader(F("Access-Control-Allow-Methods"), "*");
|
DefaultHeaders::Instance().addHeader(F("Access-Control-Allow-Methods"), "*");
|
||||||
DefaultHeaders::Instance().addHeader(F("Access-Control-Allow-Headers"), "*");
|
DefaultHeaders::Instance().addHeader(F("Access-Control-Allow-Headers"), "*");
|
||||||
|
|
||||||
|
#ifdef WLED_ENABLE_WEBSOCKETS
|
||||||
|
server.on("/liveview", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
|
request->send_P(200, "text/html", PAGE_liveviewws);
|
||||||
|
});
|
||||||
|
#else
|
||||||
server.on("/liveview", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/liveview", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
request->send_P(200, "text/html", PAGE_liveview);
|
request->send_P(200, "text/html", PAGE_liveview);
|
||||||
});
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
//settings page
|
//settings page
|
||||||
server.on("/settings", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/settings", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
@ -239,7 +245,7 @@ bool handleIfNoneMatchCacheHeader(AsyncWebServerRequest* request)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool setStaticContentCacheHeaders(AsyncWebServerResponse *response)
|
void setStaticContentCacheHeaders(AsyncWebServerResponse *response)
|
||||||
{
|
{
|
||||||
response->addHeader(F("Cache-Control"),"max-age=2592000");
|
response->addHeader(F("Cache-Control"),"max-age=2592000");
|
||||||
response->addHeader(F("ETag"), String(VERSION));
|
response->addHeader(F("ETag"), String(VERSION));
|
||||||
|
@ -220,7 +220,7 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
sappend('c',SET_F("WS"),noWifiSleep);
|
sappend('c',SET_F("WS"),noWifiSleep);
|
||||||
|
|
||||||
#ifdef WLED_USE_ETHERNET
|
#ifdef WLED_USE_ETHERNET
|
||||||
sappend('i',SET_F("ETH"),ethernetType);
|
sappend('v',SET_F("ETH"),ethernetType);
|
||||||
#else
|
#else
|
||||||
//hide ethernet setting if not compiled in
|
//hide ethernet setting if not compiled in
|
||||||
oappend(SET_F("document.getElementById('ethd').style.display='none';"));
|
oappend(SET_F("document.getElementById('ethd').style.display='none';"));
|
||||||
@ -254,27 +254,72 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (subPage == 2) {
|
if (subPage == 2) {
|
||||||
#ifdef ESP8266
|
char nS[8];
|
||||||
#if LEDPIN == 3
|
|
||||||
oappend(SET_F("d.Sf.LC.max=500;"));
|
// add usermod pins as d.um_p array (TODO: usermod config shouldn't use state. instead we should load "um" object from cfg.json)
|
||||||
#else
|
/*DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||||
oappend(SET_F("d.Sf.LC.max=1500;"));
|
JsonObject mods = doc.createNestedObject(F("mods"));
|
||||||
#endif
|
usermods.addToJsonState(mods);
|
||||||
#endif
|
if (!mods.isNull()) {
|
||||||
|
uint8_t i=0;
|
||||||
|
oappend(SET_F("d.um_p=["));
|
||||||
|
for (JsonPair kv : mods) {
|
||||||
|
if (strncmp_P(kv.key().c_str(),PSTR("pin_"),4) == 0) {
|
||||||
|
if (i++) oappend(SET_F(","));
|
||||||
|
oappend(itoa((int)kv.value(),nS,10));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oappend(SET_F("];"));
|
||||||
|
}*/
|
||||||
|
|
||||||
|
oappend(SET_F("bLimits("));
|
||||||
|
oappend(itoa(WLED_MAX_BUSSES,nS,10));
|
||||||
|
oappend(",");
|
||||||
|
oappend(itoa(MAX_LEDS_PER_BUS,nS,10));
|
||||||
|
oappend(",");
|
||||||
|
oappend(itoa(MAX_LED_MEMORY,nS,10));
|
||||||
|
oappend(SET_F(");"));
|
||||||
|
|
||||||
|
oappend(SET_F("d.Sf.LC.max=")); //TODO Formula for max LEDs on ESP8266 depending on types. 500 DMA or 1500 UART (about 4kB mem usage)
|
||||||
|
oappendi(MAX_LEDS);
|
||||||
|
oappend(";");
|
||||||
|
|
||||||
sappend('v',SET_F("LC"),ledCount);
|
sappend('v',SET_F("LC"),ledCount);
|
||||||
|
|
||||||
|
for (uint8_t s=0; s < busses.getNumBusses(); s++){
|
||||||
|
Bus* bus = busses.getBus(s);
|
||||||
|
char lp[4] = "L0"; lp[2] = 48+s; lp[3] = 0; //ascii 0-9 //strip data pin
|
||||||
|
char lc[4] = "LC"; lc[2] = 48+s; lc[3] = 0; //strip length
|
||||||
|
char co[4] = "CO"; co[2] = 48+s; co[3] = 0; //strip color order
|
||||||
|
char lt[4] = "LT"; lt[2] = 48+s; lt[3] = 0; //strip type
|
||||||
|
char ls[4] = "LS"; ls[2] = 48+s; ls[3] = 0; //strip start LED
|
||||||
|
char cv[4] = "CV"; cv[2] = 48+s; cv[3] = 0; //strip reverse
|
||||||
|
oappend(SET_F("addLEDs(1);"));
|
||||||
|
uint8_t pins[5];
|
||||||
|
uint8_t nPins = bus->getPins(pins);
|
||||||
|
for (uint8_t i = 0; i < nPins; i++) {
|
||||||
|
lp[1] = 48+i;
|
||||||
|
if (pinManager.isPinOk(pins[i])) sappend('v', lp, pins[i]);
|
||||||
|
}
|
||||||
|
sappend('v', lc, bus->getLength());
|
||||||
|
sappend('v',lt,bus->getType());
|
||||||
|
sappend('v',co,bus->getColorOrder());
|
||||||
|
sappend('v',ls,bus->getStart());
|
||||||
|
sappend('c',cv,bus->reversed);
|
||||||
|
}
|
||||||
sappend('v',SET_F("MA"),strip.ablMilliampsMax);
|
sappend('v',SET_F("MA"),strip.ablMilliampsMax);
|
||||||
sappend('v',SET_F("LA"),strip.milliampsPerLed);
|
sappend('v',SET_F("LA"),strip.milliampsPerLed);
|
||||||
if (strip.currentMilliamps)
|
if (strip.currentMilliamps)
|
||||||
{
|
{
|
||||||
sappends('m',SET_F("(\"pow\")[0]"),"");
|
sappends('m',SET_F("(\"pow\")[0]"),(char*)"");
|
||||||
olen -= 2; //delete ";
|
olen -= 2; //delete ";
|
||||||
oappendi(strip.currentMilliamps);
|
oappendi(strip.currentMilliamps);
|
||||||
oappend(SET_F("mA\";"));
|
oappend(SET_F("mA\";"));
|
||||||
}
|
}
|
||||||
|
|
||||||
sappend('v',SET_F("CA"),briS);
|
sappend('v',SET_F("CA"),briS);
|
||||||
sappend('c',SET_F("EW"),useRGBW);
|
//sappend('c',SET_F("EW"),useRGBW);
|
||||||
sappend('i',SET_F("CO"),strip.getColorOrder());
|
//sappend('i',SET_F("CO"),strip.getColorOrder());
|
||||||
sappend('v',SET_F("AW"),strip.rgbwMode);
|
sappend('v',SET_F("AW"),strip.rgbwMode);
|
||||||
|
|
||||||
sappend('c',SET_F("BO"),turnOnAtBoot);
|
sappend('c',SET_F("BO"),turnOnAtBoot);
|
||||||
@ -292,6 +337,11 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
sappend('i',SET_F("PB"),strip.paletteBlend);
|
sappend('i',SET_F("PB"),strip.paletteBlend);
|
||||||
sappend('c',SET_F("RV"),strip.reverseMode);
|
sappend('c',SET_F("RV"),strip.reverseMode);
|
||||||
sappend('c',SET_F("SL"),skipFirstLed);
|
sappend('c',SET_F("SL"),skipFirstLed);
|
||||||
|
sappend('v',SET_F("RL"),rlyPin);
|
||||||
|
sappend('c',SET_F("RM"),rlyMde);
|
||||||
|
sappend('v',SET_F("BT"),btnPin);
|
||||||
|
sappend('v',SET_F("IR"),irPin);
|
||||||
|
sappend('v',SET_F("AX"),auxPin);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subPage == 3)
|
if (subPage == 3)
|
||||||
@ -314,6 +364,10 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
sappend('c',SET_F("SH"),notifyHue);
|
sappend('c',SET_F("SH"),notifyHue);
|
||||||
sappend('c',SET_F("SM"),notifyMacro);
|
sappend('c',SET_F("SM"),notifyMacro);
|
||||||
sappend('c',SET_F("S2"),notifyTwice);
|
sappend('c',SET_F("S2"),notifyTwice);
|
||||||
|
|
||||||
|
sappend('c',SET_F("NL"),nodeListEnabled);
|
||||||
|
sappend('c',SET_F("NB"),nodeBroadcastEnabled);
|
||||||
|
|
||||||
sappend('c',SET_F("RD"),receiveDirect);
|
sappend('c',SET_F("RD"),receiveDirect);
|
||||||
sappend('v',SET_F("EP"),e131Port);
|
sappend('v',SET_F("EP"),e131Port);
|
||||||
sappend('c',SET_F("ES"),e131SkipOutOfSequence);
|
sappend('c',SET_F("ES"),e131SkipOutOfSequence);
|
||||||
|
Loading…
Reference in New Issue
Block a user