diff --git a/CHANGELOG.md b/CHANGELOG.md index e2ef83e6..d83f625f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ ### Builds after release 0.12.0 +#### Build 2201260 + +- Initial ESP32-C3 and ESP32-S2 support (PRs #2452, ) +- Full segment sync (PR #2427) +- Allow overriding of color order by ranges (PR #2463) +- Added white channel to Peek + #### Build 2112080 - Version bump to 0.13.0-b6 "Toki" diff --git a/platformio.ini b/platformio.ini index faa6f162..e52fecd4 100644 --- a/platformio.ini +++ b/platformio.ini @@ -12,7 +12,7 @@ ; default_envs = travis_esp8266, travis_esp32 # Release binaries -default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, esp32dev, esp32_eth +default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, esp32dev, esp32_eth, esp32s2_saola, esp32c3 # Build everything ; default_envs = esp32dev, esp8285_4CH_MagicHome, esp8285_4CH_H801, codm-controller-0.6-rev2, codm-controller-0.6, esp32s2_saola, d1_mini_5CH_Shojo_PCB, d1_mini, sp501e, travis_esp8266, travis_esp32, nodemcuv2, esp32_eth, anavi_miracle_controller, esp07, esp01_1m_full, m5atom, h803wf, d1_mini_ota, heltec_wifi_kit_8, esp8285_5CH_H801, d1_mini_debug, wemos_shield_esp32, elekstube_ips @@ -54,13 +54,14 @@ extra_configs = arduino_core_2_6_3 = espressif8266@2.3.3 arduino_core_2_7_4 = espressif8266@2.6.2 arduino_core_3_0_0 = espressif8266@3.0.0 +arduino_core_3_0_2 = espressif8266@3.2.0 # Development platforms arduino_core_develop = https://github.com/platformio/platform-espressif8266#develop arduino_core_git = https://github.com/platformio/platform-espressif8266#feature/stage # Platform to use for ESP8266 -platform_wled_default = ${common.arduino_core_2_7_4} +platform_wled_default = ${common.arduino_core_3_0_2} # We use 2.7.4.7 for all, includes PWM flicker fix and Wstring optimization platform_packages = tasmota/framework-arduinoespressif8266 @ 3.20704.7 platformio/toolchain-xtensa @ ~2.40802.200502 @@ -105,6 +106,7 @@ build_flags = -DBEARSSL_SSL_BASIC -D CORE_DEBUG_LEVEL=0 -D NDEBUG + -Dregister= #build_flags for the IRremoteESP8266 library (enabled decoders have to appear here) -D _IR_ENABLE_DEFAULT_=false -D DECODE_HASH=true @@ -160,10 +162,9 @@ upload_speed = 115200 # ------------------------------------------------------------------------------ lib_compat_mode = strict lib_deps = - fastled/FastLED @ 3.4.0 - IRremoteESP8266 @ 2.7.18 - https://github.com/lorol/LITTLEFS.git - https://github.com/Aircoookie/ESPAsyncWebServer.git @ ~2.0.2 + fastled/FastLED @ 3.5.0 + IRremoteESP8266 @ 2.8.1 + https://github.com/Aircoookie/ESPAsyncWebServer.git @ ~2.0.4 #For use of the TTGO T-Display ESP32 Module with integrated TFT display uncomment the following line #TFT_eSPI #For use SSD1306 OLED display uncomment following @@ -185,6 +186,7 @@ build_flags = -DFP_IN_IROM ;-Wno-deprecated-declarations ;-Wno-register + -Wno-misleading-indentation ; NONOSDK22x_190703 = 2.2.2-dev(38a443e) -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190703 ; lwIP 2 - Higher Bandwidth no Features @@ -198,6 +200,7 @@ build_flags = lib_deps = ${env.lib_deps} + https://github.com/lorol/LITTLEFS.git # ESPAsyncTCP @ 1.2.0 ESPAsyncUDP makuna/NeoPixelBus @ 2.6.7 # 2.6.5/2.6.6 and newer do not compile on ESP core < 3.0.0 @@ -212,13 +215,13 @@ default_partitions = tools/WLED_ESP32_4MB_1MB_FS.csv lib_deps = ${env.lib_deps} + https://github.com/lorol/LITTLEFS.git makuna/NeoPixelBus @ 2.6.7 https://github.com/pbolduc/AsyncTCP.git @ 1.2.0 [esp32s2] build_flags = -g -DARDUINO_ARCH_ESP32 - -DCONFIG_LITTLEFS_FOR_IDF_3_2 -DARDUINO_ARCH_ESP32S2 -DCONFIG_IDF_TARGET_ESP32S2 -D CONFIG_ASYNC_TCP_USE_WDT=0 @@ -229,6 +232,19 @@ lib_deps = makuna/NeoPixelBus @ 2.6.7 https://github.com/pbolduc/AsyncTCP.git @ 1.2.0 +[esp32c3] +build_flags = -g + -DARDUINO_ARCH_ESP32 + -DARDUINO_ARCH_ESP32C3 + -DCONFIG_IDF_TARGET_ESP32C3 + -D CONFIG_ASYNC_TCP_USE_WDT=0 + -DCO + +lib_deps = + ${env.lib_deps} + makuna/NeoPixelBus @ 2.6.7 + https://github.com/pbolduc/AsyncTCP.git @ 1.2.0 + # ------------------------------------------------------------------------------ # WLED BUILDS # ------------------------------------------------------------------------------ @@ -314,17 +330,25 @@ lib_deps = ${esp32.lib_deps} board_build.partitions = ${esp32.default_partitions} [env:esp32s2_saola] -board = esp32dev -board_build.mcu = esp32s2 -platform = espressif32 +board = esp32-s2-saola-1 +platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.2.1/platform-tasmota-espressif32-2.0.2.1.zip +platform_packages = +framework = arduino +board_build.partitions = tools/WLED_ESP32_4MB_1MB_FS.csv +board_build.flash_mode = qio +upload_speed = 460800 +build_unflags = ${common.build_unflags} +lib_deps = ${esp32s2.lib_deps} + +[env:esp32c3] +board = esp32-c3-devkitm-1 +platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.2.1/platform-tasmota-espressif32-2.0.2.1.zip platform_packages = - toolchain-xtensa32s2 - framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.0-alpha1 framework = arduino board_build.partitions = tools/WLED_ESP32_4MB_1MB_FS.csv upload_speed = 460800 build_unflags = ${common.build_unflags} -lib_deps = ${esp32s2.lib_deps} +lib_deps = ${esp32c3.lib_deps} [env:esp8285_4CH_MagicHome] board = esp8285 diff --git a/tools/cdata.js b/tools/cdata.js index ff5506c6..15455a42 100644 --- a/tools/cdata.js +++ b/tools/cdata.js @@ -217,7 +217,7 @@ writeChunks( mangle: (str) => str .replace("%", "%%") - .replace(/User Interface\<\/button\>\<\/form\>/gms, "User Interface\<\/button\>\<\/form\>%DMXMENU%"), + .replace(/Usermods\<\/button\>\<\/form\>/gms, "Usermods\<\/button\>\<\/form\>%DMXMENU%"), }, { file: "settings_wifi.htm", diff --git a/usermods/Animated_Staircase/Animated_Staircase.h b/usermods/Animated_Staircase/Animated_Staircase.h index 3bf9fdd3..35ea0d7a 100644 --- a/usermods/Animated_Staircase/Animated_Staircase.h +++ b/usermods/Animated_Staircase/Animated_Staircase.h @@ -111,17 +111,17 @@ class Animated_Staircase : public Usermod { } if (i >= onIndex && i < offIndex) { - segments->setOption(SEG_OPTION_ON, 1, 1); + segments->setOption(SEG_OPTION_ON, 1, i); // 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); + segments->setOption(SEG_OPTION_ON, 0, i); } // Always mark segments as "transitional", we are animating the staircase - segments->setOption(SEG_OPTION_TRANSITIONAL, 1, 1); + segments->setOption(SEG_OPTION_TRANSITIONAL, 1, i); } colorUpdated(CALL_MODE_DIRECT_CHANGE); } @@ -296,7 +296,7 @@ class Animated_Staircase : public Usermod { maxSegmentId = i - 1; break; } - segments->setOption(SEG_OPTION_ON, 1, 1); + segments->setOption(SEG_OPTION_ON, 1, i); } colorUpdated(CALL_MODE_DIRECT_CHANGE); DEBUG_PRINTLN(F("Animated Staircase disabled.")); diff --git a/usermods/ESP32_TouchBrightnessControl/readme.md b/usermods/ESP32_TouchBrightnessControl/readme.md deleted file mode 100644 index f210b332..00000000 --- a/usermods/ESP32_TouchBrightnessControl/readme.md +++ /dev/null @@ -1,19 +0,0 @@ -# ESP32 Touch Brightness Control - -Toggle On/Off with a long press (800ms) -Switch through 5 brightness levels (defined in usermod_touchbrightness.h, values 0-255) with a short (100ms) touch - -## Installation - -Copy 'usermod_touchbrightness.h' to the wled00 directory. -in 'usermod_list.cpp' add this: - -> #include "usermod_touchbrightness.h" -above "void registerUsermods()" - -and - -> usermods.add(new TouchBrightnessControl()); -inside the "registerUsermods()" function - - diff --git a/usermods/ESP32_TouchBrightnessControl/usermod_touchbrightness.h b/usermods/ESP32_TouchBrightnessControl/usermod_touchbrightness.h deleted file mode 100644 index 1b779592..00000000 --- a/usermods/ESP32_TouchBrightnessControl/usermod_touchbrightness.h +++ /dev/null @@ -1,89 +0,0 @@ -// -// usermod_touchbrightness.h -// github.com/aircoookie/WLED -// -// Created by Justin Kühner on 14.09.2020. -// Copyright © 2020 NeariX. All rights reserved. -// https://github.com/NeariX67/ -// Discord: @NeariX#4799 - - -#pragma once - -#include "wled.h" - -#define threshold 40 //Increase value if touches falsely accur. Decrease value if actual touches are not recognized -#define touchPin T0 //T0 = D4 / GPIO4 - -//Define the 5 brightness levels -//Long press to turn off / on -#define brightness1 51 -#define brightness2 102 -#define brightness3 153 -#define brightness4 204 -#define brightness5 255 - - -#ifdef ESP32 - - -class TouchBrightnessControl : public Usermod { - private: - unsigned long lastTime = 0; //Interval - unsigned long lastTouch = 0; //Timestamp of last Touch - unsigned long lastRelease = 0; //Timestamp of last Touch release - boolean released = true; //current Touch state (touched/released) - uint16_t touchReading = 0; //sensor reading, maybe use uint8_t??? - uint16_t touchDuration = 0; //duration of last touch - public: - - void setup() { - lastTouch = millis(); - lastRelease = millis(); - lastTime = millis(); - } - - void loop() { - if (millis() - lastTime >= 50) { //Check every 50ms if a touch occurs - lastTime = millis(); - touchReading = touchRead(touchPin); //Read touch sensor on pin T0 (GPIO4 / D4) - - if(touchReading < threshold && released) { //Touch started - released = false; - lastTouch = millis(); - } - else if(touchReading >= threshold && !released) { //Touch released - released = true; - lastRelease = millis(); - touchDuration = lastRelease - lastTouch; //Calculate duration - } - - //Serial.println(touchDuration); - - if(touchDuration >= 800 && released) { //Toggle power if button press is longer than 800ms - touchDuration = 0; //Reset touch duration to avoid multiple actions on same touch - toggleOnOff(); - colorUpdated(2); //Refresh values - } - else if(touchDuration >= 100 && released) { //Switch to next brightness if touch is between 100 and 800ms - touchDuration = 0; //Reset touch duration to avoid multiple actions on same touch - if(bri < brightness1) { - bri = brightness1; - } else if(bri >= brightness1 && bri < brightness2) { - bri = brightness2; - } else if(bri >= brightness2 && bri < brightness3) { - bri = brightness3; - } else if(bri >= brightness3 && bri < brightness4) { - bri = brightness4; - } else if(bri >= brightness4 && bri < brightness5) { - bri = brightness5; - } else if(bri >= brightness5) { - bri = brightness1; - } - colorUpdated(2); //Refresh values - } - - } - } -}; -#endif diff --git a/usermods/PIR_sensor_mqtt_v1/README.md b/usermods/PIR_sensor_mqtt_v1/README.md deleted file mode 100644 index 475c11b0..00000000 --- a/usermods/PIR_sensor_mqtt_v1/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# PIR sensor with MQTT - -This simple usermod allows attaching a PIR sensor like the AM312 and publish the readings over MQTT. A message is sent when motion is detected as well as when motion has stopped. - -This usermod has only been tested with the AM312 sensor though should work for any other PIR sensor. Note that this does not control the LED strip directly, it only publishes MQTT readings for use with other integrations like Home Assistant. - -## Installation - -Copy and replace the file `usermod.cpp` in wled00 directory. diff --git a/usermods/PIR_sensor_mqtt_v1/usermod.cpp b/usermods/PIR_sensor_mqtt_v1/usermod.cpp deleted file mode 100644 index 426a8033..00000000 --- a/usermods/PIR_sensor_mqtt_v1/usermod.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "wled.h" -/* - * This v1 usermod file allows you to add own functionality to WLED more easily - * See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality - * EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in const.h) - * If you just need 8 bytes, use 2551-2559 (you do not need to increase EEPSIZE) - * - * Consider the v2 usermod API if you need a more advanced feature set! - */ - -//Use userVar0 and userVar1 (API calls &U0=,&U1=, uint16_t) - -// PIR sensor pin -const int MOTION_PIN = 16; - // MQTT topic for sensor values -const char MQTT_TOPIC[] = "/motion"; - -int prevState = LOW; - -//gets called once at boot. Do all initialization that doesn't depend on network here -void userSetup() -{ - pinMode(MOTION_PIN, INPUT); -} - -//gets called every time WiFi is (re-)connected. Initialize own network interfaces here -void userConnected() -{ - -} - -void publishMqtt(String state) -{ - //Check if MQTT Connected, otherwise it will crash the 8266 - if (mqtt != nullptr){ - char subuf[38]; - strcpy(subuf, mqttDeviceTopic); - strcat(subuf, MQTT_TOPIC); - mqtt->publish(subuf, 0, true, state.c_str()); - } -} - -//loop. You can use "if (WLED_CONNECTED)" to check for successful connection -void userLoop() -{ - if (digitalRead(MOTION_PIN) == HIGH && prevState == LOW) { // Motion detected - publishMqtt("ON"); - prevState = HIGH; - } - if (digitalRead(MOTION_PIN) == LOW && prevState == HIGH) { // Motion stopped - publishMqtt("OFF"); - prevState = LOW; - } -} - diff --git a/usermods/ST7789_display/README.md b/usermods/ST7789_display/README.md index 653fdd75..b98d5be0 100644 --- a/usermods/ST7789_display/README.md +++ b/usermods/ST7789_display/README.md @@ -12,7 +12,7 @@ This usermod allow to use 240x240 display to display following: ## Hardware *** -![Hardware](images/ST7789_guide.jpg) +![Hardware](images/ST7789_Guide.jpg) ## Library used diff --git a/usermods/esp32_multistrip/NpbWrapper.h b/usermods/esp32_multistrip/NpbWrapper.h deleted file mode 100644 index 84cf8ac0..00000000 --- a/usermods/esp32_multistrip/NpbWrapper.h +++ /dev/null @@ -1,515 +0,0 @@ -//this code is a modified version of https://github.com/Makuna/NeoPixelBus/issues/103 -#ifndef NpbWrapper_h -#define NpbWrapper_h - -// make sure we're using esp32 platform -#ifndef ARDUINO_ARCH_ESP32 - #error This version of NbpWrapper.h only works with ESP32 hardware. -#endif - -#ifndef NUM_STRIPS - #error Need to define number of LED strips using build flag -D NUM_STRIPS=4 for 4 LED strips -#endif - -#ifndef PIXEL_COUNTS - #error Need to define pixel counts using build flag -D PIXEL_COUNTS="25, 25, 25, 25" for 4 LED strips with 25 LEDs each -#endif - -#ifndef DATA_PINS - #error Need to define data pins using build flag -D DATA_PINS="1, 2, 3, 4" if LED strips are on data pins 1, 2, 3, and 4 -#endif - -// //PIN CONFIGURATION -#ifndef LEDPIN - #define LEDPIN 1 // Legacy pin def required by some other portions of code. This pin is not used do drive LEDs. -#endif - -#ifndef IRPIN - #define IRPIN -1 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0 -#endif - -#ifndef RLYPIN - #define RLYPIN -1 //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 - -#include -#include "const.h" - -const uint8_t numStrips = NUM_STRIPS; // max 8 strips allowed on esp32 -const uint16_t pixelCounts[numStrips] = {PIXEL_COUNTS}; // number of pixels on each strip -const uint8_t dataPins[numStrips] = {DATA_PINS}; // change these pins based on your board - -#define PIXELFEATURE3 NeoGrbFeature -#define PIXELFEATURE4 NeoGrbwFeature - -// ESP32 has 8 RMT interfaces available, each of which can drive a strip of pixels -// Convenience #defines for creating NeoPixelBrightnessBus on each RMT interface for both GRB and GRBW LED strips -#define NeoPixelBrightnessBusGrbRmt0 NeoPixelBrightnessBus -#define NeoPixelBrightnessBusGrbRmt1 NeoPixelBrightnessBus -#define NeoPixelBrightnessBusGrbRmt2 NeoPixelBrightnessBus -#define NeoPixelBrightnessBusGrbRmt3 NeoPixelBrightnessBus -#define NeoPixelBrightnessBusGrbRmt4 NeoPixelBrightnessBus -#define NeoPixelBrightnessBusGrbRmt5 NeoPixelBrightnessBus -#define NeoPixelBrightnessBusGrbRmt6 NeoPixelBrightnessBus -#define NeoPixelBrightnessBusGrbRmt7 NeoPixelBrightnessBus -#define NeoPixelBrightnessBusGrbwRmt0 NeoPixelBrightnessBus -#define NeoPixelBrightnessBusGrbwRmt1 NeoPixelBrightnessBus -#define NeoPixelBrightnessBusGrbwRmt2 NeoPixelBrightnessBus -#define NeoPixelBrightnessBusGrbwRmt3 NeoPixelBrightnessBus -#define NeoPixelBrightnessBusGrbwRmt4 NeoPixelBrightnessBus -#define NeoPixelBrightnessBusGrbwRmt5 NeoPixelBrightnessBus -#define NeoPixelBrightnessBusGrbwRmt6 NeoPixelBrightnessBus -#define NeoPixelBrightnessBusGrbwRmt7 NeoPixelBrightnessBus - -enum NeoPixelType -{ - NeoPixelType_None = 0, - NeoPixelType_Grb = 1, - NeoPixelType_Grbw = 2, - NeoPixelType_End = 3 -}; - -class NeoPixelWrapper -{ -public: - NeoPixelWrapper() : - _type(NeoPixelType_None) - { - // On initialization fill in the pixelStripStartIdx array with the beginning index of each strip - // relative to th entire array. - uint16_t totalPixels = 0; - for (uint8_t idx = 0; idx < numStrips; idx++) - { - pixelStripStartIdx[idx] = totalPixels; - totalPixels += pixelCounts[idx]; - } - } - - ~NeoPixelWrapper() - { - cleanup(); - } - - void Begin(NeoPixelType type, uint16_t pixelCount) - { - - cleanup(); - - _type = type; - - switch (_type) - { - case NeoPixelType_Grb: - { - for (uint8_t idx = 0; idx < numStrips; idx++) - { - switch (idx) - { - case 0: pGrb0 = new NeoPixelBrightnessBusGrbRmt0(pixelCounts[idx], dataPins[idx]); pGrb0->Begin(); break; - case 1: pGrb1 = new NeoPixelBrightnessBusGrbRmt1(pixelCounts[idx], dataPins[idx]); pGrb1->Begin(); break; - case 2: pGrb2 = new NeoPixelBrightnessBusGrbRmt2(pixelCounts[idx], dataPins[idx]); pGrb2->Begin(); break; - case 3: pGrb3 = new NeoPixelBrightnessBusGrbRmt3(pixelCounts[idx], dataPins[idx]); pGrb3->Begin(); break; - case 4: pGrb4 = new NeoPixelBrightnessBusGrbRmt4(pixelCounts[idx], dataPins[idx]); pGrb4->Begin(); break; - case 5: pGrb5 = new NeoPixelBrightnessBusGrbRmt5(pixelCounts[idx], dataPins[idx]); pGrb5->Begin(); break; - case 6: pGrb6 = new NeoPixelBrightnessBusGrbRmt6(pixelCounts[idx], dataPins[idx]); pGrb6->Begin(); break; - case 7: pGrb7 = new NeoPixelBrightnessBusGrbRmt7(pixelCounts[idx], dataPins[idx]); pGrb7->Begin(); break; - } - } - break; - } - - case NeoPixelType_Grbw: - { - for (uint8_t idx = 0; idx < numStrips; idx++) - { - switch (idx) - { - case 0: pGrbw0 = new NeoPixelBrightnessBusGrbwRmt0(pixelCounts[idx], dataPins[idx]); pGrbw0->Begin(); break; - case 1: pGrbw1 = new NeoPixelBrightnessBusGrbwRmt1(pixelCounts[idx], dataPins[idx]); pGrbw1->Begin(); break; - case 2: pGrbw2 = new NeoPixelBrightnessBusGrbwRmt2(pixelCounts[idx], dataPins[idx]); pGrbw2->Begin(); break; - case 3: pGrbw3 = new NeoPixelBrightnessBusGrbwRmt3(pixelCounts[idx], dataPins[idx]); pGrbw3->Begin(); break; - case 4: pGrbw4 = new NeoPixelBrightnessBusGrbwRmt4(pixelCounts[idx], dataPins[idx]); pGrbw4->Begin(); break; - case 5: pGrbw5 = new NeoPixelBrightnessBusGrbwRmt5(pixelCounts[idx], dataPins[idx]); pGrbw5->Begin(); break; - case 6: pGrbw6 = new NeoPixelBrightnessBusGrbwRmt6(pixelCounts[idx], dataPins[idx]); pGrbw6->Begin(); break; - case 7: pGrbw7 = new NeoPixelBrightnessBusGrbwRmt7(pixelCounts[idx], dataPins[idx]); pGrbw7->Begin(); break; - } - } - break; - } - } - } - - void Show() - { - switch (_type) - { - case NeoPixelType_Grb: - { - for (uint8_t idx = 0; idx < numStrips; idx++) - { - switch (idx) - { - case 0: pGrb0->Show(); break; - case 1: pGrb1->Show(); break; - case 2: pGrb2->Show(); break; - case 3: pGrb3->Show(); break; - case 4: pGrb4->Show(); break; - case 5: pGrb5->Show(); break; - case 6: pGrb6->Show(); break; - case 7: pGrb7->Show(); break; - } - } - break; - } - case NeoPixelType_Grbw: - { - for (uint8_t idx = 0; idx < numStrips; idx++) - { - switch (idx) - { - case 0: pGrbw0->Show(); break; - case 1: pGrbw1->Show(); break; - case 2: pGrbw2->Show(); break; - case 3: pGrbw3->Show(); break; - case 4: pGrbw4->Show(); break; - case 5: pGrbw5->Show(); break; - case 6: pGrbw6->Show(); break; - case 7: pGrbw7->Show(); break; - } - } - break; - } - } - } - - bool CanShow() - { - bool canShow = true; - switch (_type) - { - case NeoPixelType_Grb: - { - for (uint8_t idx = 0; idx < numStrips; idx++) - { - switch (idx) - { - case 0: canShow &= pGrb0->CanShow(); break; - case 1: canShow &= pGrb1->CanShow(); break; - case 2: canShow &= pGrb2->CanShow(); break; - case 3: canShow &= pGrb3->CanShow(); break; - case 4: canShow &= pGrb4->CanShow(); break; - case 5: canShow &= pGrb5->CanShow(); break; - case 6: canShow &= pGrb6->CanShow(); break; - case 7: canShow &= pGrb7->CanShow(); break; - } - } - break; - } - case NeoPixelType_Grbw: - { - for (uint8_t idx = 0; idx < numStrips; idx++) - { - switch (idx) - { - case 0: canShow &= pGrbw0->CanShow(); break; - case 1: canShow &= pGrbw1->CanShow(); break; - case 2: canShow &= pGrbw2->CanShow(); break; - case 3: canShow &= pGrbw3->CanShow(); break; - case 4: canShow &= pGrbw4->CanShow(); break; - case 5: canShow &= pGrbw5->CanShow(); break; - case 6: canShow &= pGrbw6->CanShow(); break; - case 7: canShow &= pGrbw7->CanShow(); break; - } - } - break; - } - } - return canShow; - } - - void SetPixelColorRaw(uint16_t indexPixel, RgbwColor c) - { - // figure out which strip this pixel index is on - uint8_t stripIdx = 0; - for (uint8_t idx = 0; idx < numStrips; idx++) - { - if (indexPixel >= pixelStripStartIdx[idx]) - { - stripIdx = idx; - } - else - { - break; - } - } - // subtract strip start index so we're addressing just this strip instead of all pixels on all strips - indexPixel -= pixelStripStartIdx[stripIdx]; - switch (_type) - { - case NeoPixelType_Grb: - { - RgbColor rgb = RgbColor(c.R, c.G, c.B); - switch (stripIdx) - { - case 0: pGrb0->SetPixelColor(indexPixel, rgb); break; - case 1: pGrb1->SetPixelColor(indexPixel, rgb); break; - case 2: pGrb2->SetPixelColor(indexPixel, rgb); break; - case 3: pGrb3->SetPixelColor(indexPixel, rgb); break; - case 4: pGrb4->SetPixelColor(indexPixel, rgb); break; - case 5: pGrb5->SetPixelColor(indexPixel, rgb); break; - case 6: pGrb6->SetPixelColor(indexPixel, rgb); break; - case 7: pGrb7->SetPixelColor(indexPixel, rgb); break; - } - break; - } - case NeoPixelType_Grbw: - { - switch (stripIdx) - { - case 0: pGrbw0->SetPixelColor(indexPixel, c); break; - case 1: pGrbw1->SetPixelColor(indexPixel, c); break; - case 2: pGrbw2->SetPixelColor(indexPixel, c); break; - case 3: pGrbw3->SetPixelColor(indexPixel, c); break; - case 4: pGrbw4->SetPixelColor(indexPixel, c); break; - case 5: pGrbw5->SetPixelColor(indexPixel, c); break; - case 6: pGrbw6->SetPixelColor(indexPixel, c); break; - case 7: pGrbw7->SetPixelColor(indexPixel, c); break; - } - break; - } - } - } - - void SetPixelColor(uint16_t indexPixel, RgbwColor c) - { - /* - Set pixel color with necessary color order conversion. - */ - - 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; - - SetPixelColorRaw(indexPixel, col); - } - - void SetBrightness(byte b) - { - switch (_type) - { - case NeoPixelType_Grb: - { - for (uint8_t idx = 0; idx < numStrips; idx++) - { - switch (idx) - { - case 0: pGrb0->SetBrightness(b); break; - case 1: pGrb1->SetBrightness(b); break; - case 2: pGrb2->SetBrightness(b); break; - case 3: pGrb3->SetBrightness(b); break; - case 4: pGrb4->SetBrightness(b); break; - case 5: pGrb5->SetBrightness(b); break; - case 6: pGrb6->SetBrightness(b); break; - case 7: pGrb7->SetBrightness(b); break; - } - } - break; - } - case NeoPixelType_Grbw: - { - for (uint8_t idx = 0; idx < numStrips; idx++) - { - switch (idx) - { - case 0: pGrbw0->SetBrightness(b); break; - case 1: pGrbw1->SetBrightness(b); break; - case 2: pGrbw2->SetBrightness(b); break; - case 3: pGrbw3->SetBrightness(b); break; - case 4: pGrbw4->SetBrightness(b); break; - case 5: pGrbw5->SetBrightness(b); break; - case 6: pGrbw6->SetBrightness(b); break; - case 7: pGrbw7->SetBrightness(b); break; - } - } - break; - } - } - } - - void SetColorOrder(byte colorOrder) - { - _colorOrder = colorOrder; - } - - uint8_t GetColorOrder() - { - return _colorOrder; - } - - RgbwColor GetPixelColorRaw(uint16_t indexPixel) const - { - // figure out which strip this pixel index is on - uint8_t stripIdx = 0; - for (uint8_t idx = 0; idx < numStrips; idx++) - { - if (indexPixel >= pixelStripStartIdx[idx]) - { - stripIdx = idx; - } - else - { - break; - } - } - // subtract strip start index so we're addressing just this strip instead of all pixels on all strips - indexPixel -= pixelStripStartIdx[stripIdx]; - switch (_type) - { - case NeoPixelType_Grb: - { - switch (stripIdx) - { - case 0: return pGrb0->GetPixelColor(indexPixel); - case 1: return pGrb1->GetPixelColor(indexPixel); - case 2: return pGrb2->GetPixelColor(indexPixel); - case 3: return pGrb3->GetPixelColor(indexPixel); - case 4: return pGrb4->GetPixelColor(indexPixel); - case 5: return pGrb5->GetPixelColor(indexPixel); - case 6: return pGrb6->GetPixelColor(indexPixel); - case 7: return pGrb7->GetPixelColor(indexPixel); - } - break; - } - case NeoPixelType_Grbw: - switch (stripIdx) - { - case 0: return pGrbw0->GetPixelColor(indexPixel); - case 1: return pGrbw1->GetPixelColor(indexPixel); - case 2: return pGrbw2->GetPixelColor(indexPixel); - case 3: return pGrbw3->GetPixelColor(indexPixel); - case 4: return pGrbw4->GetPixelColor(indexPixel); - case 5: return pGrbw5->GetPixelColor(indexPixel); - case 6: return pGrbw6->GetPixelColor(indexPixel); - case 7: return pGrbw7->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 = GetPixelColorRaw(indexPixel); - 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; - - } - - -private: - NeoPixelType _type; - byte _colorOrder = 0; - - uint16_t pixelStripStartIdx[numStrips]; - - // pointers for every possible type for up to 8 strips - NeoPixelBrightnessBusGrbRmt0 *pGrb0; - NeoPixelBrightnessBusGrbRmt1 *pGrb1; - NeoPixelBrightnessBusGrbRmt2 *pGrb2; - NeoPixelBrightnessBusGrbRmt3 *pGrb3; - NeoPixelBrightnessBusGrbRmt4 *pGrb4; - NeoPixelBrightnessBusGrbRmt5 *pGrb5; - NeoPixelBrightnessBusGrbRmt6 *pGrb6; - NeoPixelBrightnessBusGrbRmt7 *pGrb7; - NeoPixelBrightnessBusGrbwRmt0 *pGrbw0; - NeoPixelBrightnessBusGrbwRmt1 *pGrbw1; - NeoPixelBrightnessBusGrbwRmt2 *pGrbw2; - NeoPixelBrightnessBusGrbwRmt3 *pGrbw3; - NeoPixelBrightnessBusGrbwRmt4 *pGrbw4; - NeoPixelBrightnessBusGrbwRmt5 *pGrbw5; - NeoPixelBrightnessBusGrbwRmt6 *pGrbw6; - NeoPixelBrightnessBusGrbwRmt7 *pGrbw7; - - void cleanup() - { - switch (_type) - { - case NeoPixelType_Grb: - { - for (uint8_t idx = 0; idx < numStrips; idx++) - { - switch (idx) - { - case 0: delete pGrb0; pGrb0 = NULL; break; - case 1: delete pGrb1; pGrb1 = NULL; break; - case 2: delete pGrb2; pGrb2 = NULL; break; - case 3: delete pGrb3; pGrb3 = NULL; break; - case 4: delete pGrb4; pGrb4 = NULL; break; - case 5: delete pGrb5; pGrb5 = NULL; break; - case 6: delete pGrb6; pGrb6 = NULL; break; - case 7: delete pGrb7; pGrb7 = NULL; break; - } - } - break; - } - case NeoPixelType_Grbw: - { - for (uint8_t idx = 0; idx < numStrips; idx++) - { - switch (idx) - { - case 0: delete pGrbw0; pGrbw0 = NULL; break; - case 1: delete pGrbw1; pGrbw1 = NULL; break; - case 2: delete pGrbw2; pGrbw2 = NULL; break; - case 3: delete pGrbw3; pGrbw3 = NULL; break; - case 4: delete pGrbw4; pGrbw4 = NULL; break; - case 5: delete pGrbw5; pGrbw5 = NULL; break; - case 6: delete pGrbw6; pGrbw6 = NULL; break; - case 7: delete pGrbw7; pGrbw7 = NULL; break; - } - } - } - } - } -}; -#endif diff --git a/usermods/esp32_multistrip/README.md b/usermods/esp32_multistrip/README.md deleted file mode 100644 index 87b89528..00000000 --- a/usermods/esp32_multistrip/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# esp32_multistrip - -This usermod enables up to 8 data pins to be used from an esp32 module to drive separate LED strands. This only works with one-wire LEDs like the WS2812. - -The esp32 RMT hardware is used for data output. See here for hardware driver implementation details: https://github.com/Makuna/NeoPixelBus/wiki/ESP32-NeoMethods#neoesp32rmt-methods - -Pass the following variables to the compiler as build flags: - - - `ESP32_MULTISTRIP` - - Define this to use usermod NpbWrapper.h instead of default one in WLED. - - `NUM_STRIPS` - - Number of strips in use - - `PIXEL_COUNTS` - - List of pixel counts in each strip - - `DATA_PINS` - - List of data pins each strip is attached to. There may be board-specific restrictions on which pins can be used for RTM. - -From the perspective of WLED software, the LEDs are addressed as one long strand. The modified NbpWrapper.h file addresses the appropriate strand from the overall LED index based on the number of LEDs defined in each strand. - -See `platformio_override.ini` for example configuration. - -Tested on low cost ESP-WROOM-32 dev boards from Amazon, such as those sold by KeeYees. diff --git a/usermods/esp32_multistrip/platformio_override.ini b/usermods/esp32_multistrip/platformio_override.ini deleted file mode 100644 index afdef676..00000000 --- a/usermods/esp32_multistrip/platformio_override.ini +++ /dev/null @@ -1,16 +0,0 @@ -; Example platformio_override.ini that shows how to configure your environment to use the multistrip usermod. -; Copy this file to the base wled directory that contains platformio.ini. -; Multistrip requires ESP32 because it has many more pins that can be used as LED outputs. -; Need to define NUM_STRIPS, PIXEL_COUNTS, and DATA_PINS as shown below. - -[platformio] -default_envs = esp32_multistrip - -[env:esp32_multistrip] -extends=env:esp32dev -build_flags = ${env:esp32dev.build_flags} - -D ESP32_MULTISTRIP ; define this variable to use ESP32_MULTISTRIP usermod - -D NUM_STRIPS=4 ; number of pixel strips in use - -D PIXEL_COUNTS="50, 50, 50, 50" ; number of pixels in each strip - -D DATA_PINS="25, 26, 32, 33" ; esp32 pins used for each pixel strip. available pins depends on esp32 module. - \ No newline at end of file diff --git a/usermods/mqtt_switch_v2/README.md b/usermods/mqtt_switch_v2/README.md index dc0e259f..148e4a56 100644 --- a/usermods/mqtt_switch_v2/README.md +++ b/usermods/mqtt_switch_v2/README.md @@ -1,3 +1,7 @@ +# DEPRECATION NOTICE +This usermod is deprecated and no longer maintained. It will be removed in a future WLED release. Please use usermod multi_relay which has more features. + + # MQTT controllable switches This usermod allows controlling switches (e.g. relays) via MQTT. diff --git a/usermods/mqtt_switch_v2/usermod_mqtt_switch.h b/usermods/mqtt_switch_v2/usermod_mqtt_switch.h index 40241206..67dfc9cc 100644 --- a/usermods/mqtt_switch_v2/usermod_mqtt_switch.h +++ b/usermods/mqtt_switch_v2/usermod_mqtt_switch.h @@ -1,5 +1,7 @@ #pragma once +#warning "This usermod is deprecated and no longer maintained. It will be removed in a future WLED release. Please use usermod multi_relay which has more features." + #include "wled.h" #ifndef WLED_ENABLE_MQTT #error "This user mod requires MQTT to be enabled." diff --git a/usermods/multi_relay/readme.md b/usermods/multi_relay/readme.md index ebf2056a..267bb54a 100644 --- a/usermods/multi_relay/readme.md +++ b/usermods/multi_relay/readme.md @@ -36,7 +36,7 @@ wled/deviceMAC/relay/0 on|off 1. Register the usermod by adding `#include "../usermods/multi_relay/usermod_multi_relay.h"` at the top and `usermods.add(new MultiRelay());` at the bottom of `usermods_list.cpp`. or -2. Use `#define USERMOD_MULTI_RELAY` in wled.h or `-D USERMOD_MULTI_RELAY`in your platformio.ini +2. Use `#define USERMOD_MULTI_RELAY` in wled.h or `-D USERMOD_MULTI_RELAY` in your platformio.ini You can override the default maximum number (4) of relays by defining MULTI_RELAY_MAX_RELAYS. diff --git a/usermods/multi_relay/usermod_multi_relay.h b/usermods/multi_relay/usermod_multi_relay.h index 9a92d4e2..23dcc1e2 100644 --- a/usermods/multi_relay/usermod_multi_relay.h +++ b/usermods/multi_relay/usermod_multi_relay.h @@ -45,6 +45,11 @@ class MultiRelay : public Usermod { // status of initialisation bool initDone = false; + bool HAautodiscovery = false; + + uint16_t periodicBroadcastSec = 60; + unsigned long lastBroadcast = 0; + // strings to reduce flash memory usage (used more than twice) static const char _name[]; static const char _enabled[]; @@ -53,14 +58,15 @@ class MultiRelay : public Usermod { static const char _activeHigh[]; static const char _external[]; static const char _button[]; + static const char _broadcast[]; + static const char _HAautodiscovery[]; - - void publishMqtt(const char* state, int relay) { + void publishMqtt(int relay) { //Check if MQTT Connected, otherwise it will crash the 8266 if (WLED_MQTT_CONNECTED){ char subuf[64]; sprintf_P(subuf, PSTR("%s/relay/%d"), mqttDeviceTopic, relay); - mqtt->publish(subuf, 0, false, state); + mqtt->publish(subuf, 0, false, _relay[relay].state ? "on" : "off"); } } @@ -68,15 +74,19 @@ class MultiRelay : public Usermod { * switch off the strip if the delay has elapsed */ void handleOffTimer() { + unsigned long now = millis(); bool activeRelays = false; for (uint8_t i=0; i 0 && millis() - _switchTimerStart > (_relay[i].delay*1000)) { + if (_relay[i].active && _switchTimerStart > 0 && now - _switchTimerStart > (_relay[i].delay*1000)) { if (!_relay[i].external) toggleRelay(i); _relay[i].active = false; + } else if (periodicBroadcastSec && now - lastBroadcast > (periodicBroadcastSec*1000)) { + if (_relay[i].pin>=0) publishMqtt(i); } activeRelays = activeRelays || _relay[i].active; } if (!activeRelays) _switchTimerStart = 0; + if (periodicBroadcastSec && now - lastBroadcast > (periodicBroadcastSec*1000)) lastBroadcast = now; } /** @@ -105,7 +115,7 @@ class MultiRelay : public Usermod { for (int i=0; ivalue(), ',', i); if (value==-1) { - error = F("There must be as much arugments as relays"); + error = F("There must be as many arguments as relays"); } else { // Switch if (_relay[i].external) switchRelay(i, (bool)value); @@ -118,7 +128,7 @@ class MultiRelay : public Usermod { for (int i=0;ivalue(), ',', i); if (value==-1) { - error = F("There must be as mutch arugments as relays"); + error = F("There must be as many arguments as relays"); } else { // Toggle if (value && _relay[i].external) toggleRelay(i); @@ -199,7 +209,7 @@ class MultiRelay : public Usermod { _relay[relay].state = mode; pinMode(_relay[relay].pin, OUTPUT); digitalWrite(_relay[relay].pin, mode ? !_relay[relay].mode : _relay[relay].mode); - publishMqtt(mode ? "on" : "off", relay); + publishMqtt(relay); } /** @@ -252,6 +262,50 @@ class MultiRelay : public Usermod { strcpy(subuf, mqttDeviceTopic); strcat_P(subuf, PSTR("/relay/#")); mqtt->subscribe(subuf, 0); + if (HAautodiscovery) publishHomeAssistantAutodiscovery(); + for (uint8_t i=0; i= 0 && _relay[i].external) { + StaticJsonDocument<1024> json; + sprintf_P(buf, PSTR("%s Switch %d"), serverDescription, i); //max length: 33 + 8 + 3 = 44 + json[F("name")] = buf; + + sprintf_P(buf, PSTR("%s/relay/%d"), mqttDeviceTopic, i); //max length: 33 + 7 + 3 = 43 + json["~"] = buf; + strcat_P(buf, PSTR("/command")); + mqtt->subscribe(buf, 0); + + json[F("stat_t")] = "~"; + json[F("cmd_t")] = F("~/command"); + json[F("pl_off")] = F("off"); + json[F("pl_on")] = F("on"); + json[F("uniq_id")] = uid; + + strcpy(buf, mqttDeviceTopic); //max length: 33 + 7 = 40 + strcat_P(buf, PSTR("/status")); + json[F("avty_t")] = buf; + json[F("pl_avail")] = F("online"); + json[F("pl_not_avail")] = F("offline"); + //TODO: dev + payload_size = serializeJson(json, json_str); + } else { + //Unpublish disabled or internal relays + json_str[0] = 0; + payload_size = 0; + } + sprintf_P(buf, PSTR("homeassistant/switch/%s/config"), uid); + mqtt->publish(buf, 0, true, json_str, payload_size); } } @@ -266,7 +320,7 @@ class MultiRelay : public Usermod { if (!pinManager.allocatePin(_relay[i].pin,true, PinOwner::UM_MultiRelay)) { _relay[i].pin = -1; // allocation failed } else { - if (!_relay[i].external) _relay[i].state = offMode; + if (!_relay[i].external) _relay[i].state = !offMode; switchRelay(i, _relay[i].state); _relay[i].active = false; } @@ -313,13 +367,18 @@ class MultiRelay : public Usermod { */ bool handleButton(uint8_t b) { yield(); - if (buttonType[b] == BTN_TYPE_NONE || buttonType[b] == BTN_TYPE_RESERVED || buttonType[b] == BTN_TYPE_PIR_SENSOR || buttonType[b] == BTN_TYPE_ANALOG || buttonType[b] == BTN_TYPE_ANALOG_INVERTED) { + if (!enabled + || buttonType[b] == BTN_TYPE_NONE + || buttonType[b] == BTN_TYPE_RESERVED + || buttonType[b] == BTN_TYPE_PIR_SENSOR + || buttonType[b] == BTN_TYPE_ANALOG + || buttonType[b] == BTN_TYPE_ANALOG_INVERTED) { return false; } bool handled = false; for (uint8_t i=0; i 600) { //long press + //longPressAction(b); //not exposed + //handled = false; //use if you want to pass to default behaviour buttonLongPressed[b] = true; } @@ -371,7 +432,8 @@ class MultiRelay : public Usermod { if (!buttonLongPressed[b]) { //short press // if this is second release within 350ms it is a double press (buttonWaitTime!=0) if (doublePress) { - //doublePressAction(b); + //doublePressAction(b); //not exposed + //handled = false; //use if you want to pass to default behaviour } else { buttonWaitTime[b] = now; } @@ -379,9 +441,10 @@ class MultiRelay : public Usermod { buttonPressedBefore[b] = false; buttonLongPressed[b] = false; } - // if 450ms elapsed since last press/release it is a short press + // if 350ms elapsed since last press/release it is a short press if (buttonWaitTime[b] && now - buttonWaitTime[b] > 350 && !buttonPressedBefore[b]) { buttonWaitTime[b] = 0; + //shortPressAction(b); //not exposed for (uint8_t i=0; i=0 && _relay[i].button == b) { toggleRelay(i); @@ -477,6 +540,7 @@ class MultiRelay : public Usermod { JsonObject top = root.createNestedObject(FPSTR(_name)); top[FPSTR(_enabled)] = enabled; + top[FPSTR(_broadcast)] = periodicBroadcastSec; for (uint8_t i=0; i=0 && pinManager.allocatePin(_relay[i].pin, true, PinOwner::UM_MultiRelay)) { if (!_relay[i].external) { - switchRelay(i, offMode); + _relay[i].state = !offMode; + switchRelay(i, _relay[i].state); + _oldMode = offMode; } } else { _relay[i].pin = -1; @@ -549,7 +619,7 @@ class MultiRelay : public Usermod { DEBUG_PRINTLN(F(" config (re)loaded.")); } // use "return !top["newestParameter"].isNull();" when updating Usermod with new features - return !top[F("relay-0")][FPSTR(_button)].isNull(); + return !top[FPSTR(_broadcast)].isNull(); } /** @@ -570,3 +640,5 @@ const char MultiRelay::_delay_str[] PROGMEM = "delay-s"; const char MultiRelay::_activeHigh[] PROGMEM = "active-high"; const char MultiRelay::_external[] PROGMEM = "external"; const char MultiRelay::_button[] PROGMEM = "button"; +const char MultiRelay::_broadcast[] PROGMEM = "broadcast-sec"; +const char MultiRelay::_HAautodiscovery[] PROGMEM = "HA-autodiscovery"; diff --git a/usermods/quinled_digquad_preassembled_unofficial_v0.1/README.md b/usermods/quinled_digquad_preassembled_unofficial_v0.1/README.md deleted file mode 100644 index 39ae4edd..00000000 --- a/usermods/quinled_digquad_preassembled_unofficial_v0.1/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# QuinLED-Dig-Quad Preassembled Unofficial Build - -This usermod targets the [Preassembled QuinLED-Dig-Quad](https://quinled.info/pre-assembled-quinled-dig-quad/). Tested on board revision v1r6b, -and includes the following features: - - * **Multi-channel Support** - enabling use of LED1, LED2, LED3, LED4 pins to work using segments - * **Temperature Sensor Support** - pulls readings from the built-in temperature sensor and adds the reading to the *Info* page in the UI - -## Background - -As a starting point, you should check out this awesome video from Quindor: [How to compile WLED yourself](https://quinled.info/2020/12/22/livestream-wled-compile/). The usermod you are reading now just provides some shortcuts for parts of what were covered in that video. - -## Build Firmware with Multi-channel and Temp Support - -1. Copy the `platformio_override.ini` file to the project's root directory -1. If using VS Code with the PlatformIO plugin like in the video, you will now see this new project task listed in the PLATFORMIO panel at the bottom as `env:QL-DigQuad-Pre-v0.1` (you probably need to hit the refresh button) - - - -1. Edit this file from the root directory as needed: - - - - * `PIXEL_COUNTS` may need to be adjusted for your set-up. E.g. I have lots of LEDs in Channel 1, but that's probably unusual for most - * `DATA_PINS` may need to be changed to "16,3,1,26" instead of "16,1,3,26" apparently depending on the board revision or some such - -1. Build the mod (e.g. click `Build` from the project task circled above) and update your firmware using the `QL-DigQuad-Pre-v0.1` file, e.g. using _Manual OTA_ from the Config menu. Based on the video and my own experience, you might need to build twice 🤷‍♂️. - -## Observing Temperature - -Hopefully you can now see the Temperature listed in the Info page. If not, use Chrome Developer Tools to find the current temperature - -1. Open the Developer Tools Console -2. Enter `lastinfo.u.Temperature` to view the Temperature array - - - diff --git a/usermods/quinled_digquad_preassembled_unofficial_v0.1/images/json-temp.png b/usermods/quinled_digquad_preassembled_unofficial_v0.1/images/json-temp.png deleted file mode 100644 index 66e50112..00000000 Binary files a/usermods/quinled_digquad_preassembled_unofficial_v0.1/images/json-temp.png and /dev/null differ diff --git a/usermods/quinled_digquad_preassembled_unofficial_v0.1/images/params.png b/usermods/quinled_digquad_preassembled_unofficial_v0.1/images/params.png deleted file mode 100644 index 64233f86..00000000 Binary files a/usermods/quinled_digquad_preassembled_unofficial_v0.1/images/params.png and /dev/null differ diff --git a/usermods/quinled_digquad_preassembled_unofficial_v0.1/images/pio-screenshot.png b/usermods/quinled_digquad_preassembled_unofficial_v0.1/images/pio-screenshot.png deleted file mode 100644 index e178ed16..00000000 Binary files a/usermods/quinled_digquad_preassembled_unofficial_v0.1/images/pio-screenshot.png and /dev/null differ diff --git a/usermods/quinled_digquad_preassembled_unofficial_v0.1/platformio_override.ini b/usermods/quinled_digquad_preassembled_unofficial_v0.1/platformio_override.ini deleted file mode 100644 index 6f416668..00000000 --- a/usermods/quinled_digquad_preassembled_unofficial_v0.1/platformio_override.ini +++ /dev/null @@ -1,16 +0,0 @@ -; QuinLED-Dig-Quad Preassembled Unofficial - -[env:QL-DigQuad-Pre-v0.1] -extends = env:esp32dev -build_flags = ${common.build_flags_esp32} - -D ESP32_MULTISTRIP - -D NUM_STRIPS=4 - -D PIXEL_COUNTS="600, 300, 300, 300" - -D DATA_PINS="16,1,3,26" - -D RLYPIN=19 - -D BTNPIN=17 - -D USERMOD_DALLASTEMPERATURE - -D USERMOD_DALLASTEMPERATURE_MEASUREMENT_INTERVAL=10000 -lib_deps = ${env.lib_deps} - milesburton/DallasTemperature@^3.9.0 - OneWire@~2.3.5 \ No newline at end of file diff --git a/usermods/ssd1306_i2c_oled_u8g2/README.md b/usermods/ssd1306_i2c_oled_u8g2/README.md deleted file mode 100644 index 70919cc5..00000000 --- a/usermods/ssd1306_i2c_oled_u8g2/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# SSD1306 128x32 OLED via I2C with u8g2 -This usermod allows to connect 128x32 Oled display to WLED controlled and show -the next information: -- Current SSID -- IP address if obtained - * in AP mode and turned off lightning AP password is shown -- Current effect -- Current palette -- On/Off icon (sun/moon) - -## Hardware -![Hardware connection](assets/hw_connection.png) - -## Requirements -Functionality checked with: -- commit 095429a7df4f9e2b34dd464f7bbfd068df6558eb -- Wemos d1 mini -- PlatformIO -- Generic SSD1306 128x32 I2C OLED display from aliexpress - -### Platformio -Add `U8g2@~2.27.2` dependency to `lib_deps_external` under `[common]` section in `platformio.ini`: -```ini -# platformio.ini -... -[common] -... -lib_deps_external = - ... - U8g2@~2.27.2 -... -``` - -### Arduino IDE -Install library `U8g2 by oliver` in `Tools | Include Library | Manage libraries` menu. \ No newline at end of file diff --git a/usermods/ssd1306_i2c_oled_u8g2/assets/hw_connection.png b/usermods/ssd1306_i2c_oled_u8g2/assets/hw_connection.png deleted file mode 100644 index a0e51b4d..00000000 Binary files a/usermods/ssd1306_i2c_oled_u8g2/assets/hw_connection.png and /dev/null differ diff --git a/usermods/ssd1306_i2c_oled_u8g2/wled06_usermod.ino b/usermods/ssd1306_i2c_oled_u8g2/wled06_usermod.ino deleted file mode 100644 index 8c749603..00000000 --- a/usermods/ssd1306_i2c_oled_u8g2/wled06_usermod.ino +++ /dev/null @@ -1,175 +0,0 @@ -#include // from https://github.com/olikraus/u8g2/ - -//The SCL and SDA pins are defined here. -//Lolin32 boards use SCL=5 SDA=4 -#define U8X8_PIN_SCL 5 -#define U8X8_PIN_SDA 4 - - -// If display does not work or looks corrupted check the -// constructor reference: -// https://github.com/olikraus/u8g2/wiki/u8x8setupcpp -// or check the gallery: -// https://github.com/olikraus/u8g2/wiki/gallery -U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, - U8X8_PIN_SDA); // Pins are Reset, SCL, SDA - -// gets called once at boot. Do all initialization that doesn't depend on -// network here -void userSetup() { - u8x8.begin(); - u8x8.setPowerSave(0); - u8x8.setContrast(10); //Contrast setup will help to preserve OLED lifetime. In case OLED need to be brighter increase number up to 255 - u8x8.setFont(u8x8_font_chroma48medium8_r); - u8x8.drawString(0, 0, "Loading..."); -} - -// gets called every time WiFi is (re-)connected. Initialize own network -// interfaces here -void userConnected() {} - -// needRedraw marks if redraw is required to prevent often redrawing. -bool needRedraw = true; - -// Next variables hold the previous known values to determine if redraw is -// required. -String knownSsid = ""; -IPAddress knownIp; -uint8_t knownBrightness = 0; -uint8_t knownMode = 0; -uint8_t knownPalette = 0; - -long lastUpdate = 0; -long lastRedraw = 0; -bool displayTurnedOff = false; -// How often we are redrawing screen -#define USER_LOOP_REFRESH_RATE_MS 5000 - -void userLoop() { - - // Check if we time interval for redrawing passes. - if (millis() - lastUpdate < USER_LOOP_REFRESH_RATE_MS) { - return; - } - lastUpdate = millis(); - - // Turn off display after 3 minutes with no change. - if(!displayTurnedOff && millis() - lastRedraw > 3*60*1000) { - u8x8.setPowerSave(1); - displayTurnedOff = true; - } - - // Check if values which are shown on display changed from the last time. - if (((apActive) ? String(apSSID) : WiFi.SSID()) != knownSsid) { - needRedraw = true; - } else if (knownIp != (apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP())) { - needRedraw = true; - } else if (knownBrightness != bri) { - needRedraw = true; - } else if (knownMode != strip.getMode()) { - needRedraw = true; - } else if (knownPalette != strip.getSegment(0).palette) { - needRedraw = true; - } - - if (!needRedraw) { - return; - } - needRedraw = false; - - if (displayTurnedOff) - { - u8x8.setPowerSave(0); - displayTurnedOff = false; - } - lastRedraw = millis(); - - // Update last known values. - #if defined(ESP8266) - knownSsid = apActive ? WiFi.softAPSSID() : WiFi.SSID(); - #else - knownSsid = WiFi.SSID(); - #endif - knownIp = apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP(); - knownBrightness = bri; - knownMode = strip.getMode(); - knownPalette = strip.getSegment(0).palette; - - u8x8.clear(); - u8x8.setFont(u8x8_font_chroma48medium8_r); - - // First row with Wifi name - u8x8.setCursor(1, 0); - u8x8.print(knownSsid.substring(0, u8x8.getCols() > 1 ? u8x8.getCols() - 2 : 0)); - // Print `~` char to indicate that SSID is longer, than owr dicplay - if (knownSsid.length() > u8x8.getCols()) - u8x8.print("~"); - - // Second row with IP or Psssword - u8x8.setCursor(1, 1); - // Print password in AP mode and if led is OFF. - if (apActive && bri == 0) - u8x8.print(apPass); - else - u8x8.print(knownIp); - - // Third row with mode name - u8x8.setCursor(2, 2); - uint8_t qComma = 0; - bool insideQuotes = false; - uint8_t printedChars = 0; - char singleJsonSymbol; - // Find the mode name in JSON - for (size_t i = 0; i < strlen_P(JSON_mode_names); i++) { - singleJsonSymbol = pgm_read_byte_near(JSON_mode_names + i); - switch (singleJsonSymbol) { - case '"': - insideQuotes = !insideQuotes; - break; - case '[': - case ']': - break; - case ',': - qComma++; - default: - if (!insideQuotes || (qComma != knownMode)) - break; - u8x8.print(singleJsonSymbol); - printedChars++; - } - if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2)) - break; - } - // Fourth row with palette name - u8x8.setCursor(2, 3); - qComma = 0; - insideQuotes = false; - printedChars = 0; - // Looking for palette name in JSON. - for (size_t i = 0; i < strlen_P(JSON_palette_names); i++) { - singleJsonSymbol = pgm_read_byte_near(JSON_palette_names + i); - switch (singleJsonSymbol) { - case '"': - insideQuotes = !insideQuotes; - break; - case '[': - case ']': - break; - case ',': - qComma++; - default: - if (!insideQuotes || (qComma != knownPalette)) - break; - u8x8.print(singleJsonSymbol); - printedChars++; - } - if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2)) - break; - } - - u8x8.setFont(u8x8_font_open_iconic_embedded_1x1); - u8x8.drawGlyph(0, 0, 80); // wifi icon - u8x8.drawGlyph(0, 1, 68); // home icon - u8x8.setFont(u8x8_font_open_iconic_weather_2x2); - u8x8.drawGlyph(0, 2, 66 + (bri > 0 ? 3 : 0)); // sun/moon icon -} diff --git a/wled00/FX.cpp b/wled00/FX.cpp index cf46bf28..9f756802 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -2091,7 +2091,7 @@ uint16_t WS2812FX::mode_colortwinkle() } } } - return FRAMETIME; + return FRAMETIME_FIXED; } @@ -2876,7 +2876,7 @@ uint16_t WS2812FX::candle(bool multi) } } - return FRAMETIME; + return FRAMETIME_FIXED; } uint16_t WS2812FX::mode_candle() diff --git a/wled00/FX.h b/wled00/FX.h index 9a910108..afdf0103 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -48,7 +48,8 @@ /* Not used in all effects yet */ #define WLED_FPS 42 -#define FRAMETIME (1000/WLED_FPS) +#define FRAMETIME_FIXED (1000/WLED_FPS) +#define FRAMETIME _frametime /* each segment uses 52 bytes of SRAM memory, so if you're application fails because of insufficient memory, decreasing MAX_NUM_SEGMENTS may help */ @@ -71,7 +72,7 @@ #define FAIR_DATA_PER_SEG (MAX_SEGMENT_DATA / MAX_NUM_SEGMENTS) #define LED_SKIP_AMOUNT 1 -#define MIN_SHOW_DELAY 15 +#define MIN_SHOW_DELAY (_frametime < 16 ? 8 : 15) #define NUM_COLORS 3 /* number of colors per segment */ #define SEGMENT _segments[_segment_index] @@ -655,6 +656,7 @@ class WS2812FX { setPixelColor(uint16_t n, uint32_t c), setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0), show(void), + setTargetFps(uint8_t fps), setPixelSegment(uint8_t n), deserializeMap(uint8_t n=0); @@ -685,6 +687,7 @@ class WS2812FX { getActiveSegmentsNum(void), //getFirstSelectedSegment(void), getMainSegmentId(void), + getTargetFps(void), gamma8(uint8_t), gamma8_cal(uint8_t, float), sin_gap(uint16_t), @@ -856,6 +859,8 @@ class WS2812FX { uint16_t _usedSegmentData = 0; uint16_t _transitionDur = 750; + uint8_t _targetFps = 42; + uint16_t _frametime = (1000/42); uint16_t _cumulativeFps = 2; bool diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 1e1bbab2..c7ee98f8 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -165,12 +165,12 @@ void WS2812FX::service() { _triggered = false; } -void WS2812FX::setPixelColor(uint16_t n, uint32_t c) { +void IRAM_ATTR WS2812FX::setPixelColor(uint16_t n, uint32_t c) { setPixelColor(n, R(c), G(c), B(c), W(c)); } //used to map from segment index to physical pixel, taking into account grouping, offsets, reverse and mirroring -uint16_t WS2812FX::realPixelIndex(uint16_t i) { +uint16_t IRAM_ATTR WS2812FX::realPixelIndex(uint16_t i) { int16_t iGroup = i * SEGMENT.groupLength(); /* reverse just an individual segment */ @@ -187,7 +187,7 @@ uint16_t WS2812FX::realPixelIndex(uint16_t i) { return realIndex; } -void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) +void IRAM_ATTR WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) { if (SEGLEN) {//from segment uint16_t realIndex = realPixelIndex(i); @@ -350,6 +350,15 @@ uint16_t WS2812FX::getFps() { return _cumulativeFps +1; } +uint8_t WS2812FX::getTargetFps() { + return _targetFps; +} + +void WS2812FX::setTargetFps(uint8_t fps) { + if (fps > 0 && fps <= 120) _targetFps = fps; + _frametime = 1000 / _targetFps; +} + /** * Forces the next frame to be computed on all active segments. */ @@ -775,7 +784,7 @@ void WS2812FX::setTransitionMode(bool t) /* * color blend function */ -uint32_t WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint16_t blend, bool b16) { +uint32_t IRAM_ATTR WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint16_t blend, bool b16) { if(blend == 0) return color1; uint16_t blendmax = b16 ? 0xFFFF : 0xFF; if(blend == blendmax) return color2; @@ -878,13 +887,13 @@ void WS2812FX::blur(uint8_t blur_amount) } } -uint16_t WS2812FX::triwave16(uint16_t in) +uint16_t IRAM_ATTR WS2812FX::triwave16(uint16_t in) { if (in < 0x8000) return in *2; return 0xFFFF - (in - 0x8000)*2; } -uint8_t WS2812FX::sin_gap(uint16_t in) { +uint8_t IRAM_ATTR WS2812FX::sin_gap(uint16_t in) { if (in & 0x100) return 0; //if (in > 255) return 0; return sin8(in + 192); //correct phase shift of sine so that it starts and stops at 0 @@ -951,13 +960,13 @@ uint8_t WS2812FX::get_random_wheel_index(uint8_t pos) { } -uint32_t WS2812FX::crgb_to_col(CRGB fastled) +uint32_t IRAM_ATTR WS2812FX::crgb_to_col(CRGB fastled) { return RGBW32(fastled.red, fastled.green, fastled.blue, 0); } -CRGB WS2812FX::col_to_crgb(uint32_t color) +CRGB IRAM_ATTR WS2812FX::col_to_crgb(uint32_t color) { CRGB fastled_col; fastled_col.red = R(color); @@ -1080,7 +1089,7 @@ void WS2812FX::handle_palette(void) * @param pbri Value to scale the brightness of the returned color by. Default is 255. (no scaling) * @returns Single color from palette */ -uint32_t WS2812FX::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri) +uint32_t IRAM_ATTR WS2812FX::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri) { if (SEGMENT.palette == 0 && mcol < 3) { uint32_t color = SEGCOLOR(mcol); diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index ab3156ff..da5467b5 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -73,6 +73,62 @@ struct BusConfig { } }; +// Defines an LED Strip and its color ordering. +struct ColorOrderMapEntry { + uint16_t start; + uint16_t len; + uint8_t colorOrder; +}; + +struct ColorOrderMap { + void add(uint16_t start, uint16_t len, uint8_t colorOrder) { + if (_count >= WLED_MAX_COLOR_ORDER_MAPPINGS) { + return; + } + if (len == 0) { + return; + } + if (colorOrder > COL_ORDER_MAX) { + return; + } + _mappings[_count].start = start; + _mappings[_count].len = len; + _mappings[_count].colorOrder = colorOrder; + _count++; + } + + uint8_t count() const { + return _count; + } + + void reset() { + _count = 0; + memset(_mappings, 0, sizeof(_mappings)); + } + + const ColorOrderMapEntry* get(uint8_t n) const { + if (n > _count) { + return nullptr; + } + return &(_mappings[n]); + } + + inline uint8_t getPixelColorOrder(uint16_t pix, uint8_t defaultColorOrder) const { + if (_count == 0) return defaultColorOrder; + + for (uint8_t i = 0; i < _count; i++) { + if (pix >= _mappings[i].start && pix < (_mappings[i].start + _mappings[i].len)) { + return _mappings[i].colorOrder; + } + } + return defaultColorOrder; + } + + private: + uint8_t _count; + ColorOrderMapEntry _mappings[WLED_MAX_COLOR_ORDER_MAPPINGS]; +}; + //parent class of BusDigital, BusPwm, and BusNetwork class Bus { public: @@ -152,7 +208,7 @@ class Bus { class BusDigital : public Bus { public: - BusDigital(BusConfig &bc, uint8_t nr) : Bus(bc.type, bc.start) { + BusDigital(BusConfig &bc, uint8_t nr, const ColorOrderMap &com) : Bus(bc.type, bc.start), _colorOrderMap(com) { if (!IS_DIGITAL(bc.type) || !bc.count) return; if (!pinManager.allocatePin(bc.pins[0], true, PinOwner::BusDigital)) return; _pins[0] = bc.pins[0]; @@ -197,7 +253,7 @@ class BusDigital : public Bus { //TODO only show if no new show due in the next 50ms void setStatusPixel(uint32_t c) { if (_skip && canShow()) { - PolyBus::setPixelColor(_busPtr, _iType, 0, c, _colorOrder); + PolyBus::setPixelColor(_busPtr, _iType, 0, c, _colorOrderMap.getPixelColorOrder(_start, _colorOrder)); PolyBus::show(_busPtr, _iType); } } @@ -207,13 +263,13 @@ class BusDigital : public Bus { if (_cct >= 1900) c = colorBalanceFromKelvin(_cct, c); //color correction from CCT if (reversed) pix = _len - pix -1; else pix += _skip; - PolyBus::setPixelColor(_busPtr, _iType, pix, c, _colorOrder); + PolyBus::setPixelColor(_busPtr, _iType, pix, c, _colorOrderMap.getPixelColorOrder(pix+_start, _colorOrder)); } uint32_t getPixelColor(uint16_t pix) { if (reversed) pix = _len - pix -1; else pix += _skip; - return PolyBus::getPixelColor(_busPtr, _iType, pix, _colorOrder); + return PolyBus::getPixelColor(_busPtr, _iType, pix, _colorOrderMap.getPixelColorOrder(pix+_start, _colorOrder)); } inline uint8_t getColorOrder() { @@ -263,6 +319,7 @@ class BusDigital : public Bus { uint8_t _iType = I_NONE; uint8_t _skip = 0; void * _busPtr = nullptr; + const ColorOrderMap &_colorOrderMap; }; @@ -288,7 +345,7 @@ class BusPwm : public Bus { if (!pinManager.allocatePin(currentPin, true, PinOwner::BusPwm)) { deallocatePins(); return; } - _pins[i] = currentPin; // store only after allocatePin() succeeds + _pins[i] = currentPin; //store only after allocatePin() succeeds #ifdef ESP8266 pinMode(_pins[i], OUTPUT); #else @@ -397,7 +454,7 @@ class BusPwm : public Bus { private: uint8_t _pins[5] = {255, 255, 255, 255, 255}; - uint8_t _data[5] = {255, 255, 255, 255, 255}; + uint8_t _data[5] = {0}; #ifdef ARDUINO_ARCH_ESP32 uint8_t _ledcStart = 255; #endif @@ -555,7 +612,7 @@ class BusManager { if (bc.type >= TYPE_NET_DDP_RGB && bc.type < 96) { busses[numBusses] = new BusNetwork(bc); } else if (IS_DIGITAL(bc.type)) { - busses[numBusses] = new BusDigital(bc, numBusses); + busses[numBusses] = new BusDigital(bc, numBusses, colorOrderMap); } else { busses[numBusses] = new BusPwm(bc); } @@ -640,8 +697,17 @@ class BusManager { return len; } + void updateColorOrderMap(const ColorOrderMap &com) { + memcpy(&colorOrderMap, &com, sizeof(ColorOrderMap)); + } + + const ColorOrderMap& getColorOrderMap() const { + return colorOrderMap; + } + private: uint8_t numBusses = 0; Bus* busses[WLED_MAX_BUSSES]; + ColorOrderMap colorOrderMap; }; #endif diff --git a/wled00/bus_wrapper.h b/wled00/bus_wrapper.h index bc8e6099..c94d39ae 100644 --- a/wled00/bus_wrapper.h +++ b/wled00/bus_wrapper.h @@ -102,26 +102,34 @@ #ifdef ARDUINO_ARCH_ESP32 //RGB #define B_32_RN_NEO_3 NeoPixelBrightnessBus +#ifndef CONFIG_IDF_TARGET_ESP32C3 #define B_32_I0_NEO_3 NeoPixelBrightnessBus -#ifndef CONFIG_IDF_TARGET_ESP32S2 +#endif +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) #define B_32_I1_NEO_3 NeoPixelBrightnessBus #endif //RGBW #define B_32_RN_NEO_4 NeoPixelBrightnessBus +#ifndef CONFIG_IDF_TARGET_ESP32C3 #define B_32_I0_NEO_4 NeoPixelBrightnessBus -#ifndef CONFIG_IDF_TARGET_ESP32S2 +#endif +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) #define B_32_I1_NEO_4 NeoPixelBrightnessBus #endif //400Kbps #define B_32_RN_400_3 NeoPixelBrightnessBus +#ifndef CONFIG_IDF_TARGET_ESP32C3 #define B_32_I0_400_3 NeoPixelBrightnessBus -#ifndef CONFIG_IDF_TARGET_ESP32S2 +#endif +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) #define B_32_I1_400_3 NeoPixelBrightnessBus #endif //TM1814 (RGBW) #define B_32_RN_TM1_4 NeoPixelBrightnessBus +#ifndef CONFIG_IDF_TARGET_ESP32C3 #define B_32_I0_TM1_4 NeoPixelBrightnessBus -#ifndef CONFIG_IDF_TARGET_ESP32S2 +#endif +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) #define B_32_I1_TM1_4 NeoPixelBrightnessBus #endif //Bit Bang theoratically possible, but very undesirable and not needed (no pin restrictions on RMT and I2S) @@ -190,23 +198,31 @@ class PolyBus { #endif #ifdef ARDUINO_ARCH_ESP32 case I_32_RN_NEO_3: (static_cast(busPtr))->Begin(); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_NEO_3: (static_cast(busPtr))->Begin(); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_NEO_3: (static_cast(busPtr))->Begin(); break; #endif case I_32_RN_NEO_4: (static_cast(busPtr))->Begin(); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_NEO_4: (static_cast(busPtr))->Begin(); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_NEO_4: (static_cast(busPtr))->Begin(); break; #endif case I_32_RN_400_3: (static_cast(busPtr))->Begin(); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_400_3: (static_cast(busPtr))->Begin(); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_400_3: (static_cast(busPtr))->Begin(); break; #endif case I_32_RN_TM1_4: beginTM1814(busPtr); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_TM1_4: beginTM1814(busPtr); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_TM1_4: beginTM1814(busPtr); break; #endif // ESP32 can (and should, to avoid inadvertantly driving the chip select signal) specify the pins used for SPI, but only in begin() @@ -247,23 +263,31 @@ class PolyBus { #endif #ifdef ARDUINO_ARCH_ESP32 case I_32_RN_NEO_3: busPtr = new B_32_RN_NEO_3(len, pins[0], (NeoBusChannel)channel); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_NEO_3: busPtr = new B_32_I0_NEO_3(len, pins[0]); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_NEO_3: busPtr = new B_32_I1_NEO_3(len, pins[0]); break; #endif case I_32_RN_NEO_4: busPtr = new B_32_RN_NEO_4(len, pins[0], (NeoBusChannel)channel); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_NEO_4: busPtr = new B_32_I0_NEO_4(len, pins[0]); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_NEO_4: busPtr = new B_32_I1_NEO_4(len, pins[0]); break; #endif case I_32_RN_400_3: busPtr = new B_32_RN_400_3(len, pins[0], (NeoBusChannel)channel); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_400_3: busPtr = new B_32_I0_400_3(len, pins[0]); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_400_3: busPtr = new B_32_I1_400_3(len, pins[0]); break; #endif case I_32_RN_TM1_4: busPtr = new B_32_RN_TM1_4(len, pins[0], (NeoBusChannel)channel); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_TM1_4: busPtr = new B_32_I0_TM1_4(len, pins[0]); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_TM1_4: busPtr = new B_32_I1_TM1_4(len, pins[0]); break; #endif #endif @@ -305,23 +329,31 @@ class PolyBus { #endif #ifdef ARDUINO_ARCH_ESP32 case I_32_RN_NEO_3: (static_cast(busPtr))->Show(); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_NEO_3: (static_cast(busPtr))->Show(); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_NEO_3: (static_cast(busPtr))->Show(); break; #endif case I_32_RN_NEO_4: (static_cast(busPtr))->Show(); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_NEO_4: (static_cast(busPtr))->Show(); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_NEO_4: (static_cast(busPtr))->Show(); break; #endif case I_32_RN_400_3: (static_cast(busPtr))->Show(); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_400_3: (static_cast(busPtr))->Show(); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_400_3: (static_cast(busPtr))->Show(); break; #endif case I_32_RN_TM1_4: (static_cast(busPtr))->Show(); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_TM1_4: (static_cast(busPtr))->Show(); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_TM1_4: (static_cast(busPtr))->Show(); break; #endif #endif @@ -360,23 +392,31 @@ class PolyBus { #endif #ifdef ARDUINO_ARCH_ESP32 case I_32_RN_NEO_3: return (static_cast(busPtr))->CanShow(); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_NEO_3: return (static_cast(busPtr))->CanShow(); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_NEO_3: return (static_cast(busPtr))->CanShow(); break; #endif case I_32_RN_NEO_4: return (static_cast(busPtr))->CanShow(); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_NEO_4: return (static_cast(busPtr))->CanShow(); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_NEO_4: return (static_cast(busPtr))->CanShow(); break; #endif case I_32_RN_400_3: return (static_cast(busPtr))->CanShow(); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_400_3: return (static_cast(busPtr))->CanShow(); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_400_3: return (static_cast(busPtr))->CanShow(); break; #endif case I_32_RN_TM1_4: return (static_cast(busPtr))->CanShow(); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_TM1_4: return (static_cast(busPtr))->CanShow(); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_TM1_4: return (static_cast(busPtr))->CanShow(); break; #endif #endif @@ -439,23 +479,31 @@ class PolyBus { #endif #ifdef ARDUINO_ARCH_ESP32 case I_32_RN_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; #endif case I_32_RN_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; #endif case I_32_RN_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; #endif case I_32_RN_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; #endif #endif @@ -494,23 +542,31 @@ class PolyBus { #endif #ifdef ARDUINO_ARCH_ESP32 case I_32_RN_NEO_3: (static_cast(busPtr))->SetBrightness(b); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_NEO_3: (static_cast(busPtr))->SetBrightness(b); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_NEO_3: (static_cast(busPtr))->SetBrightness(b); break; #endif case I_32_RN_NEO_4: (static_cast(busPtr))->SetBrightness(b); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_NEO_4: (static_cast(busPtr))->SetBrightness(b); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_NEO_4: (static_cast(busPtr))->SetBrightness(b); break; #endif case I_32_RN_400_3: (static_cast(busPtr))->SetBrightness(b); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_400_3: (static_cast(busPtr))->SetBrightness(b); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_400_3: (static_cast(busPtr))->SetBrightness(b); break; #endif case I_32_RN_TM1_4: (static_cast(busPtr))->SetBrightness(b); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_TM1_4: (static_cast(busPtr))->SetBrightness(b); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_TM1_4: (static_cast(busPtr))->SetBrightness(b); break; #endif #endif @@ -550,23 +606,31 @@ class PolyBus { #endif #ifdef ARDUINO_ARCH_ESP32 case I_32_RN_NEO_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_NEO_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_NEO_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; #endif case I_32_RN_NEO_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_NEO_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_NEO_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; #endif case I_32_RN_400_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_400_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_400_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; #endif case I_32_RN_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; #endif #endif @@ -623,23 +687,31 @@ class PolyBus { #endif #ifdef ARDUINO_ARCH_ESP32 case I_32_RN_NEO_3: delete (static_cast(busPtr)); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_NEO_3: delete (static_cast(busPtr)); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_NEO_3: delete (static_cast(busPtr)); break; #endif case I_32_RN_NEO_4: delete (static_cast(busPtr)); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_NEO_4: delete (static_cast(busPtr)); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_NEO_4: delete (static_cast(busPtr)); break; #endif case I_32_RN_400_3: delete (static_cast(busPtr)); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_400_3: delete (static_cast(busPtr)); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_400_3: delete (static_cast(busPtr)); break; #endif case I_32_RN_TM1_4: delete (static_cast(busPtr)); break; + #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I0_TM1_4: delete (static_cast(busPtr)); break; - #ifndef CONFIG_IDF_TARGET_ESP32S2 + #endif + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) case I_32_I1_TM1_4: delete (static_cast(busPtr)); break; #endif #endif diff --git a/wled00/button.cpp b/wled00/button.cpp index 96cdfed5..3dd61613 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -17,7 +17,7 @@ void shortPressAction(uint8_t b) if (!macroButton[b]) { switch (b) { case 0: toggleOnOff(); colorUpdated(CALL_MODE_BUTTON); break; - default: ++effectCurrent %= strip.getModeCount(); colorUpdated(CALL_MODE_BUTTON); break; + case 1: ++effectCurrent %= strip.getModeCount(); effectChanged = true; colorUpdated(CALL_MODE_BUTTON); break; } } else { applyPreset(macroButton[b], CALL_MODE_BUTTON_PRESET); @@ -36,7 +36,7 @@ void longPressAction(uint8_t b) if (!macroLongPress[b]) { switch (b) { case 0: _setRandomColor(false,true); break; - default: bri += 8; colorUpdated(CALL_MODE_BUTTON); buttonPressedTime[b] = millis(); break; // repeatable action + case 1: bri += 8; colorUpdated(CALL_MODE_BUTTON); buttonPressedTime[b] = millis(); break; // repeatable action } } else { applyPreset(macroLongPress[b], CALL_MODE_BUTTON_PRESET); @@ -55,7 +55,7 @@ void doublePressAction(uint8_t b) if (!macroDoublePress[b]) { switch (b) { //case 0: toggleOnOff(); colorUpdated(CALL_MODE_BUTTON); break; //instant short press on button 0 if no macro set - default: ++effectPalette %= strip.getPaletteCount(); colorUpdated(CALL_MODE_BUTTON); break; + case 1: ++effectPalette %= strip.getPaletteCount(); effectChanged = true; colorUpdated(CALL_MODE_BUTTON); break; } } else { applyPreset(macroDoublePress[b], CALL_MODE_BUTTON_PRESET); @@ -85,7 +85,7 @@ bool isButtonPressed(uint8_t i) if (digitalRead(btnPin[i]) == HIGH) return true; break; case BTN_TYPE_TOUCH: - #ifdef ARDUINO_ARCH_ESP32 + #if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) if (touchRead(btnPin[i]) <= touchThreshold) return true; #endif break; @@ -210,6 +210,7 @@ void handleAnalog(uint8_t b) void handleButton() { static unsigned long lastRead = 0UL; + bool analog = false; for (uint8_t b=0; b 250) { // button is not a button but a potentiometer - if (b+1 == WLED_MAX_BUTTONS) lastRead = millis(); + analog = true; handleAnalog(b); continue; } @@ -275,6 +276,7 @@ void handleButton() shortPressAction(b); } } + if (analog) lastRead = millis(); } void handleIO() diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index c4fdbde6..18d5d2a7 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -85,6 +85,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { CJSON(cctFromRgb, hw_led[F("cr")]); CJSON(strip.cctBlending, hw_led[F("cb")]); Bus::setCCTBlend(strip.cctBlending); + strip.setTargetFps(hw_led["fps"]); //NOP if 0, default 42 FPS JsonArray ins = hw_led["ins"]; @@ -122,6 +123,22 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { } if (hw_led["rev"]) busses.getBus(0)->reversed = true; //set 0.11 global reversed setting for first bus + // read color order map configuration + JsonArray hw_com = hw[F("com")]; + if (!hw_com.isNull()) { + ColorOrderMap com = {}; + uint8_t s = 0; + for (JsonObject entry : hw_com) { + if (s > WLED_MAX_COLOR_ORDER_MAPPINGS) break; + uint16_t start = entry[F("start")] | 0; + uint16_t len = entry[F("len")] | 0; + uint8_t colorOrder = (int)entry[F("order")]; + com.add(start, len, colorOrder); + s++; + } + busses.updateColorOrderMap(com); + } + // read multiple button configuration JsonObject btn_obj = hw["btn"]; JsonArray hw_btn_ins = btn_obj[F("ins")]; @@ -239,8 +256,9 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { CJSON(receiveNotificationColor, if_sync_recv["col"]); CJSON(receiveNotificationEffects, if_sync_recv["fx"]); CJSON(receiveGroups, if_sync_recv["grp"]); + CJSON(receiveSegmentOptions, if_sync_recv["seg"]); //! following line might be a problem if called after boot - receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects); + receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects || receiveSegmentOptions); JsonObject if_sync_send = if_sync["send"]; prev = notifyDirectDefault; @@ -365,7 +383,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { CJSON(timerMinutes[it], timer["min"]); CJSON(timerMacro[it], timer["macro"]); - byte dowPrev = timerWeekday[it]; + byte dowPrev = timerWeekday[it]; //note: act is currently only 0 or 1. //the reason we are not using bool is that the on-disk type in 0.11.0 was already int int actPrev = timerWeekday[it] & 0x01; @@ -375,7 +393,17 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { int act = timer["en"] | actPrev; if (act) timerWeekday[it]++; } - + if (it<8) { + JsonObject start = timer["start"]; + byte startm = start["mon"]; + if (startm) timerMonth[it] = (startm << 4); + CJSON(timerDay[it], start["day"]); + JsonObject end = timer["end"]; + CJSON(timerDayEnd[it], end["day"]); + byte endm = end["mon"]; + if (startm) timerMonth[it] += endm & 0x0F; + if (!(timerMonth[it] & 0x0F)) timerMonth[it] += 12; //default end month to 12 + } it++; } @@ -539,6 +567,7 @@ void serializeConfig() { hw_led["cct"] = correctWB; hw_led[F("cr")] = cctFromRgb; hw_led[F("cb")] = strip.cctBlending; + hw_led["fps"] = strip.getTargetFps(); hw_led[F("rgbwm")] = Bus::getAutoWhiteMode(); JsonArray hw_led_ins = hw_led.createNestedArray("ins"); @@ -561,6 +590,18 @@ void serializeConfig() { ins[F("rgbw")] = bus->isRgbw(); } + JsonArray hw_com = hw.createNestedArray(F("com")); + const ColorOrderMap& com = busses.getColorOrderMap(); + for (uint8_t s = 0; s < com.count(); s++) { + const ColorOrderMapEntry *entry = com.get(s); + if (!entry) break; + + JsonObject co = hw_com.createNestedObject(); + co[F("start")] = entry->start; + co[F("len")] = entry->len; + co[F("order")] = entry->colorOrder; + } + // button(s) JsonObject hw_btn = hw.createNestedObject("btn"); hw_btn["max"] = WLED_MAX_BUTTONS; // just information about max number of buttons (not actually used) @@ -628,6 +669,7 @@ void serializeConfig() { if_sync_recv["col"] = receiveNotificationColor; if_sync_recv["fx"] = receiveNotificationEffects; if_sync_recv["grp"] = receiveGroups; + if_sync_recv["seg"] = receiveSegmentOptions; JsonObject if_sync_send = if_sync.createNestedObject("send"); if_sync_send[F("dir")] = notifyDirect; @@ -740,6 +782,14 @@ void serializeConfig() { timers_ins0["min"] = timerMinutes[i]; timers_ins0["macro"] = timerMacro[i]; timers_ins0[F("dow")] = timerWeekday[i] >> 1; + if (i<8) { + JsonObject start = timers_ins0.createNestedObject("start"); + start["mon"] = (timerMonth[i] >> 4) & 0xF; + start["day"] = timerDay[i]; + JsonObject end = timers_ins0.createNestedObject("end"); + end["mon"] = timerMonth[i] & 0xF; + end["day"] = timerDayEnd[i]; + } } JsonObject ota = doc.createNestedObject("ota"); diff --git a/wled00/colors.cpp b/wled00/colors.cpp index 424c9916..0655060e 100644 --- a/wled00/colors.cpp +++ b/wled00/colors.cpp @@ -22,11 +22,6 @@ void colorFromUint24(uint32_t in, bool secondary) _col[2] = B(in); } -//store color components in uint32_t -uint32_t colorFromRgbw(byte* rgbw) { - return RGBW32(rgbw[0], rgbw[1], rgbw[2], rgbw[3]); -} - //relatively change white brightness, minumum A=5 void relativeChangeWhite(int8_t amount, byte lowerBoundary) { @@ -259,7 +254,7 @@ uint32_t colorBalanceFromKelvin(uint16_t kelvin, uint32_t rgb) rgbw[1] = ((uint16_t) correctionRGB[1] * G(rgb)) /255; // correct G rgbw[2] = ((uint16_t) correctionRGB[2] * B(rgb)) /255; // correct B rgbw[3] = W(rgb); - return colorFromRgbw(rgbw); + return RGBW32(rgbw[0],rgbw[1],rgbw[2],rgbw[3]); } //approximates a Kelvin color temperature from an RGB color. @@ -299,4 +294,4 @@ uint16_t approximateKelvinFromRGB(uint32_t rgb) { uint16_t k = 8080 + (225-r) *86; return (k > 10091) ? 10091 : k; } -} \ No newline at end of file +} diff --git a/wled00/const.h b/wled00/const.h index be9978bf..68f09bab 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -39,6 +39,12 @@ #endif #endif +#ifdef ESP8266 +#define WLED_MAX_COLOR_ORDER_MAPPINGS 5 +#else +#define WLED_MAX_COLOR_ORDER_MAPPINGS 10 +#endif + //Usermod IDs #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 @@ -171,6 +177,7 @@ #define COL_ORDER_RBG 3 #define COL_ORDER_BGR 4 #define COL_ORDER_GBR 5 +#define COL_ORDER_MAX 5 //Button type diff --git a/wled00/data/index.css b/wled00/data/index.css index a7588ddb..fe7f5582 100644 --- a/wled00/data/index.css +++ b/wled00/data/index.css @@ -609,11 +609,12 @@ input[type=range]:active + .sliderbubble { width: 216px; } .btn-xs { - width: 39px; + width: 42px; + height: 42px; margin: 2px 0 0 0; } .btn-pl-add { - margin-left: 9px; + margin-left: 5px; } @@ -645,7 +646,7 @@ input[type=range]:active + .sliderbubble { .sel-pl { width: 192px; background-position: 168px 16px; - margin: 8px 7px 0 0; + margin: 8px 3px 0 0; } .sel-ple { diff --git a/wled00/data/index.htm b/wled00/data/index.htm index 25787aa3..6ec6d5bf 100644 --- a/wled00/data/index.htm +++ b/wled00/data/index.htm @@ -141,7 +141,7 @@

Effect speed

- +
diff --git a/wled00/data/index.js b/wled00/data/index.js index 806315ae..8f13a9f3 100644 --- a/wled00/data/index.js +++ b/wled00/data/index.js @@ -603,7 +603,6 @@ function populateSegments(s)
- +
+ + +

`; } @@ -627,10 +630,13 @@ function populateSegments(s) noNewSegs = false; } for (var i = 0; i <= lSeg; i++) { - updateLen(i); - updateTrail(d.getElementById(`seg${i}bri`)); - if (segCount < 2) d.getElementById(`segd${lSeg}`).style.display = "none"; + updateLen(i); + updateTrail(d.getElementById(`seg${i}bri`)); + let segr = d.getElementById(`segr${i}`); + if (segr) segr.style.display = "none"; } + if (segCount < 2) d.getElementById(`segd${lSeg}`).style.display = "none"; + if (!noNewSegs && (cfg.comp.seglen?parseInt(d.getElementById(`seg${lSeg}s`).value):0)+parseInt(d.getElementById(`seg${lSeg}e`).value) 1) ? "inline":"none"; } @@ -872,7 +878,7 @@ function updateLen(s) { if (!d.getElementById(`seg${s}s`)) return; var start = parseInt(d.getElementById(`seg${s}s`).value); - var stop = parseInt(d.getElementById(`seg${s}e`).value); + var stop = parseInt(d.getElementById(`seg${s}e`).value); var len = stop - (cfg.comp.seglen?0:start); var out = "(delete)"; if (len > 1) { @@ -1491,6 +1497,29 @@ function selSeg(s){ requestJson(obj, false); } +function rptSeg(s) +{ + var name = d.getElementById(`seg${s}t`).value; + var start = parseInt(d.getElementById(`seg${s}s`).value); + var stop = parseInt(d.getElementById(`seg${s}e`).value); + if (stop == 0) {return;} + var rev = d.getElementById(`seg${s}rev`).checked; + var mi = d.getElementById(`seg${s}mi`).checked; + var sel = d.getElementById(`seg${s}sel`).checked; + var obj = {"seg": {"id": s, "n": name, "start": start, "stop": (cfg.comp.seglen?start:0)+stop, "rev": rev, "mi": mi, "on": !powered[s], "bri": parseInt(d.getElementById(`seg${s}bri`).value), "sel": sel}}; + if (d.getElementById(`seg${s}grp`)) { + var grp = parseInt(d.getElementById(`seg${s}grp`).value); + var spc = parseInt(d.getElementById(`seg${s}spc`).value); + var ofs = parseInt(d.getElementById(`seg${s}of` ).value); + obj.seg.grp = grp; + obj.seg.spc = spc; + obj.seg.of = ofs; + } + obj.seg.rpt = true; + expand(s); + requestJson(obj); +} + function setSeg(s){ var name = d.getElementById(`seg${s}t`).value; var start = parseInt(d.getElementById(`seg${s}s`).value); @@ -1542,6 +1571,13 @@ function setSegBri(s){ requestJson(obj); } +function tglFreeze(s=null) +{ + var obj = {"seg": {"frz": "t"}}; // toggle + if (s!==null) obj.id = s; + requestJson(obj); +} + function setX(ind = null) { if (ind === null) { ind = parseInt(d.querySelector('#fxlist input[name="fx"]:checked').value); diff --git a/wled00/data/settings_leds.htm b/wled00/data/settings_leds.htm index 375f63ba..6c96f9d8 100644 --- a/wled00/data/settings_leds.htm +++ b/wled00/data/settings_leds.htm @@ -6,7 +6,7 @@ LED Settings