update to 2.20
update to 2.20
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
#include <brzo_i2c.h>
|
||||
#include <brzo_i2c.h> //https://github.com/pasko-zh/brzo_i2c
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "definitions.h"
|
||||
|
||||
#include "version.h"
|
||||
// ***************************************************************************
|
||||
// Load libraries for: WebServer / WiFiManager / WebSockets
|
||||
@@ -9,7 +8,7 @@
|
||||
// needed for library WiFiManager
|
||||
#include <DNSServer.h>
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
|
||||
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
|
||||
|
||||
#include <WiFiClient.h>
|
||||
#include <ESP8266mDNS.h>
|
||||
@@ -62,6 +61,18 @@
|
||||
WiFiEventHandler wifiDisconnectHandler;
|
||||
#endif
|
||||
|
||||
#ifdef ARDUINOJSON_VERSION
|
||||
#if !(ARDUINOJSON_VERSION_MAJOR == 6 and ARDUINOJSON_VERSION_MINOR == 7)
|
||||
#error "Install ArduinoJson v6.7.0-beta"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_E131
|
||||
#include <ESPAsyncUDP.h> //https://github.com/me-no-dev/ESPAsyncUDP
|
||||
#include <ESPAsyncE131.h> //https://github.com/forkineye/ESPAsyncE131
|
||||
ESPAsyncE131 e131(END_UNIVERSE - START_UNIVERSE + 1);
|
||||
#endif
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
// Instanciate HTTP(80) / WebSockets(81) Server
|
||||
@@ -74,32 +85,6 @@ WebSocketsServer webSocket = WebSocketsServer(81);
|
||||
ESP8266HTTPUpdateServer httpUpdater;
|
||||
#endif
|
||||
|
||||
#ifdef USE_NEOANIMATIONFX
|
||||
// ***************************************************************************
|
||||
// Load libraries / Instanciate NeoAnimationFX library
|
||||
// ***************************************************************************
|
||||
// https://github.com/debsahu/NeoAnimationFX
|
||||
#include "NeoAnimationFX.h"
|
||||
#define NEOMETHOD NeoPBBGRB800
|
||||
|
||||
NEOMETHOD neoStrip(NUMLEDS);
|
||||
NeoAnimationFX<NEOMETHOD> strip(neoStrip);
|
||||
|
||||
// Uses Pin RX / GPIO3 (Only pin that is supported, due to hardware limitations)
|
||||
// NEOMETHOD NeoPBBGRB800 uses GRB config 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
|
||||
// NEOMETHOD NeoPBBGRB400 uses GRB config 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
||||
// NEOMETHOD NeoPBBRGB800 uses RGB config 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
|
||||
// NEOMETHOD NeoPBBRGB400 uses RGB config 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
||||
|
||||
// Uses Pin D4 / GPIO2 (Only pin that is supported, due to hardware limitations)
|
||||
// NEOMETHOD NeoPBBGRBU800 uses GRB config 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
|
||||
// NEOMETHOD NeoPBBGRBU400 uses GRB config 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
||||
// NEOMETHOD NeoPBBRGBU800 uses RGB config 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
|
||||
// NEOMETHOD NeoPBBRGBU400 uses RGB config 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_WS2812FX
|
||||
// ***************************************************************************
|
||||
// Load libraries / Instanciate WS2812FX library
|
||||
// ***************************************************************************
|
||||
@@ -124,6 +109,23 @@ NeoAnimationFX<NEOMETHOD> strip(neoStrip);
|
||||
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
|
||||
// and minimize distance between Arduino and first pixel. Avoid connecting
|
||||
// on a live circuit...if you must, connect GND first.
|
||||
|
||||
#ifdef USE_WS2812FX_DMA
|
||||
#include <NeoPixelBus.h>
|
||||
NeoEsp8266Dma800KbpsMethod dma = NeoEsp8266Dma800KbpsMethod(NUMLEDS, 3); //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
|
||||
//NeoEsp8266Dma400KbpsMethod dma = NeoEsp8266Dma400KbpsMethod(NUMLEDS, 3); //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
||||
#endif
|
||||
#ifdef USE_WS2812FX_UART
|
||||
#include <NeoPixelBus.h>
|
||||
NeoEsp8266Uart800KbpsMethod dma = NeoEsp8266Uart800KbpsMethod(NUMLEDS, 3);
|
||||
#endif
|
||||
#if defined(USE_WS2812FX_DMA) or defined(USE_WS2812FX_UART)
|
||||
void DMA_Show(void) {
|
||||
if(dma.IsReadyToUpdate()) {
|
||||
memcpy(dma.getPixels(), strip.getPixels(), dma.getPixelsSize());
|
||||
dma.Update();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// ***************************************************************************
|
||||
@@ -252,7 +254,7 @@ void setup() {
|
||||
pinMode(BUILTIN_LED, OUTPUT);
|
||||
// button pin setup
|
||||
#ifdef ENABLE_BUTTON
|
||||
pinMode(BUTTON, INPUT_PULLUP);
|
||||
pinMode(BUTTON,INPUT_PULLUP);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_BUTTON_GY33
|
||||
@@ -293,10 +295,14 @@ DBG_OUTPUT_PORT.println("Starting....");
|
||||
// Setup: Neopixel
|
||||
// ***************************************************************************
|
||||
strip.init();
|
||||
#if defined(USE_WS2812FX_DMA) or defined(USE_WS2812FX_UART)
|
||||
dma.Initialize();
|
||||
strip.setCustomShow(DMA_Show);
|
||||
#endif
|
||||
strip.setBrightness(brightness);
|
||||
strip.setSpeed(convertSpeed(ws2812fx_speed));
|
||||
//strip.setMode(FX_MODE_RAINBOW_CYCLE);
|
||||
strip.setColor(main_color.white, main_color.red, main_color.green, main_color.blue);
|
||||
strip.setColor(main_color.red, main_color.green, main_color.blue, main_color.white);
|
||||
strip.start();
|
||||
|
||||
// ***************************************************************************
|
||||
@@ -350,11 +356,15 @@ DBG_OUTPUT_PORT.println("Starting....");
|
||||
|
||||
// Uncomment if you want to restart ESP8266 if it cannot connect to WiFi.
|
||||
// Value in brackets is in seconds that WiFiManger waits until restart
|
||||
//wifiManager.setConfigPortalTimeout(180);
|
||||
#ifdef WIFIMGR_PORTAL_TIMEOUT
|
||||
wifiManager.setConfigPortalTimeout(WIFIMGR_PORTAL_TIMEOUT);
|
||||
#endif
|
||||
|
||||
// Uncomment if you want to set static IP
|
||||
// Order is: IP, Gateway and Subnet
|
||||
//wifiManager.setSTAStaticIPConfig(IPAddress(192,168,0,128), IPAddress(192,168,0,1), IPAddress(255,255,255,0));
|
||||
#ifdef WIFIMGR_SET_MANUAL_IP
|
||||
wifiManager.setSTAStaticIPConfig(IPAddress(_ip[0], _ip[1], _ip[2], _ip[3]), IPAddress(_gw[0], _gw[1], _gw[2], _gw[3]), IPAddress(_sn[0], _sn[1], _sn[2], _sn[3]));
|
||||
#endif
|
||||
|
||||
//fetches ssid and pass and tries to connect
|
||||
//if it does not connect it starts an access point with the specified name
|
||||
@@ -363,7 +373,7 @@ DBG_OUTPUT_PORT.println("Starting....");
|
||||
if (!wifiManager.autoConnect(HOSTNAME)) {
|
||||
DBG_OUTPUT_PORT.println("failed to connect and hit timeout");
|
||||
//reset and try again, or maybe put it to deep sleep
|
||||
ESP.reset(); //Will be removed when upgrading to standalone offline McLightingUI version
|
||||
ESP.reset(); //Will be removed when upgrading to standalone offline McLightingUI version
|
||||
delay(1000); //Will be removed when upgrading to standalone offline McLightingUI version
|
||||
}
|
||||
|
||||
@@ -448,6 +458,10 @@ ESP.reset(); //Will be removed when upgrading to standalone offline McLightingU
|
||||
// ***************************************************************************
|
||||
// Configure MQTT
|
||||
// ***************************************************************************
|
||||
#ifdef ENABLE_MQTT_HOSTNAME_CHIPID
|
||||
snprintf(mqtt_clientid, 64, "%s-%08X", HOSTNAME, ESP.getChipId());
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
if (mqtt_host != "" && atoi(mqtt_port) > 0) {
|
||||
snprintf(mqtt_intopic, sizeof mqtt_intopic, "%s/in", HOSTNAME);
|
||||
@@ -539,12 +553,15 @@ ESP.reset(); //Will be removed when upgrading to standalone offline McLightingU
|
||||
json["core_version"] = ESP.getCoreVersion();
|
||||
json["cpu_freq"] = ESP.getCpuFreqMHz();
|
||||
json["chip_id"] = ESP.getFlashChipId();
|
||||
#ifndef USE_NEOANIMATIONFX
|
||||
json["animation_lib"] = "WS2812FX";
|
||||
json["pin"] = PIN;
|
||||
#if defined(USE_WS2812FX_DMA)
|
||||
json["animation_lib"] = "WS2812FX_DMA";
|
||||
json["pin"] = 3;
|
||||
#elif defined(USE_WS2812FX_UART)
|
||||
json["animation_lib"] = "WS2812FX_UART";
|
||||
json["pin"] = 2;
|
||||
#else
|
||||
json["animation_lib"] = "NeoAnimationFX";
|
||||
json["pin"] = "Ignored, check NEOMETHOD";
|
||||
json["animation_lib"] = "WS2812FX";
|
||||
json["pin"] = PIN;
|
||||
#endif
|
||||
json["number_leds"] = NUMLEDS;
|
||||
#ifdef ENABLE_BUTTON
|
||||
@@ -694,7 +711,7 @@ ESP.reset(); //Will be removed when upgrading to standalone offline McLightingU
|
||||
|
||||
server.on("/get_color", []() {
|
||||
char rgbcolor[9];
|
||||
snprintf(rgbcolor, sizeof(rgbcolor), "%02X%02X%02X%02X", main_color.white, main_color.red, main_color.green, main_color.blue);
|
||||
snprintf(rgbcolor, sizeof(rgbcolor), "%02X%02X%02X%02X", main_color.red, main_color.green, main_color.blue, main_color.white);
|
||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
||||
server.send(200, "text/plain", rgbcolor );
|
||||
DBG_OUTPUT_PORT.print("/get_color: ");
|
||||
@@ -884,6 +901,26 @@ ESP.reset(); //Will be removed when upgrading to standalone offline McLightingU
|
||||
if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState);
|
||||
#endif
|
||||
});
|
||||
|
||||
#ifdef ENABLE_E131
|
||||
server.on("/e131", []() {
|
||||
exit_func = true;
|
||||
mode = E131;
|
||||
getStatusJSON();
|
||||
#ifdef ENABLE_MQTT
|
||||
mqtt_client.publish(mqtt_outtopic, String("OK =e131").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =131").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = true;
|
||||
#endif
|
||||
#ifdef ENABLE_STATE_SAVE_SPIFFS
|
||||
if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState);
|
||||
#endif
|
||||
});
|
||||
#endif
|
||||
|
||||
server.on("/tv", []() {
|
||||
exit_func = true;
|
||||
@@ -939,6 +976,15 @@ ESP.reset(); //Will be removed when upgrading to standalone offline McLightingU
|
||||
if (mdns_result) {
|
||||
MDNS.addService("http", "tcp", 80);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_E131
|
||||
// Choose one to begin listening for E1.31 data
|
||||
// if (e131.begin(E131_UNICAST)) // Listen via Unicast
|
||||
if (e131.begin(E131_MULTICAST, START_UNIVERSE, END_UNIVERSE)) // Listen via Multicast
|
||||
Serial.println(F("Listening for data..."));
|
||||
else
|
||||
Serial.println(F("*** e131.begin failed ***"));
|
||||
#endif
|
||||
#ifdef ENABLE_STATE_SAVE_SPIFFS
|
||||
(readStateFS()) ? DBG_OUTPUT_PORT.println(" Success!") : DBG_OUTPUT_PORT.println(" Failure!");
|
||||
#endif
|
||||
@@ -950,7 +996,7 @@ ESP.reset(); //Will be removed when upgrading to standalone offline McLightingU
|
||||
DBG_OUTPUT_PORT.printf("Found saved state: %s\n", saved_state_string.c_str());
|
||||
setModeByStateString(saved_state_string);
|
||||
}
|
||||
sprintf(last_state, "STA|%2d|%3d|%3d|%3d|%3d|%3d|%3d|%3d", mode, ws2812fx_mode, ws2812fx_speed, brightness, main_color.white, main_color.red, main_color.green, main_color.blue);
|
||||
sprintf(last_state, "STA|%2d|%3d|%3d|%3d|%3d|%3d|%3d|%3d", mode, ws2812fx_mode, ws2812fx_speed, brightness, main_color.red, main_color.green, main_color.blue, main_color.white);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_BUTTON_GY33
|
||||
@@ -1019,7 +1065,7 @@ void loop() {
|
||||
// mode = HOLD;
|
||||
}
|
||||
if (mode == SETCOLOR) {
|
||||
strip.setColor(main_color.white, main_color.red, main_color.green, main_color.blue);
|
||||
strip.setColor(main_color.red, main_color.green, main_color.blue, main_color.white);
|
||||
strip.trigger();
|
||||
mode = (prevmode == SET_MODE) ? SETSPEED : HOLD;
|
||||
}
|
||||
@@ -1036,7 +1082,7 @@ void loop() {
|
||||
}
|
||||
#ifdef ENABLE_LEGACY_ANIMATIONS
|
||||
if (mode == WIPE) {
|
||||
strip.setColor(main_color.white, main_color.red, main_color.green, main_color.blue);
|
||||
strip.setColor(main_color.red, main_color.green, main_color.blue, main_color.white);
|
||||
strip.setMode(FX_MODE_COLOR_WIPE);
|
||||
strip.trigger();
|
||||
mode = HOLD;
|
||||
@@ -1052,13 +1098,13 @@ void loop() {
|
||||
mode = HOLD;
|
||||
}
|
||||
if (mode == THEATERCHASE) {
|
||||
strip.setColor(main_color.white, main_color.red, main_color.green, main_color.blue);
|
||||
strip.setColor(main_color.red, main_color.green, main_color.blue, main_color.white);
|
||||
strip.setMode(FX_MODE_THEATER_CHASE);
|
||||
strip.trigger();
|
||||
mode = HOLD;
|
||||
}
|
||||
if (mode == TWINKLERANDOM) {
|
||||
strip.setColor(main_color.white, main_color.red, main_color.green, main_color.blue);
|
||||
strip.setColor(main_color.red, main_color.green, main_color.blue, main_color.white);
|
||||
strip.setMode(FX_MODE_TWINKLE_RANDOM);
|
||||
strip.trigger();
|
||||
mode = HOLD;
|
||||
@@ -1068,6 +1114,11 @@ void loop() {
|
||||
strip.trigger();
|
||||
mode = HOLD;
|
||||
}
|
||||
#ifdef ENABLE_E131
|
||||
if (mode == E131) {
|
||||
handleE131();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
if (mode == HOLD || mode == CUSTOM) {
|
||||
if(!strip.isRunning()) strip.start();
|
||||
@@ -1076,6 +1127,7 @@ void loop() {
|
||||
exit_func = false;
|
||||
}
|
||||
#endif
|
||||
if (prevmode == SET_MODE) prevmode = HOLD;
|
||||
}
|
||||
#ifdef ENABLE_LEGACY_ANIMATIONS
|
||||
if (mode == TV) {
|
||||
@@ -1101,7 +1153,7 @@ void loop() {
|
||||
|
||||
#ifdef ENABLE_STATE_SAVE_EEPROM
|
||||
// Check for state changes
|
||||
sprintf(current_state, "STA|%2d|%3d|%3d|%3d|%3d|%3d|%3d|%3d", mode, strip.getMode(), ws2812fx_speed, brightness, main_color.white, main_color.red, main_color.green, main_color.blue);
|
||||
sprintf(current_state, "STA|%2d|%3d|%3d|%3d|%3d|%3d|%3d|%3d", mode, strip.getMode(), ws2812fx_speed, brightness, main_color.red, main_color.green, main_color.blue, main_color.white);
|
||||
|
||||
if (strcmp(current_state, last_state) != 0) {
|
||||
// DBG_OUTPUT_PORT.printf("STATE CHANGED: %s / %s\n", last_state, current_state);
|
||||
|
||||
+591
-361
File diff suppressed because it is too large
Load Diff
+299
-133
@@ -37,42 +37,85 @@
|
||||
#ifndef WS2812FX_h
|
||||
#define WS2812FX_h
|
||||
|
||||
#define FSH(x) (__FlashStringHelper*)(x)
|
||||
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
|
||||
#define DEFAULT_BRIGHTNESS 50
|
||||
#define DEFAULT_MODE 0
|
||||
#define DEFAULT_SPEED 1000
|
||||
#define DEFAULT_COLOR 0x00FF0000
|
||||
#define DEFAULT_BRIGHTNESS (uint8_t)50
|
||||
#define DEFAULT_MODE (uint8_t)0
|
||||
#define DEFAULT_SPEED (uint16_t)1000
|
||||
#define DEFAULT_COLOR (uint32_t)0xFF0000
|
||||
|
||||
#define SPEED_MIN 10
|
||||
#define SPEED_MAX 65535
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
//#pragma message("Compiling for ESP")
|
||||
#define SPEED_MIN (uint16_t)2
|
||||
#else
|
||||
//#pragma message("Compiling for Arduino")
|
||||
#define SPEED_MIN (uint16_t)10
|
||||
#endif
|
||||
#define SPEED_MAX (uint16_t)65535
|
||||
|
||||
#define BRIGHTNESS_MIN 0
|
||||
#define BRIGHTNESS_MAX 255
|
||||
#define BRIGHTNESS_MIN (uint8_t)0
|
||||
#define BRIGHTNESS_MAX (uint8_t)255
|
||||
|
||||
/* each segment uses 36 bytes of SRAM memory, so if you're application fails because of
|
||||
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
||||
#define MAX_NUM_SEGMENTS 10
|
||||
#define NUM_COLORS 3 /* number of colors per segment */
|
||||
#define NUM_COLORS 3 /* number of colors per segment */
|
||||
#define MAX_CUSTOM_MODES 4
|
||||
#define SEGMENT _segments[_segment_index]
|
||||
#define SEGMENT_RUNTIME _segment_runtimes[_segment_index]
|
||||
#define SEGMENT_LENGTH (SEGMENT.stop - SEGMENT.start + 1)
|
||||
#define RESET_RUNTIME memset(_segment_runtimes, 0, sizeof(_segment_runtimes))
|
||||
|
||||
// some common colors
|
||||
#define RED 0x00FF0000
|
||||
#define GREEN 0x0000FF00
|
||||
#define BLUE 0x000000FF
|
||||
#define WHITE 0x00FFFFFF
|
||||
#define BLACK 0x00000000
|
||||
#define YELLOW 0x00FFFF00
|
||||
#define CYAN 0x0000FFFF
|
||||
#define MAGENTA 0x00FF00FF
|
||||
#define PURPLE 0x00400080
|
||||
#define ORANGE 0x00FF3000
|
||||
#define ULTRAWHITE 0xFFFFFFFF
|
||||
#define RED (uint32_t)0xFF0000
|
||||
#define GREEN (uint32_t)0x00FF00
|
||||
#define BLUE (uint32_t)0x0000FF
|
||||
#define WHITE (uint32_t)0xFFFFFF
|
||||
#define BLACK (uint32_t)0x000000
|
||||
#define YELLOW (uint32_t)0xFFFF00
|
||||
#define CYAN (uint32_t)0x00FFFF
|
||||
#define MAGENTA (uint32_t)0xFF00FF
|
||||
#define PURPLE (uint32_t)0x400080
|
||||
#define ORANGE (uint32_t)0xFF3000
|
||||
#define PINK (uint32_t)0xFF1493
|
||||
#define ULTRAWHITE (uint32_t)0xFFFFFFFF
|
||||
#define DARK(c) (uint32_t)((c >> 4) & 0x0f0f0f0f)
|
||||
|
||||
#define MODE_COUNT 57
|
||||
// segment options
|
||||
// bit 7: reverse animation
|
||||
// bits 4-6: fade rate (0-7)
|
||||
// bit 3: gamma correction
|
||||
// bits 1-2: size
|
||||
// bits 0: TBD
|
||||
#define NO_OPTIONS (uint8_t)B00000000
|
||||
#define REVERSE (uint8_t)B10000000
|
||||
#define IS_REVERSE ((SEGMENT.options & REVERSE) == REVERSE)
|
||||
#define FADE_XFAST (uint8_t)B00010000
|
||||
#define FADE_FAST (uint8_t)B00100000
|
||||
#define FADE_MEDIUM (uint8_t)B00110000
|
||||
#define FADE_SLOW (uint8_t)B01000000
|
||||
#define FADE_XSLOW (uint8_t)B01010000
|
||||
#define FADE_XXSLOW (uint8_t)B01100000
|
||||
#define FADE_GLACIAL (uint8_t)B01110000
|
||||
#define FADE_RATE ((SEGMENT.options >> 4) & 7)
|
||||
#define GAMMA (uint8_t)B00001000
|
||||
#define IS_GAMMA ((SEGMENT.options & GAMMA) == GAMMA)
|
||||
#define SIZE_SMALL (uint8_t)B00000000
|
||||
#define SIZE_MEDIUM (uint8_t)B00000010
|
||||
#define SIZE_LARGE (uint8_t)B00000100
|
||||
#define SIZE_XLARGE (uint8_t)B00000110
|
||||
#define SIZE_OPTION ((SEGMENT.options >> 1) & 3)
|
||||
|
||||
// segment runtime options (aux_param2)
|
||||
#define FRAME (uint8_t)B10000000
|
||||
#define SET_FRAME (SEGMENT_RUNTIME.aux_param2 |= FRAME)
|
||||
#define CLR_FRAME (SEGMENT_RUNTIME.aux_param2 &= ~FRAME)
|
||||
#define CYCLE (uint8_t)B01000000
|
||||
#define SET_CYCLE (SEGMENT_RUNTIME.aux_param2 |= CYCLE)
|
||||
#define CLR_CYCLE (SEGMENT_RUNTIME.aux_param2 &= ~CYCLE)
|
||||
|
||||
#define MODE_COUNT (sizeof(_names)/sizeof(_names[0]))
|
||||
|
||||
#define FX_MODE_STATIC 0
|
||||
#define FX_MODE_BLINK 1
|
||||
@@ -130,7 +173,137 @@
|
||||
#define FX_MODE_BICOLOR_CHASE 53
|
||||
#define FX_MODE_TRICOLOR_CHASE 54
|
||||
#define FX_MODE_ICU 55
|
||||
#define FX_MODE_CUSTOM 56
|
||||
#define FX_MODE_CUSTOM 56 // keep this for backward compatiblity
|
||||
#define FX_MODE_CUSTOM_0 56 // custom modes need to go at the end
|
||||
#define FX_MODE_CUSTOM_1 57
|
||||
#define FX_MODE_CUSTOM_2 58
|
||||
#define FX_MODE_CUSTOM_3 59
|
||||
|
||||
// create GLOBAL names to allow WS2812FX to compile with sketches and other libs that store strings
|
||||
// in PROGMEM (get rid of the "section type conflict with __c" errors once and for all. Amen.)
|
||||
const char name_0[] PROGMEM = "Static";
|
||||
const char name_1[] PROGMEM = "Blink";
|
||||
const char name_2[] PROGMEM = "Breath";
|
||||
const char name_3[] PROGMEM = "Color Wipe";
|
||||
const char name_4[] PROGMEM = "Color Wipe Inverse";
|
||||
const char name_5[] PROGMEM = "Color Wipe Reverse";
|
||||
const char name_6[] PROGMEM = "Color Wipe Reverse Inverse";
|
||||
const char name_7[] PROGMEM = "Color Wipe Random";
|
||||
const char name_8[] PROGMEM = "Random Color";
|
||||
const char name_9[] PROGMEM = "Single Dynamic";
|
||||
const char name_10[] PROGMEM = "Multi Dynamic";
|
||||
const char name_11[] PROGMEM = "Rainbow";
|
||||
const char name_12[] PROGMEM = "Rainbow Cycle";
|
||||
const char name_13[] PROGMEM = "Scan";
|
||||
const char name_14[] PROGMEM = "Dual Scan";
|
||||
const char name_15[] PROGMEM = "Fade";
|
||||
const char name_16[] PROGMEM = "Theater Chase";
|
||||
const char name_17[] PROGMEM = "Theater Chase Rainbow";
|
||||
const char name_18[] PROGMEM = "Running Lights";
|
||||
const char name_19[] PROGMEM = "Twinkle";
|
||||
const char name_20[] PROGMEM = "Twinkle Random";
|
||||
const char name_21[] PROGMEM = "Twinkle Fade";
|
||||
const char name_22[] PROGMEM = "Twinkle Fade Random";
|
||||
const char name_23[] PROGMEM = "Sparkle";
|
||||
const char name_24[] PROGMEM = "Flash Sparkle";
|
||||
const char name_25[] PROGMEM = "Hyper Sparkle";
|
||||
const char name_26[] PROGMEM = "Strobe";
|
||||
const char name_27[] PROGMEM = "Strobe Rainbow";
|
||||
const char name_28[] PROGMEM = "Multi Strobe";
|
||||
const char name_29[] PROGMEM = "Blink Rainbow";
|
||||
const char name_30[] PROGMEM = "Chase White";
|
||||
const char name_31[] PROGMEM = "Chase Color";
|
||||
const char name_32[] PROGMEM = "Chase Random";
|
||||
const char name_33[] PROGMEM = "Chase Rainbow";
|
||||
const char name_34[] PROGMEM = "Chase Flash";
|
||||
const char name_35[] PROGMEM = "Chase Flash Random";
|
||||
const char name_36[] PROGMEM = "Chase Rainbow White";
|
||||
const char name_37[] PROGMEM = "Chase Blackout";
|
||||
const char name_38[] PROGMEM = "Chase Blackout Rainbow";
|
||||
const char name_39[] PROGMEM = "Color Sweep Random";
|
||||
const char name_40[] PROGMEM = "Running Color";
|
||||
const char name_41[] PROGMEM = "Running Red Blue";
|
||||
const char name_42[] PROGMEM = "Running Random";
|
||||
const char name_43[] PROGMEM = "Larson Scanner";
|
||||
const char name_44[] PROGMEM = "Comet";
|
||||
const char name_45[] PROGMEM = "Fireworks";
|
||||
const char name_46[] PROGMEM = "Fireworks Random";
|
||||
const char name_47[] PROGMEM = "Merry Christmas";
|
||||
const char name_48[] PROGMEM = "Fire Flicker";
|
||||
const char name_49[] PROGMEM = "Fire Flicker (soft)";
|
||||
const char name_50[] PROGMEM = "Fire Flicker (intense)";
|
||||
const char name_51[] PROGMEM = "Circus Combustus";
|
||||
const char name_52[] PROGMEM = "Halloween";
|
||||
const char name_53[] PROGMEM = "Bicolor Chase";
|
||||
const char name_54[] PROGMEM = "Tricolor Chase";
|
||||
const char name_55[] PROGMEM = "ICU";
|
||||
const char name_56[] PROGMEM = "Custom 0"; // custom modes need to go at the end
|
||||
const char name_57[] PROGMEM = "Custom 1";
|
||||
const char name_58[] PROGMEM = "Custom 2";
|
||||
const char name_59[] PROGMEM = "Custom 3";
|
||||
|
||||
static const __FlashStringHelper* _names[] = {
|
||||
FSH(name_0),
|
||||
FSH(name_1),
|
||||
FSH(name_2),
|
||||
FSH(name_3),
|
||||
FSH(name_4),
|
||||
FSH(name_5),
|
||||
FSH(name_6),
|
||||
FSH(name_7),
|
||||
FSH(name_8),
|
||||
FSH(name_9),
|
||||
FSH(name_10),
|
||||
FSH(name_11),
|
||||
FSH(name_12),
|
||||
FSH(name_13),
|
||||
FSH(name_14),
|
||||
FSH(name_15),
|
||||
FSH(name_16),
|
||||
FSH(name_17),
|
||||
FSH(name_18),
|
||||
FSH(name_19),
|
||||
FSH(name_20),
|
||||
FSH(name_21),
|
||||
FSH(name_22),
|
||||
FSH(name_23),
|
||||
FSH(name_24),
|
||||
FSH(name_25),
|
||||
FSH(name_26),
|
||||
FSH(name_27),
|
||||
FSH(name_28),
|
||||
FSH(name_29),
|
||||
FSH(name_30),
|
||||
FSH(name_31),
|
||||
FSH(name_32),
|
||||
FSH(name_33),
|
||||
FSH(name_34),
|
||||
FSH(name_35),
|
||||
FSH(name_36),
|
||||
FSH(name_37),
|
||||
FSH(name_38),
|
||||
FSH(name_39),
|
||||
FSH(name_40),
|
||||
FSH(name_41),
|
||||
FSH(name_42),
|
||||
FSH(name_43),
|
||||
FSH(name_44),
|
||||
FSH(name_45),
|
||||
FSH(name_46),
|
||||
FSH(name_47),
|
||||
FSH(name_48),
|
||||
FSH(name_49),
|
||||
FSH(name_50),
|
||||
FSH(name_51),
|
||||
FSH(name_52),
|
||||
FSH(name_53),
|
||||
FSH(name_54),
|
||||
FSH(name_55),
|
||||
FSH(name_56),
|
||||
FSH(name_57),
|
||||
FSH(name_58),
|
||||
FSH(name_59)
|
||||
};
|
||||
|
||||
class WS2812FX : public Adafruit_NeoPixel {
|
||||
|
||||
@@ -143,21 +316,20 @@ class WS2812FX : public Adafruit_NeoPixel {
|
||||
uint16_t stop;
|
||||
uint16_t speed;
|
||||
uint8_t mode;
|
||||
bool reverse;
|
||||
uint8_t options;
|
||||
uint32_t colors[NUM_COLORS];
|
||||
} segment;
|
||||
|
||||
// segment runtime parameters
|
||||
public:
|
||||
typedef struct Segment_runtime { // 16 bytes
|
||||
unsigned long next_time;
|
||||
uint32_t counter_mode_step;
|
||||
uint32_t counter_mode_call;
|
||||
uint16_t aux_param;
|
||||
uint16_t aux_param2;
|
||||
uint8_t aux_param; // auxilary param (usually stores a color_wheel index)
|
||||
uint8_t aux_param2; // auxilary param (usually stores bitwise options)
|
||||
uint16_t aux_param3; // auxilary param (usually stores a segment index)
|
||||
} segment_runtime;
|
||||
|
||||
public:
|
||||
WS2812FX(uint16_t n, uint8_t p, neoPixelType t) : Adafruit_NeoPixel(n, p, t) {
|
||||
_mode[FX_MODE_STATIC] = &WS2812FX::mode_static;
|
||||
_mode[FX_MODE_BLINK] = &WS2812FX::mode_blink;
|
||||
@@ -205,15 +377,15 @@ class WS2812FX : public Adafruit_NeoPixel {
|
||||
_mode[FX_MODE_FIREWORKS] = &WS2812FX::mode_fireworks;
|
||||
_mode[FX_MODE_FIREWORKS_RANDOM] = &WS2812FX::mode_fireworks_random;
|
||||
_mode[FX_MODE_MERRY_CHRISTMAS] = &WS2812FX::mode_merry_christmas;
|
||||
_mode[FX_MODE_HALLOWEEN] = &WS2812FX::mode_halloween;
|
||||
_mode[FX_MODE_FIRE_FLICKER] = &WS2812FX::mode_fire_flicker;
|
||||
_mode[FX_MODE_FIRE_FLICKER_SOFT] = &WS2812FX::mode_fire_flicker_soft;
|
||||
_mode[FX_MODE_FIRE_FLICKER_INTENSE] = &WS2812FX::mode_fire_flicker_intense;
|
||||
_mode[FX_MODE_CIRCUS_COMBUSTUS] = &WS2812FX::mode_circus_combustus;
|
||||
_mode[FX_MODE_HALLOWEEN] = &WS2812FX::mode_halloween;
|
||||
_mode[FX_MODE_BICOLOR_CHASE] = &WS2812FX::mode_bicolor_chase;
|
||||
_mode[FX_MODE_TRICOLOR_CHASE] = &WS2812FX::mode_tricolor_chase;
|
||||
// if flash memory is constrained (I'm looking at you Arduino Nano), replace modes
|
||||
// that use a lot of flash with mode_static (reduces flash footprint by about 3600 bytes)
|
||||
// that use a lot of flash with mode_static (reduces flash footprint by about 2100 bytes)
|
||||
#ifdef REDUCED_MODES
|
||||
_mode[FX_MODE_BREATH] = &WS2812FX::mode_static;
|
||||
_mode[FX_MODE_RUNNING_LIGHTS] = &WS2812FX::mode_static;
|
||||
@@ -223,67 +395,12 @@ class WS2812FX : public Adafruit_NeoPixel {
|
||||
_mode[FX_MODE_RUNNING_LIGHTS] = &WS2812FX::mode_running_lights;
|
||||
_mode[FX_MODE_ICU] = &WS2812FX::mode_icu;
|
||||
#endif
|
||||
_mode[FX_MODE_CUSTOM] = &WS2812FX::mode_custom;
|
||||
_mode[FX_MODE_CUSTOM_0] = &WS2812FX::mode_custom_0;
|
||||
_mode[FX_MODE_CUSTOM_1] = &WS2812FX::mode_custom_1;
|
||||
_mode[FX_MODE_CUSTOM_2] = &WS2812FX::mode_custom_2;
|
||||
_mode[FX_MODE_CUSTOM_3] = &WS2812FX::mode_custom_3;
|
||||
|
||||
_name[FX_MODE_STATIC] = F("Static");
|
||||
_name[FX_MODE_BLINK] = F("Blink");
|
||||
_name[FX_MODE_BREATH] = F("Breath");
|
||||
_name[FX_MODE_COLOR_WIPE] = F("Color Wipe");
|
||||
_name[FX_MODE_COLOR_WIPE_INV ] = F("Color Wipe Inverse");
|
||||
_name[FX_MODE_COLOR_WIPE_REV] = F("Color Wipe Reverse");
|
||||
_name[FX_MODE_COLOR_WIPE_REV_INV] = F("Color Wipe Reverse Inverse");
|
||||
_name[FX_MODE_COLOR_WIPE_RANDOM] = F("Color Wipe Random");
|
||||
_name[FX_MODE_RANDOM_COLOR] = F("Random Color");
|
||||
_name[FX_MODE_SINGLE_DYNAMIC] = F("Single Dynamic");
|
||||
_name[FX_MODE_MULTI_DYNAMIC] = F("Multi Dynamic");
|
||||
_name[FX_MODE_RAINBOW] = F("Rainbow");
|
||||
_name[FX_MODE_RAINBOW_CYCLE] = F("Rainbow Cycle");
|
||||
_name[FX_MODE_SCAN] = F("Scan");
|
||||
_name[FX_MODE_DUAL_SCAN] = F("Dual Scan");
|
||||
_name[FX_MODE_FADE] = F("Fade");
|
||||
_name[FX_MODE_THEATER_CHASE] = F("Theater Chase");
|
||||
_name[FX_MODE_THEATER_CHASE_RAINBOW] = F("Theater Chase Rainbow");
|
||||
_name[FX_MODE_RUNNING_LIGHTS] = F("Running Lights");
|
||||
_name[FX_MODE_TWINKLE] = F("Twinkle");
|
||||
_name[FX_MODE_TWINKLE_RANDOM] = F("Twinkle Random");
|
||||
_name[FX_MODE_TWINKLE_FADE] = F("Twinkle Fade");
|
||||
_name[FX_MODE_TWINKLE_FADE_RANDOM] = F("Twinkle Fade Random");
|
||||
_name[FX_MODE_SPARKLE] = F("Sparkle");
|
||||
_name[FX_MODE_FLASH_SPARKLE] = F("Flash Sparkle");
|
||||
_name[FX_MODE_HYPER_SPARKLE] = F("Hyper Sparkle");
|
||||
_name[FX_MODE_STROBE] = F("Strobe");
|
||||
_name[FX_MODE_STROBE_RAINBOW] = F("Strobe Rainbow");
|
||||
_name[FX_MODE_MULTI_STROBE] = F("Multi Strobe");
|
||||
_name[FX_MODE_BLINK_RAINBOW] = F("Blink Rainbow");
|
||||
_name[FX_MODE_CHASE_WHITE] = F("Chase White");
|
||||
_name[FX_MODE_CHASE_COLOR] = F("Chase Color");
|
||||
_name[FX_MODE_CHASE_RANDOM] = F("Chase Random");
|
||||
_name[FX_MODE_CHASE_RAINBOW] = F("Chase Rainbow");
|
||||
_name[FX_MODE_CHASE_FLASH] = F("Chase Flash");
|
||||
_name[FX_MODE_CHASE_FLASH_RANDOM] = F("Chase Flash Random");
|
||||
_name[FX_MODE_CHASE_RAINBOW_WHITE] = F("Chase Rainbow White");
|
||||
_name[FX_MODE_CHASE_BLACKOUT] = F("Chase Blackout");
|
||||
_name[FX_MODE_CHASE_BLACKOUT_RAINBOW] = F("Chase Blackout Rainbow");
|
||||
_name[FX_MODE_COLOR_SWEEP_RANDOM] = F("Color Sweep Random");
|
||||
_name[FX_MODE_RUNNING_COLOR] = F("Running Color");
|
||||
_name[FX_MODE_RUNNING_RED_BLUE] = F("Running Red Blue");
|
||||
_name[FX_MODE_RUNNING_RANDOM] = F("Running Random");
|
||||
_name[FX_MODE_LARSON_SCANNER] = F("Larson Scanner");
|
||||
_name[FX_MODE_COMET] = F("Comet");
|
||||
_name[FX_MODE_FIREWORKS] = F("Fireworks");
|
||||
_name[FX_MODE_FIREWORKS_RANDOM] = F("Fireworks Random");
|
||||
_name[FX_MODE_MERRY_CHRISTMAS] = F("Merry Christmas");
|
||||
_name[FX_MODE_HALLOWEEN] = F("Halloween");
|
||||
_name[FX_MODE_FIRE_FLICKER] = F("Fire Flicker");
|
||||
_name[FX_MODE_FIRE_FLICKER_SOFT] = F("Fire Flicker (soft)");
|
||||
_name[FX_MODE_FIRE_FLICKER_INTENSE] = F("Fire Flicker (intense)");
|
||||
_name[FX_MODE_CIRCUS_COMBUSTUS] = F("Circus Combustus");
|
||||
_name[FX_MODE_BICOLOR_CHASE] = F("Bicolor Chase");
|
||||
_name[FX_MODE_TRICOLOR_CHASE] = F("Tricolor Chase");
|
||||
_name[FX_MODE_ICU] = F("ICU");
|
||||
_name[FX_MODE_CUSTOM] = F("Custom");
|
||||
|
||||
_brightness = DEFAULT_BRIGHTNESS;
|
||||
brightness = DEFAULT_BRIGHTNESS + 1; // Adafruit_NeoPixel internally offsets brightness by 1
|
||||
_running = false;
|
||||
_num_segments = 1;
|
||||
_segments[0].mode = DEFAULT_MODE;
|
||||
@@ -291,21 +408,33 @@ class WS2812FX : public Adafruit_NeoPixel {
|
||||
_segments[0].start = 0;
|
||||
_segments[0].stop = n - 1;
|
||||
_segments[0].speed = DEFAULT_SPEED;
|
||||
RESET_RUNTIME;
|
||||
resetSegmentRuntimes();
|
||||
}
|
||||
|
||||
void
|
||||
// timer(void),
|
||||
init(void),
|
||||
service(void),
|
||||
start(void),
|
||||
stop(void),
|
||||
pause(void),
|
||||
resume(void),
|
||||
strip_off(void),
|
||||
fade_out(void),
|
||||
setMode(uint8_t m),
|
||||
setMode(uint8_t seg, uint8_t m),
|
||||
setOptions(uint8_t seg, uint8_t o),
|
||||
setCustomMode(uint16_t (*p)()),
|
||||
setCustomShow(void (*p)()),
|
||||
setSpeed(uint16_t s),
|
||||
setSpeed(uint8_t seg, uint16_t s),
|
||||
increaseSpeed(uint8_t s),
|
||||
decreaseSpeed(uint8_t s),
|
||||
setColor(uint8_t w, uint8_t r, uint8_t g, uint8_t b),
|
||||
setColor(uint8_t r, uint8_t g, uint8_t b),
|
||||
setColor(uint8_t r, uint8_t g, uint8_t b, uint8_t w),
|
||||
setColor(uint32_t c),
|
||||
setColor(uint8_t seg, uint32_t c),
|
||||
setColors(uint8_t seg, uint32_t* c),
|
||||
setBrightness(uint8_t b),
|
||||
increaseBrightness(uint8_t s),
|
||||
decreaseBrightness(uint8_t s),
|
||||
@@ -314,52 +443,92 @@ class WS2812FX : public Adafruit_NeoPixel {
|
||||
decreaseLength(uint16_t s),
|
||||
trigger(void),
|
||||
setNumSegments(uint8_t n),
|
||||
setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, uint32_t color, uint16_t speed, bool reverse),
|
||||
setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, uint32_t color, uint16_t speed, bool reverse),
|
||||
setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, uint32_t color, uint16_t speed, uint8_t options),
|
||||
setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, const uint32_t colors[], uint16_t speed, bool reverse),
|
||||
resetSegments();
|
||||
setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, const uint32_t colors[], uint16_t speed, uint8_t options),
|
||||
resetSegments(),
|
||||
resetSegmentRuntimes(),
|
||||
resetSegmentRuntime(uint8_t),
|
||||
setPixelColor(uint16_t n, uint32_t c),
|
||||
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b),
|
||||
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w),
|
||||
copyPixels(uint16_t d, uint16_t s, uint16_t c),
|
||||
show(void);
|
||||
|
||||
boolean
|
||||
isRunning(void);
|
||||
isRunning(void),
|
||||
isTriggered(void),
|
||||
isFrame(void),
|
||||
isFrame(uint8_t),
|
||||
isCycle(void),
|
||||
isCycle(uint8_t);
|
||||
|
||||
uint8_t
|
||||
random8(void),
|
||||
random8(uint8_t),
|
||||
getMode(void),
|
||||
getBrightness(void),
|
||||
getMode(uint8_t),
|
||||
getModeCount(void),
|
||||
getNumSegments(void);
|
||||
setCustomMode(const __FlashStringHelper* name, uint16_t (*p)()),
|
||||
setCustomMode(uint8_t i, const __FlashStringHelper* name, uint16_t (*p)()),
|
||||
getNumSegments(void),
|
||||
get_random_wheel_index(uint8_t),
|
||||
getOptions(uint8_t);
|
||||
|
||||
uint16_t
|
||||
random16(void),
|
||||
random16(uint16_t),
|
||||
getSpeed(void),
|
||||
getLength(void);
|
||||
getSpeed(uint8_t),
|
||||
getLength(void),
|
||||
getNumBytes(void);
|
||||
|
||||
uint32_t
|
||||
color_wheel(uint8_t),
|
||||
getColor(void);
|
||||
getColor(void),
|
||||
getColor(uint8_t),
|
||||
intensitySum(void);
|
||||
|
||||
const __FlashStringHelper*
|
||||
getModeName(uint8_t m);
|
||||
uint32_t* getColors(uint8_t);
|
||||
uint32_t* intensitySums(void);
|
||||
|
||||
WS2812FX::Segment
|
||||
getSegment(void);
|
||||
const __FlashStringHelper* getModeName(uint8_t m);
|
||||
|
||||
WS2812FX::Segment_runtime
|
||||
getSegmentRuntime(void);
|
||||
WS2812FX::Segment* getSegment(void);
|
||||
|
||||
WS2812FX::Segment*
|
||||
getSegments(void);
|
||||
WS2812FX::Segment* getSegment(uint8_t);
|
||||
|
||||
private:
|
||||
void
|
||||
strip_off(void),
|
||||
fade_out(void);
|
||||
WS2812FX::Segment* getSegments(void);
|
||||
|
||||
WS2812FX::Segment_runtime* getSegmentRuntime(void);
|
||||
|
||||
WS2812FX::Segment_runtime* getSegmentRuntime(uint8_t);
|
||||
|
||||
WS2812FX::Segment_runtime* getSegmentRuntimes(void);
|
||||
|
||||
// mode helper functions
|
||||
uint16_t
|
||||
blink(uint32_t, uint32_t, bool strobe),
|
||||
color_wipe(uint32_t, uint32_t, bool),
|
||||
twinkle(uint32_t, uint32_t),
|
||||
twinkle_fade(uint32_t),
|
||||
chase(uint32_t, uint32_t, uint32_t),
|
||||
running(uint32_t, uint32_t),
|
||||
fireworks(uint32_t),
|
||||
fire_flicker(int),
|
||||
tricolor_chase(uint32_t, uint32_t, uint32_t),
|
||||
scan(uint32_t, uint32_t, bool);
|
||||
uint32_t
|
||||
color_blend(uint32_t, uint32_t, uint8_t);
|
||||
|
||||
// builtin modes
|
||||
uint16_t
|
||||
mode_static(void),
|
||||
blink(uint32_t, uint32_t, bool strobe),
|
||||
mode_blink(void),
|
||||
mode_blink_rainbow(void),
|
||||
mode_strobe(void),
|
||||
mode_strobe_rainbow(void),
|
||||
color_wipe(uint32_t, uint32_t, bool),
|
||||
mode_color_wipe(void),
|
||||
mode_color_wipe_inv(void),
|
||||
mode_color_wipe_rev(void),
|
||||
@@ -373,23 +542,19 @@ class WS2812FX : public Adafruit_NeoPixel {
|
||||
mode_fade(void),
|
||||
mode_scan(void),
|
||||
mode_dual_scan(void),
|
||||
theater_chase(uint32_t, uint32_t),
|
||||
mode_theater_chase(void),
|
||||
mode_theater_chase_rainbow(void),
|
||||
mode_rainbow(void),
|
||||
mode_rainbow_cycle(void),
|
||||
mode_running_lights(void),
|
||||
twinkle(uint32_t),
|
||||
mode_twinkle(void),
|
||||
mode_twinkle_random(void),
|
||||
twinkle_fade(uint32_t),
|
||||
mode_twinkle_fade(void),
|
||||
mode_twinkle_fade_random(void),
|
||||
mode_sparkle(void),
|
||||
mode_flash_sparkle(void),
|
||||
mode_hyper_sparkle(void),
|
||||
mode_multi_strobe(void),
|
||||
chase(uint32_t, uint32_t, uint32_t),
|
||||
mode_chase_white(void),
|
||||
mode_chase_color(void),
|
||||
mode_chase_random(void),
|
||||
@@ -399,13 +564,11 @@ class WS2812FX : public Adafruit_NeoPixel {
|
||||
mode_chase_rainbow_white(void),
|
||||
mode_chase_blackout(void),
|
||||
mode_chase_blackout_rainbow(void),
|
||||
running(uint32_t, uint32_t),
|
||||
mode_running_color(void),
|
||||
mode_running_red_blue(void),
|
||||
mode_running_random(void),
|
||||
mode_larson_scanner(void),
|
||||
mode_comet(void),
|
||||
fireworks(uint32_t),
|
||||
mode_fireworks(void),
|
||||
mode_fireworks_random(void),
|
||||
mode_merry_christmas(void),
|
||||
@@ -413,33 +576,36 @@ class WS2812FX : public Adafruit_NeoPixel {
|
||||
mode_fire_flicker(void),
|
||||
mode_fire_flicker_soft(void),
|
||||
mode_fire_flicker_intense(void),
|
||||
fire_flicker(int),
|
||||
mode_circus_combustus(void),
|
||||
tricolor_chase(uint32_t, uint32_t, uint32_t),
|
||||
mode_bicolor_chase(void),
|
||||
mode_tricolor_chase(void),
|
||||
mode_icu(void),
|
||||
mode_custom(void);
|
||||
mode_custom_0(void),
|
||||
mode_custom_1(void),
|
||||
mode_custom_2(void),
|
||||
mode_custom_3(void);
|
||||
|
||||
private:
|
||||
uint16_t _rand16seed;
|
||||
uint16_t (*customModes[MAX_CUSTOM_MODES])(void) {
|
||||
[]{ return (uint16_t)1000; },
|
||||
[]{ return (uint16_t)1000; },
|
||||
[]{ return (uint16_t)1000; },
|
||||
[]{ return (uint16_t)1000; }
|
||||
};
|
||||
void (*customShow)(void) = NULL;
|
||||
|
||||
boolean
|
||||
_running,
|
||||
_triggered;
|
||||
|
||||
uint8_t
|
||||
get_random_wheel_index(uint8_t),
|
||||
_brightness;
|
||||
|
||||
const __FlashStringHelper*
|
||||
_name[MODE_COUNT]; // SRAM footprint: 2 bytes per element
|
||||
|
||||
mode_ptr
|
||||
_mode[MODE_COUNT]; // SRAM footprint: 4 bytes per element
|
||||
mode_ptr _mode[MODE_COUNT]; // SRAM footprint: 4 bytes per element
|
||||
|
||||
uint8_t _segment_index = 0;
|
||||
uint8_t _num_segments = 1;
|
||||
segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 20 bytes per element
|
||||
// start, stop, speed, mode, reverse, color[]
|
||||
{ 0, 7, DEFAULT_SPEED, FX_MODE_STATIC, false, {DEFAULT_COLOR}}
|
||||
// start, stop, speed, mode, options, color[]
|
||||
{ 0, 7, DEFAULT_SPEED, FX_MODE_STATIC, NO_OPTIONS, {DEFAULT_COLOR}}
|
||||
};
|
||||
segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 16 bytes per element
|
||||
};
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
Custom effect that changes random pixels to transition between colors
|
||||
|
||||
Keith Lord - 2018
|
||||
|
||||
LICENSE
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Keith Lord
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
CHANGELOG
|
||||
2018-08-19 initial version
|
||||
*/
|
||||
|
||||
#ifndef BlockDissolve_h
|
||||
#define BlockDissolve_h
|
||||
|
||||
#include <WS2812FX.h>
|
||||
|
||||
extern WS2812FX ws2812fx;
|
||||
|
||||
uint16_t blockDissolve(void) {
|
||||
WS2812FX::Segment* seg = ws2812fx.getSegment();
|
||||
WS2812FX::Segment_runtime* segrt = ws2812fx.getSegmentRuntime();
|
||||
int seglen = seg->stop - seg->start + 1;
|
||||
|
||||
uint32_t color = seg->colors[segrt->aux_param];
|
||||
ws2812fx.setPixelColor(seg->start, color);
|
||||
// get the decimated color after setPixelColor() has mangled it
|
||||
// in accordance to the brightness setting
|
||||
uint32_t desColor = ws2812fx.getPixelColor(seg->start);
|
||||
|
||||
for(uint16_t i=0; i<seglen; i++) {
|
||||
int index = seg->start + ws2812fx.random16(seglen);
|
||||
if(ws2812fx.getPixelColor(index) != desColor) {
|
||||
ws2812fx.setPixelColor(index, color);
|
||||
return seg->speed;
|
||||
}
|
||||
}
|
||||
|
||||
for(uint16_t i=seg->start; i<seg->stop; i++) {
|
||||
ws2812fx.setPixelColor(i, color);
|
||||
}
|
||||
|
||||
segrt->aux_param = (segrt->aux_param + 1) % NUM_COLORS;
|
||||
return seg->speed;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
Custom effect that creates two Larson scanners moving in opposite directions.
|
||||
If you set the REVERSE option, an offset will be added to the comet after each
|
||||
cycle (so if the LEDs are arranged in a circle, the animation will appear to
|
||||
"walk" around the circle.)
|
||||
|
||||
Keith Lord - 2018
|
||||
|
||||
LICENSE
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Keith Lord
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
CHANGELOG
|
||||
2018-02-26 initial version
|
||||
*/
|
||||
|
||||
#ifndef DualLarson_h
|
||||
#define DualLarson_h
|
||||
|
||||
#include <WS2812FX.h>
|
||||
|
||||
extern WS2812FX ws2812fx;
|
||||
|
||||
uint16_t dualLarson(void) {
|
||||
WS2812FX::Segment* seg = ws2812fx.getSegment(); // get the current segment
|
||||
WS2812FX::Segment_runtime* segrt = ws2812fx.getSegmentRuntime();
|
||||
int seglen = seg->stop - seg->start + 1;
|
||||
|
||||
static int16_t offset = 0;
|
||||
int8_t dir = segrt->aux_param ? -1 : 1;
|
||||
segrt->aux_param3 += dir;
|
||||
|
||||
ws2812fx.fade_out();
|
||||
|
||||
int16_t segIndex = (segrt->aux_param3 + offset) % seglen;
|
||||
ws2812fx.setPixelColor(seg->start + segIndex, seg->colors[0]);
|
||||
ws2812fx.setPixelColor(seg->stop - segIndex, seg->colors[2]);
|
||||
|
||||
if(segrt->aux_param3 >= (seg->stop - seg->start) || segrt->aux_param3 <= 0) {
|
||||
segrt->aux_param = !segrt->aux_param;
|
||||
if(seg->options & REVERSE) offset = (offset + 1) % seglen;
|
||||
}
|
||||
|
||||
return (seg->speed / (seglen * 2));
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
Custom effect that creates random comets
|
||||
|
||||
Keith Lord - 2018
|
||||
|
||||
LICENSE
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Keith Lord
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
CHANGELOG
|
||||
2018-02-26 initial version
|
||||
*/
|
||||
|
||||
#ifndef MultiComet_h
|
||||
#define MultiComet_h
|
||||
|
||||
#include <WS2812FX.h>
|
||||
|
||||
extern WS2812FX ws2812fx;
|
||||
|
||||
uint16_t multiComet(void) {
|
||||
WS2812FX::Segment* seg = ws2812fx.getSegment(); // get the current segment
|
||||
int seglen = seg->stop - seg->start + 1;
|
||||
|
||||
bool isReverse = (seg->options & REVERSE) == REVERSE;
|
||||
|
||||
ws2812fx.fade_out();
|
||||
|
||||
static int16_t comets[] = {UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX};
|
||||
static int8_t numComets = sizeof(comets)/sizeof(comets[0]);
|
||||
|
||||
for(uint8_t i=0; i < numComets; i++) {
|
||||
if(comets[i] < seglen) {
|
||||
if(isReverse) {
|
||||
ws2812fx.setPixelColor(seg->stop - comets[i], i % 2 ? seg->colors[0] : seg->colors[2]);
|
||||
} else {
|
||||
ws2812fx.setPixelColor(seg->start + comets[i], i % 2 ? seg->colors[0] : seg->colors[2]);
|
||||
}
|
||||
comets[i]++;
|
||||
} else {
|
||||
if(!random(seglen)) {
|
||||
comets[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (seg->speed / seglen);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
Custom effect that creates three color spans that oscillate back and forth.
|
||||
|
||||
Keith Lord - 2018
|
||||
|
||||
LICENSE
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Keith Lord
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
CHANGELOG
|
||||
2018-07-26 initial version
|
||||
*/
|
||||
|
||||
#ifndef Oscillate_h
|
||||
#define Oscillate_h
|
||||
|
||||
#include <WS2812FX.h>
|
||||
|
||||
extern WS2812FX ws2812fx;
|
||||
|
||||
typedef struct Oscillator {
|
||||
int16_t pos;
|
||||
int8_t size;
|
||||
int8_t dir;
|
||||
int8_t speed;
|
||||
} oscillator;
|
||||
|
||||
uint16_t oscillate(void) {
|
||||
WS2812FX::Segment* seg = ws2812fx.getSegment(); // get the current segment
|
||||
int seglen = seg->stop - seg->start + 1;
|
||||
|
||||
static oscillator oscillators[NUM_COLORS] = {
|
||||
{seglen/4, seglen/8, 1, 1},
|
||||
{seglen/4*2, seglen/8, -1, 1},
|
||||
{seglen/4*3, seglen/8, 1, 2}
|
||||
};
|
||||
|
||||
for(int8_t i=0; i < sizeof(oscillators)/sizeof(oscillators[0]); i++) {
|
||||
oscillators[i].pos += oscillators[i].dir * oscillators[i].speed;
|
||||
if((oscillators[i].dir == -1) && (oscillators[i].pos <= 0)) {
|
||||
oscillators[i].pos = 0;
|
||||
oscillators[i].dir = 1;
|
||||
oscillators[i].speed = random(1, 3);
|
||||
}
|
||||
if((oscillators[i].dir == 1) && (oscillators[i].pos >= (seglen - 1))) {
|
||||
oscillators[i].pos = seglen - 1;
|
||||
oscillators[i].dir = -1;
|
||||
oscillators[i].speed = random(1, 3);
|
||||
}
|
||||
}
|
||||
|
||||
for(int16_t i=0; i < seglen; i++) {
|
||||
uint32_t color = BLACK;
|
||||
for(int8_t j=0; j < sizeof(oscillators)/sizeof(oscillators[0]); j++) {
|
||||
if(i >= oscillators[j].pos - oscillators[j].size && i <= oscillators[j].pos + oscillators[j].size) {
|
||||
color = (color == BLACK) ? seg->colors[j] : ws2812fx.color_blend(color, seg->colors[j], 128);
|
||||
}
|
||||
}
|
||||
ws2812fx.setPixelColor(seg->start + i, color);
|
||||
}
|
||||
return(seg->speed / 8);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
Custom effect that looks like popcorn.
|
||||
The 'popcorn' is color[0] and the background color is color[1].
|
||||
If color[0] is the same as color[1], the 'popcorn' will be a random color.
|
||||
|
||||
Keith Lord - 2018
|
||||
|
||||
LICENSE
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Keith Lord
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
CHANGELOG
|
||||
2018-11-13 initial version
|
||||
*/
|
||||
|
||||
#ifndef Popcorn_h
|
||||
#define Popcorn_h
|
||||
|
||||
#include <WS2812FX.h>
|
||||
|
||||
#define MAX_NUM_POPCORN 10
|
||||
#define GRAVITY 0.1
|
||||
|
||||
extern WS2812FX ws2812fx;
|
||||
|
||||
typedef struct Kernel {
|
||||
float position;
|
||||
float velocity;
|
||||
int32_t color;
|
||||
} kernel;
|
||||
|
||||
uint16_t popcorn(void) {
|
||||
WS2812FX::Segment* seg = ws2812fx.getSegment(); // get the current segment
|
||||
uint16_t seglen = seg->stop - seg->start + 1;
|
||||
uint32_t popcornColor = seg->colors[0];
|
||||
uint32_t bgColor = seg->colors[1];
|
||||
if(popcornColor == bgColor) popcornColor = ws2812fx.color_wheel(ws2812fx.random8());
|
||||
bool isReverse = (seg->options & REVERSE) != 0;
|
||||
|
||||
static kernel popcorn[MAX_NUM_POPCORN];
|
||||
static float coeff = 0.0f;
|
||||
if(coeff == 0.0f) { // calculate the velocity coeff once (the secret sauce)
|
||||
coeff = pow((float)seglen, 0.5223324f) * 0.3944296f;
|
||||
}
|
||||
|
||||
// reset all LEDs to background color
|
||||
for(uint16_t i=seg->start; i <= seg->stop; i++) {
|
||||
ws2812fx.setPixelColor(i, bgColor);
|
||||
}
|
||||
|
||||
uint16_t ledIndex;
|
||||
for(int8_t i=0; i < MAX_NUM_POPCORN; i++) {
|
||||
bool isActive = popcorn[i].position >= 0.0f;
|
||||
|
||||
if(isActive) { // if kernel is active, update its position
|
||||
popcorn[i].position += popcorn[i].velocity;
|
||||
popcorn[i].velocity -= GRAVITY;
|
||||
ledIndex = isReverse ? seg->stop - popcorn[i].position : seg->start + popcorn[i].position;
|
||||
if(ledIndex >= seg->start && ledIndex <= seg->stop) ws2812fx.setPixelColor(ledIndex, popcorn[i].color);
|
||||
} else { // if kernel is inactive, randomly pop it
|
||||
if(ws2812fx.random8() < 2) { // POP!!!
|
||||
popcorn[i].position = 0.0f;
|
||||
popcorn[i].velocity = coeff * (random(66, 100) / 100.0f);
|
||||
popcorn[i].color = popcornColor;
|
||||
ledIndex = isReverse ? seg->stop : seg->start;
|
||||
ws2812fx.setPixelColor(ledIndex, popcorn[i].color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(seg->speed / seglen);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
Custom effect that combines the fireworks effect and running effect
|
||||
to produce a rain-like effect. Depending on the size of your LED strip, you
|
||||
may want to play with the FADE and SIZE options.
|
||||
The background color is black, unless you use a FADE_RATE other then DEFAULT,
|
||||
in which case the background color is color[1].
|
||||
The color of the rain is either color[0] or color[2] (chosen randomly), unless
|
||||
color[0]==color[1], in which case the rain is a random color.
|
||||
|
||||
Keith Lord - 2018
|
||||
|
||||
LICENSE
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Keith Lord
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
CHANGELOG
|
||||
2018-12-14 initial version
|
||||
*/
|
||||
|
||||
#ifndef Rain_h
|
||||
#define Rain_h
|
||||
|
||||
#include <WS2812FX.h>
|
||||
|
||||
extern WS2812FX ws2812fx;
|
||||
|
||||
uint16_t rain(void) {
|
||||
WS2812FX::Segment* seg = ws2812fx.getSegment(); // get the current segment
|
||||
uint16_t seglen = seg->stop - seg->start + 1;
|
||||
uint32_t rainColor = (ws2812fx.random8() & 1) == 0 ? seg->colors[0] : seg->colors[2];
|
||||
if(seg->colors[0] == seg->colors[1]) rainColor = ws2812fx.color_wheel(ws2812fx.random8());
|
||||
|
||||
ws2812fx.fireworks(rainColor);
|
||||
|
||||
// shift everything two pixels
|
||||
bool isReverse = (seg->options & REVERSE) != 0;
|
||||
if(isReverse) {
|
||||
ws2812fx.copyPixels(seg->start + 2, seg->start, seglen - 2);
|
||||
} else {
|
||||
ws2812fx.copyPixels(seg->start, seg->start + 2, seglen - 2);
|
||||
}
|
||||
|
||||
return(seg->speed / seglen);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
Custom effect that creates a Larson Scanner with rainbow colors
|
||||
It has two modes:
|
||||
1) if the segment options parameter is set to NO_OPTIONS, then
|
||||
the rainbow of colors span the 'comet'.
|
||||
2) if the segment options parameter is set to a FADE option
|
||||
(e.g. FADE_MEDIUM), then the rainbow of colors span the segment
|
||||
and the 'comet' merely shows the colors at that point in the segment.
|
||||
|
||||
Keith Lord - 2018
|
||||
|
||||
LICENSE
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Keith Lord
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
CHANGELOG
|
||||
2018-08-26 initial version
|
||||
*/
|
||||
|
||||
#ifndef RainbowLarson_h
|
||||
#define RainbowLarson_h
|
||||
|
||||
#include <WS2812FX.h>
|
||||
|
||||
extern WS2812FX ws2812fx;
|
||||
|
||||
uint16_t rainbowLarson(void) {
|
||||
WS2812FX::Segment* seg = ws2812fx.getSegment(); // get the current segment
|
||||
int seglen = seg->stop - seg->start + 1;
|
||||
|
||||
static int16_t index = 0, dir = 1, cnt = 0;
|
||||
index += dir;
|
||||
|
||||
ws2812fx.fade_out();
|
||||
|
||||
if(seg->options == NO_OPTIONS) {
|
||||
ws2812fx.setPixelColor(seg->start + index, ws2812fx.color_wheel((cnt++ % 8) * 32));
|
||||
} else {
|
||||
ws2812fx.setPixelColor(seg->start + index, ws2812fx.color_wheel((index * 256) / seglen));
|
||||
}
|
||||
|
||||
if(index >= (seg->stop - seg->start) || index <= 0) dir = -dir;
|
||||
|
||||
return (seg->speed / (seglen * 2));
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
Custom effect that creates a random chase effect
|
||||
|
||||
Keith Lord - 2018
|
||||
|
||||
LICENSE
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Keith Lord
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
CHANGELOG
|
||||
2018-02-26 initial version
|
||||
*/
|
||||
|
||||
#ifndef RandomChase_h
|
||||
#define RandomChase_h
|
||||
|
||||
#include <WS2812FX.h>
|
||||
|
||||
extern WS2812FX ws2812fx;
|
||||
|
||||
uint16_t randomChase(void) {
|
||||
WS2812FX::Segment* seg = ws2812fx.getSegment();
|
||||
for(uint16_t i=seg->stop; i>seg->start; i--) {
|
||||
ws2812fx.setPixelColor(i, ws2812fx.getPixelColor(i-1));
|
||||
}
|
||||
uint32_t color = ws2812fx.getPixelColor(seg->start + 1);
|
||||
int r = random(6) != 0 ? (color >> 16 & 0xFF) : random(256);
|
||||
int g = random(6) != 0 ? (color >> 8 & 0xFF) : random(256);
|
||||
int b = random(6) != 0 ? (color & 0xFF) : random(256);
|
||||
ws2812fx.setPixelColor(seg->start, r, g, b);
|
||||
return seg->speed;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
Custom effect that fades between three colors. You can add the TRIFADE_BLACK option
|
||||
in the setSegment() call to fade to black between each color.
|
||||
|
||||
Keith Lord - 2018
|
||||
|
||||
LICENSE
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Keith Lord
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
CHANGELOG
|
||||
2018-07-26 initial version
|
||||
*/
|
||||
|
||||
#ifndef TriFade_h
|
||||
#define TriFade_h
|
||||
|
||||
#define TRIFADE_BLACK (uint8_t)0x80
|
||||
|
||||
#include <WS2812FX.h>
|
||||
|
||||
extern WS2812FX ws2812fx;
|
||||
|
||||
uint16_t triFade(void) {
|
||||
WS2812FX::Segment* seg = ws2812fx.getSegment(); // get the current segment
|
||||
uint8_t options = seg->options;
|
||||
bool trifade_black = (options & TRIFADE_BLACK) == TRIFADE_BLACK;
|
||||
|
||||
static int count = 0;
|
||||
static uint32_t color1 = 0, color2 = 0;
|
||||
|
||||
if(count == 0) {
|
||||
color1 = seg->colors[0];
|
||||
color2 = trifade_black ? BLACK : seg->colors[1];
|
||||
} else if(count == 256) {
|
||||
color1 = trifade_black ? BLACK : seg->colors[1];
|
||||
color2 = trifade_black ? seg->colors[1] : seg->colors[2];
|
||||
} else if(count == 512) {
|
||||
color1 = trifade_black ? seg->colors[1] : seg->colors[2];
|
||||
color2 = trifade_black ? BLACK : seg->colors[0];
|
||||
} else if(count == 768) {
|
||||
color1 = trifade_black ? BLACK : seg->colors[0];
|
||||
color2 = trifade_black ? seg->colors[2] : seg->colors[1];
|
||||
} else if(count == 1024) {
|
||||
color1 = trifade_black ? seg->colors[2] : seg->colors[1];
|
||||
color2 = trifade_black ? BLACK : seg->colors[2];
|
||||
} else if(count == 1280) {
|
||||
color1 = trifade_black ? BLACK: seg->colors[2];
|
||||
color2 = seg->colors[0];
|
||||
}
|
||||
|
||||
uint32_t color = ws2812fx.color_blend(color1, color2, count % 256);
|
||||
for(uint16_t i=seg->start; i <= seg->stop; i++) {
|
||||
ws2812fx.setPixelColor(i, color);
|
||||
}
|
||||
|
||||
count += 4;
|
||||
if(count >= 1536) count = 0;
|
||||
|
||||
return (seg->speed / 128);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
Custom effect that mimics a multiband VU meter
|
||||
|
||||
Keith Lord - 2018
|
||||
|
||||
LICENSE
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Keith Lord
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
CHANGELOG
|
||||
2018-08-21 initial version
|
||||
*/
|
||||
|
||||
#ifndef VUMeter_h
|
||||
#define VUMeter_h
|
||||
|
||||
#include <WS2812FX.h>
|
||||
|
||||
#ifndef NUM_BANDS
|
||||
#define NUM_BANDS 2
|
||||
#endif
|
||||
|
||||
// set USE_RANDOM_DATA to false in the line below if vuMeterBands[] is populated
|
||||
// by an external data source. otherwise random data will be used for the effect.
|
||||
#ifndef USE_RANDOM_DATA
|
||||
#define USE_RANDOM_DATA true
|
||||
#endif
|
||||
|
||||
extern WS2812FX ws2812fx;
|
||||
|
||||
uint8_t vuMeterBands[NUM_BANDS]; // global VU meter band amplitude data (range 0-255)
|
||||
|
||||
uint16_t vuMeter(void) {
|
||||
WS2812FX::Segment* seg = ws2812fx.getSegment();
|
||||
uint16_t seglen = seg->stop - seg->start + 1;
|
||||
uint16_t bandSize = seglen / NUM_BANDS;
|
||||
|
||||
for(uint8_t i=0; i<NUM_BANDS; i++) {
|
||||
#if USE_RANDOM_DATA
|
||||
int randomData = vuMeterBands[i] + ws2812fx.random8(32) - ws2812fx.random8(32);
|
||||
vuMeterBands[i] = (randomData < 0 || randomData > 255) ? 128 : randomData;
|
||||
#endif
|
||||
|
||||
uint8_t scaledBand = (vuMeterBands[i] * bandSize) / 256;
|
||||
for(uint16_t j=0; j<bandSize; j++) {
|
||||
uint16_t index = seg->start + (i * bandSize) + j;
|
||||
if(j <= scaledBand) {
|
||||
if(j < bandSize - 4) ws2812fx.setPixelColor(index, seg->colors[0]);
|
||||
else if(j < bandSize - 2) ws2812fx.setPixelColor(index, seg->colors[1]);
|
||||
else ws2812fx.setPixelColor(index, seg->colors[2]);
|
||||
} else {
|
||||
ws2812fx.setPixelColor(index, BLACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return seg->speed;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,35 +1,48 @@
|
||||
//#define USE_NEOANIMATIONFX // Uses NeoAnimationFX, PIN is ignored & set to RX/GPIO3 or UART method: D4/GPIO2, see: https://github.com/debsahu/NeoAnimationFX
|
||||
#define USE_WS2812FX // Uses WS2812FX, see: https://github.com/kitesurfer1404/WS2812FX
|
||||
//#define USE_WS2812FX_DMA // Uses PIN is ignored & set to RX/GPIO3 Uses WS2812FX, see: https://github.com/kitesurfer1404/WS2812FX
|
||||
//#define USE_WS2812FX_UART1 // Uses PIN is ignored & set to D4/GPIO2 Uses WS2812FX, see: https://github.com/kitesurfer1404/WS2812FX
|
||||
//#define USE_WS2812FX_UART2 // Uses PIN is ignored & set to TX/GPIO1 Uses WS2812FX, see: https://github.com/kitesurfer1404/WS2812FX
|
||||
|
||||
// Neopixel
|
||||
#define PIN 15 // PIN (15 / D8) where neopixel / WS2811 strip is attached
|
||||
#define NUMLEDS 12 // Number of leds in the strip
|
||||
#define NUMLEDS 194 // Number of leds in the strip
|
||||
#define BUILTIN_LED 2 // ESP-12F has the built in LED on GPIO2, see https://github.com/esp8266/Arduino/issues/2192
|
||||
#define BUTTON 14 // Input pin (14 / D5) for switching the LED strip on / off, connect this PIN to ground to trigger button.
|
||||
#define BUTTON_GY33 12 // Input pin (12 / D6) for read color data with RGB sensor, connect this PIN to ground to trigger button.
|
||||
#define RGBW // If defined, use RGBW Strips
|
||||
|
||||
const char HOSTNAME[] = "FABLightingRGBW"; // Friedly hostname
|
||||
const char HOSTNAME[] = "McLightingRGBW"; // Friedly hostname
|
||||
|
||||
#define HTTP_OTA // If defined, enable Added ESP8266HTTPUpdateServer
|
||||
//#define ENABLE_OTA // If defined, enable Arduino OTA code.
|
||||
#define HTTP_OTA // If defined, enable ESP8266HTTPUpdateServer OTA code.
|
||||
//#define ENABLE_OTA // If defined, enable Arduino OTA code.
|
||||
#define ENABLE_AMQTT // If defined, enable Async MQTT code, see: https://github.com/marvinroger/async-mqtt-client
|
||||
//#define ENABLE_MQTT // If defined, enable MQTT client code, see: https://github.com/toblum/McLighting/wiki/MQTT-API
|
||||
#define ENABLE_HOMEASSISTANT // If defined, enable Homeassistant integration, ENABLE_MQTT must be active
|
||||
//#define ENABLE_MQTT // If defined, enable MQTT client code, see: https://github.com/toblum/McLighting/wiki/MQTT-API
|
||||
#define ENABLE_HOMEASSISTANT // If defined, enable Homeassistant integration, ENABLE_MQTT or ENABLE_AMQTT must be active
|
||||
#define ENABLE_BUTTON // If defined, enable button handling code, see: https://github.com/toblum/McLighting/wiki/Button-control
|
||||
//#define ENABLE_BUTTON_GY33 // If defined, enable button handling code for GY-33 color sensor to scan color
|
||||
#define ENABLE_BUTTON_GY33 // If defined, enable button handling code for GY-33 color sensor to scan color
|
||||
//#define MQTT_HOME_ASSISTANT_SUPPORT // If defined, use AMQTT and select Tools -> IwIP Variant -> Higher Bandwidth
|
||||
#define ENABLE_LEGACY_ANIMATIONS
|
||||
#define ENABLE_STATE_SAVE_SPIFFS // If defined, saves state on SPIFFS
|
||||
//#define ENABLE_STATE_SAVE_EEPROM // If defined, save state on reboot
|
||||
//#define ENABLE_MQTT_HOSTNAME_CHIPID // Uncomment/comment to add ESPChipID to end of MQTT hostname
|
||||
#define DBG_OUTPUT_PORT Serial // Set debug output port
|
||||
|
||||
#if defined(USE_NEOANIMATIONFX) and defined(USE_WS2812FX)
|
||||
#error "Cant have both NeoAnimationFX and WS2812FX enabled. Choose either one."
|
||||
#define ENABLE_LEGACY_ANIMATIONS // Dont disbale this for now
|
||||
#define ENABLE_E131 // E1.31 implementation
|
||||
|
||||
#ifdef ENABLE_E131
|
||||
#define START_UNIVERSE 1 // First DMX Universe to listen for
|
||||
#define END_UNIVERSE 2 // Total number of Universes to listen for, starting at UNIVERSE
|
||||
#endif
|
||||
#if !defined(USE_NEOANIMATIONFX) and !defined(USE_WS2812FX)
|
||||
#error "Need to either use NeoAnimationFX and WS2812FX mode."
|
||||
|
||||
//#define WIFIMGR_PORTAL_TIMEOUT 180
|
||||
//#define WIFIMGR_SET_MANUAL_IP
|
||||
|
||||
#ifdef WIFIMGR_SET_MANUAL_IP
|
||||
uint8_t _ip[4] = {192,168,0,128};
|
||||
uint8_t _gw[4] = {192,168,0,1};
|
||||
uint8_t _sn[4] = {255,255,255,0};
|
||||
#endif
|
||||
|
||||
#ifdef MQTT_HOME_ASSISTANT_SUPPORT
|
||||
#define MQTT_HOME_ASSISTANT_0_84_SUPPORT // Comment if using HA version < 0.84
|
||||
#endif
|
||||
|
||||
#if defined(USE_WS2812FX_DMA) and defined(USE_WS2812FX_UART)
|
||||
#error "Cant have both DMA and UART method."
|
||||
#endif
|
||||
#if defined(ENABLE_MQTT) and defined(ENABLE_AMQTT)
|
||||
#error "Cant have both PubSubClient and AsyncMQTT enabled. Choose either one."
|
||||
@@ -43,15 +56,15 @@ const char HOSTNAME[] = "FABLightingRGBW"; // Friedly hostname
|
||||
|
||||
// parameters for automatically cycling favorite patterns
|
||||
uint32_t autoParams[][4] = { // color, speed, mode, duration (seconds)
|
||||
{0x00ff0000, 120, 1, 5.0}, // blink red for 5 seconds
|
||||
{0x0000ff00, 120, 3, 10.0}, // wipe green for 10 seconds
|
||||
{0x000000ff, 196, 14, 5.0}, // dual scan blue for 5 seconds
|
||||
{0x000000ff, 196, 46, 15.0} // fireworks for 15 seconds
|
||||
{0xff000000, 120, 1, 5.0}, // blink red for 5 seconds
|
||||
{0x00ff0000, 120, 3, 10.0}, // wipe green for 10 seconds
|
||||
{0x0000ff00, 196, 14, 5.0}, // dual scan blue for 5 seconds
|
||||
{0x0000ff00, 196, 46, 15.0} // fireworks for 15 seconds
|
||||
};
|
||||
|
||||
#if defined(ENABLE_MQTT) or defined(ENABLE_AMQTT)
|
||||
#ifdef ENABLE_MQTT
|
||||
#define MQTT_MAX_PACKET_SIZE 512
|
||||
#define MQTT_MAX_PACKET_SIZE 2048
|
||||
#define MQTT_MAX_RECONNECT_TRIES 4
|
||||
|
||||
int mqtt_reconnect_retries = 0;
|
||||
@@ -80,10 +93,11 @@ uint32_t autoParams[][4] = { // color, speed, mode, duration (seconds)
|
||||
uint16_t color_temp = 327; // min is 154 and max is 500
|
||||
#endif
|
||||
|
||||
//#define ENABLE_MQTT_HOSTNAME_CHIPID // Uncomment/comment to add ESPChipID to end of MQTT hostname
|
||||
#ifdef ENABLE_MQTT_HOSTNAME_CHIPID
|
||||
const char* mqtt_clientid = String(String(HOSTNAME) + "-" + String(ESP.getChipId())).c_str(); // MQTT ClientID
|
||||
char mqtt_clientid[64];
|
||||
#else
|
||||
const char* mqtt_clientid = HOSTNAME; // MQTT ClientID
|
||||
const char* mqtt_clientid = HOSTNAME;
|
||||
#endif
|
||||
|
||||
char mqtt_host[64] = "";
|
||||
@@ -96,10 +110,15 @@ uint32_t autoParams[][4] = { // color, speed, mode, duration (seconds)
|
||||
// ***************************************************************************
|
||||
// Global variables / definitions
|
||||
// ***************************************************************************
|
||||
#define DBG_OUTPUT_PORT Serial // Set debug output port
|
||||
|
||||
// List of all color modes
|
||||
#ifdef ENABLE_LEGACY_ANIMATIONS
|
||||
enum MODE { SET_MODE, HOLD, AUTO, OFF, TV, CUSTOM, SETCOLOR, SETSPEED, BRIGHTNESS, WIPE, RAINBOW, RAINBOWCYCLE, THEATERCHASE, TWINKLERANDOM, THEATERCHASERAINBOW};
|
||||
#ifdef ENABLE_E131
|
||||
enum MODE { SET_MODE, HOLD, AUTO, OFF, TV, CUSTOM, SETCOLOR, SETSPEED, BRIGHTNESS, WIPE, RAINBOW, RAINBOWCYCLE, THEATERCHASE, TWINKLERANDOM, THEATERCHASERAINBOW, E131 };
|
||||
#else
|
||||
enum MODE { SET_MODE, HOLD, AUTO, OFF, TV, CUSTOM, SETCOLOR, SETSPEED, BRIGHTNESS, WIPE, RAINBOW, RAINBOWCYCLE, THEATERCHASE, TWINKLERANDOM, THEATERCHASERAINBOW};
|
||||
#endif
|
||||
MODE mode = RAINBOW; // Standard mode that is active when software starts
|
||||
bool exit_func = false; // Global helper variable to get out of the color modes when mode changes
|
||||
#else
|
||||
@@ -126,9 +145,11 @@ struct ledstate // Data structure to store a state of a single led
|
||||
|
||||
typedef struct ledstate LEDState; // Define the datatype LEDState
|
||||
LEDState ledstates[NUMLEDS]; // Get an array of led states to store the state of the whole strip
|
||||
LEDState main_color = { 0, 255, 0, 0}; // Store the "main color" of the strip used in single color modes
|
||||
LEDState main_color = { 0, 255, 0, 0 }; // Store the "main color" of the strip used in single color modes
|
||||
|
||||
|
||||
#define ENABLE_STATE_SAVE_SPIFFS // If defined, saves state on SPIFFS
|
||||
//#define ENABLE_STATE_SAVE_EEPROM // If defined, save state on reboot
|
||||
#ifdef ENABLE_STATE_SAVE_EEPROM
|
||||
char current_state[36]; // Keeps the current state representation
|
||||
char last_state[36]; // Save the last state as string representation
|
||||
@@ -146,10 +167,10 @@ LEDState main_color = { 0, 255, 0, 0}; // Store the "main color" of the strip u
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_BUTTON
|
||||
#define BTN_MODE_SHORT "STA| 1| 0|245|196|255| 0| 0| 0" // Static white
|
||||
#define BTN_MODE_MEDIUM "STA| 1| 48|245|196| 0|255|102| 0" // Fire flicker
|
||||
#define BTN_MODE_LONG "STA| 1| 46|253|196| 0|255|102| 0" // Fireworks random
|
||||
|
||||
#define BTN_MODE_SHORT "STA| 1| 0|245|196| 0| 0| 0|255" // Static white
|
||||
#define BTN_MODE_MEDIUM "STA| 1| 48|245|196|255|102| 0| 0" // Fire flicker
|
||||
#define BTN_MODE_LONG "STA| 1| 46|253|196|255|102| 0| 0" // Fireworks random
|
||||
|
||||
unsigned long keyPrevMillis = 0;
|
||||
const unsigned long keySampleIntervalMs = 25;
|
||||
byte longKeyPressCountMax = 80; // 80 * 25 = 2000 ms
|
||||
|
||||
@@ -1,6 +1,40 @@
|
||||
// ***************************************************************************
|
||||
// Request handlers
|
||||
// ***************************************************************************
|
||||
#ifdef ENABLE_E131
|
||||
void checkForRequests(void); //prototype
|
||||
|
||||
void handleE131(){
|
||||
if (!e131.isEmpty())
|
||||
{
|
||||
e131_packet_t packet;
|
||||
e131.pull(&packet); // Pull packet from ring buffer
|
||||
|
||||
uint16_t universe = htons(packet.universe);
|
||||
uint8_t *data = packet.property_values + 1;
|
||||
|
||||
if (universe < START_UNIVERSE || universe > END_UNIVERSE) return; //async will take care about filling the buffer
|
||||
|
||||
// Serial.printf("Universe %u / %u Channels | Packet#: %u / Errors: %u / CH1: %u\n",
|
||||
// htons(packet.universe), // The Universe for this packet
|
||||
// htons(packet.property_value_count) - 1, // Start code is ignored, we're interested in dimmer data
|
||||
// e131.stats.num_packets, // Packet counter
|
||||
// e131.stats.packet_errors, // Packet error counter
|
||||
// packet.property_values[1]); // Dimmer data for Channel 1
|
||||
|
||||
uint16_t multipacketOffset = (universe - START_UNIVERSE) * 170; //if more than 170 LEDs (510 channels), client will send in next higher universe
|
||||
if (NUMLEDS <= multipacketOffset) return;
|
||||
uint16_t len = (170 + multipacketOffset > NUMLEDS) ? (NUMLEDS - multipacketOffset) : 170;
|
||||
for (uint16_t i = 0; i < len; i++){
|
||||
uint16_t j = i * 3;
|
||||
strip.setPixelColor(i + multipacketOffset, data[j], data[j + 1], data[j + 2]);
|
||||
}
|
||||
strip.show();
|
||||
checkForRequests();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
void tickerSendState(){
|
||||
new_ha_mqtt_msg = true;
|
||||
@@ -15,18 +49,18 @@ void tickerSpiffsSaveState(){
|
||||
void getArgs() {
|
||||
if (server.arg("rgb") != "") {
|
||||
uint32_t rgb = (uint32_t) strtoul(server.arg("rgb").c_str(), NULL, 16);
|
||||
main_color.white = ((rgb >> 24) & 0xFF);
|
||||
main_color.red = ((rgb >> 16) & 0xFF);
|
||||
main_color.green = ((rgb >> 8) & 0xFF);
|
||||
main_color.blue = ((rgb ) & 0xFF);
|
||||
main_color.red = ((rgb >> 24) & 0xFF);
|
||||
main_color.green = ((rgb >> 16) & 0xFF);
|
||||
main_color.blue = ((rgb >> 8) & 0xFF);
|
||||
main_color.white = ((rgb >> 0) & 0xFF);
|
||||
} else {
|
||||
main_color.white = server.arg("w").toInt();
|
||||
main_color.red = server.arg("r").toInt();
|
||||
main_color.red = server.arg("r").toInt();
|
||||
main_color.green = server.arg("g").toInt();
|
||||
main_color.blue = server.arg("b").toInt();
|
||||
main_color.blue = server.arg("b").toInt();
|
||||
main_color.white = server.arg("w").toInt();
|
||||
}
|
||||
if (server.arg("s") != "") {
|
||||
ws2812fx_speed = constrain(server.arg("s").toInt(), 0, 255);
|
||||
ws2812fx_speed = constrain(server.arg("s").toInt(), 0, 255);
|
||||
}
|
||||
|
||||
if (server.arg("m") != "") {
|
||||
@@ -39,21 +73,21 @@ void getArgs() {
|
||||
brightness = constrain(server.arg("p").toInt(), 0, 255);
|
||||
}
|
||||
|
||||
main_color.white = constrain(main_color.white, 0, 255);
|
||||
main_color.red = constrain(main_color.red, 0, 255);
|
||||
main_color.red = constrain(main_color.red, 0, 255);
|
||||
main_color.green = constrain(main_color.green, 0, 255);
|
||||
main_color.blue = constrain(main_color.blue, 0, 255);
|
||||
|
||||
main_color.blue = constrain(main_color.blue, 0, 255);
|
||||
main_color.white = constrain(main_color.white, 0, 255);
|
||||
|
||||
DBG_OUTPUT_PORT.print("Mode: ");
|
||||
DBG_OUTPUT_PORT.print(mode);
|
||||
DBG_OUTPUT_PORT.print(", Color: ");
|
||||
DBG_OUTPUT_PORT.print(main_color.white);
|
||||
DBG_OUTPUT_PORT.print(", ");
|
||||
DBG_OUTPUT_PORT.print(main_color.red);
|
||||
DBG_OUTPUT_PORT.print(", ");
|
||||
DBG_OUTPUT_PORT.print(main_color.green);
|
||||
DBG_OUTPUT_PORT.print(", ");
|
||||
DBG_OUTPUT_PORT.print(main_color.blue);
|
||||
DBG_OUTPUT_PORT.print(", ");
|
||||
DBG_OUTPUT_PORT.print(main_color.white);
|
||||
DBG_OUTPUT_PORT.print(", Speed:");
|
||||
DBG_OUTPUT_PORT.print(ws2812fx_speed);
|
||||
DBG_OUTPUT_PORT.print(", Brightness:");
|
||||
@@ -81,10 +115,11 @@ uint16_t convertSpeed(uint8_t mcl_speed) {
|
||||
void handleSetMainColor(uint8_t * mypayload) {
|
||||
// decode rgb data
|
||||
uint32_t rgb = (uint32_t) strtoul((const char *) &mypayload[1], NULL, 16);
|
||||
main_color.white = ((rgb >> 24) & 0xFF);
|
||||
main_color.red = ((rgb >> 16) & 0xFF);
|
||||
main_color.green = ((rgb >> 8) & 0xFF);
|
||||
main_color.blue = ((rgb ) & 0xFF);
|
||||
main_color.red = ((rgb >> 24) & 0xFF);
|
||||
main_color.green = ((rgb >> 16) & 0xFF);
|
||||
main_color.blue = ((rgb >> 8) & 0xFF);
|
||||
main_color.white = ((rgb >> 0) & 0xFF);
|
||||
// strip.setColor(main_color.red, main_color.green, main_color.blue);
|
||||
mode = SETCOLOR;
|
||||
}
|
||||
|
||||
@@ -92,12 +127,12 @@ void handleSetAllMode(uint8_t * mypayload) {
|
||||
// decode rgb data
|
||||
uint32_t rgb = (uint32_t) strtoul((const char *) &mypayload[1], NULL, 16);
|
||||
|
||||
main_color.white = ((rgb >> 24) & 0xFF);
|
||||
main_color.red = ((rgb >> 16) & 0xFF);
|
||||
main_color.green = ((rgb >> 8) & 0xFF);
|
||||
main_color.blue = ((rgb ) & 0xFF);
|
||||
main_color.red = ((rgb >> 24) & 0xFF);
|
||||
main_color.green = ((rgb >> 16) & 0xFF);
|
||||
main_color.blue = ((rgb >> 8) & 0xFF);
|
||||
main_color.white = ((rgb >> 0) & 0xFF);
|
||||
|
||||
DBG_OUTPUT_PORT.printf("WS: Set all leds to main color: W: [%u] R: [%u] G: [%u] B: [%u]\n", main_color.white, main_color.red, main_color.green, main_color.blue);
|
||||
DBG_OUTPUT_PORT.printf("WS: Set all leds to main color: R: [%u] G: [%u] B: [%u] W: [%u]\n", main_color.red, main_color.green, main_color.blue, main_color.white);
|
||||
#ifdef ENABLE_LEGACY_ANIMATIONS
|
||||
exit_func = true;
|
||||
#endif
|
||||
@@ -113,23 +148,21 @@ void handleSetSingleLED(uint8_t * mypayload, uint8_t firstChar = 0) {
|
||||
|
||||
DBG_OUTPUT_PORT.printf("led value: [%i]. Entry threshold: <= [%i] (=> %s)\n", led, strip.numPixels(), mypayload );
|
||||
if (led <= strip.numPixels()) {
|
||||
char whitehex[3];
|
||||
char redhex[3];
|
||||
char greenhex[3];
|
||||
char bluehex[3];
|
||||
strncpy (whitehex, (const char *) &mypayload[2 + firstChar], 2 );
|
||||
strncpy (redhex, (const char *) &mypayload[4 + firstChar], 2 );
|
||||
strncpy (greenhex, (const char *) &mypayload[6 + firstChar], 2 );
|
||||
strncpy (bluehex, (const char *) &mypayload[8 + firstChar], 2 );
|
||||
ledstates[led].white = strtol(whitehex, NULL, 16);
|
||||
char whitehex[3];
|
||||
strncpy (redhex, (const char *) &mypayload[2 + firstChar], 2 );
|
||||
strncpy (greenhex, (const char *) &mypayload[4 + firstChar], 2 );
|
||||
strncpy (bluehex, (const char *) &mypayload[6 + firstChar], 2 );
|
||||
strncpy (whitehex, (const char *) &mypayload[2 + firstChar], 2 );
|
||||
ledstates[led].red = strtol(redhex, NULL, 16);
|
||||
ledstates[led].green = strtol(greenhex, NULL, 16);
|
||||
ledstates[led].blue = strtol(bluehex, NULL, 16);
|
||||
DBG_OUTPUT_PORT.printf(" rgb.white: [%s] rgb.red: [%s] rgb.green: [%s] rgb.blue: [%s]\n", whitehex, redhex, greenhex, bluehex);
|
||||
DBG_OUTPUT_PORT.printf(" rgb.white: [%i] rgb.red: [%i] rgb.green: [%i] rgb.blue: [%i]\n", strtol(whitehex, NULL, 16), strtol(redhex, NULL, 16), strtol(greenhex, NULL, 16), strtol(bluehex, NULL, 16));
|
||||
DBG_OUTPUT_PORT.printf("WS: Set single led [%i] to [%i] [%i] [%i] [%i] (%s)!\n", led, ledstates[led].white, ledstates[led].red, ledstates[led].green, ledstates[led].blue, mypayload);
|
||||
|
||||
|
||||
ledstates[led].white = strtol(whitehex, NULL, 16);
|
||||
DBG_OUTPUT_PORT.printf("rgb.red: [%s] rgb.green: [%s] rgb.blue: [%s] rgb.white: [%s]\n", redhex, greenhex, bluehex, whitehex);
|
||||
DBG_OUTPUT_PORT.printf("rgb.red: [%i] rgb.green: [%i] rgb.blue: [%i] rgb.white: [%i]\n", strtol(redhex, NULL, 16), strtol(greenhex, NULL, 16), strtol(bluehex, NULL, 16), strtol(whitehex, NULL, 16));
|
||||
DBG_OUTPUT_PORT.printf("WS: Set single led [%i] to [%i] [%i] [%i] [%i] (%s)!\n", led, ledstates[led].red, ledstates[led].green, ledstates[led].blue, ledstates[led].white, mypayload);
|
||||
strip.setPixelColor(led, ledstates[led].red, ledstates[led].green, ledstates[led].blue, ledstates[led].white);
|
||||
strip.show();
|
||||
}
|
||||
@@ -194,27 +227,27 @@ void setModeByStateString(String saved_state_string) {
|
||||
ws2812fx_speed = str_ws2812fx_speed.toInt();
|
||||
String str_brightness = getValue(saved_state_string, '|', 4);
|
||||
brightness = str_brightness.toInt();
|
||||
String str_white = getValue(saved_state_string, '|', 5);
|
||||
main_color.white = str_white.toInt();
|
||||
String str_red = getValue(saved_state_string, '|', 6);
|
||||
String str_red = getValue(saved_state_string, '|', 5);
|
||||
main_color.red = str_red.toInt();
|
||||
String str_green = getValue(saved_state_string, '|', 7);
|
||||
String str_green = getValue(saved_state_string, '|', 6);
|
||||
main_color.green = str_green.toInt();
|
||||
String str_blue = getValue(saved_state_string, '|', 8);
|
||||
String str_blue = getValue(saved_state_string, '|', 7);
|
||||
main_color.blue = str_blue.toInt();
|
||||
String str_white = getValue(saved_state_string, '|', 8);
|
||||
main_color.white = str_white.toInt();
|
||||
|
||||
DBG_OUTPUT_PORT.printf("ws2812fx_mode: %d\n", ws2812fx_mode);
|
||||
DBG_OUTPUT_PORT.printf("ws2812fx_speed: %d\n", ws2812fx_speed);
|
||||
DBG_OUTPUT_PORT.printf("brightness: %d\n", brightness);
|
||||
DBG_OUTPUT_PORT.printf("main_color.white: %d\n", main_color.white);
|
||||
DBG_OUTPUT_PORT.printf("main_color.red: %d\n", main_color.red);
|
||||
DBG_OUTPUT_PORT.printf("main_color.green: %d\n", main_color.green);
|
||||
DBG_OUTPUT_PORT.printf("main_color.blue: %d\n", main_color.blue);
|
||||
DBG_OUTPUT_PORT.printf("main_color.white: %d\n", main_color.white);
|
||||
|
||||
strip.setMode(ws2812fx_mode);
|
||||
strip.setSpeed(convertSpeed(ws2812fx_speed));
|
||||
strip.setBrightness(brightness);
|
||||
strip.setColor(main_color.white, main_color.red, main_color.green, main_color.blue);
|
||||
strip.setColor(main_color.red, main_color.green, main_color.blue, main_color.white);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_LEGACY_ANIMATIONS
|
||||
@@ -285,6 +318,19 @@ void setModeByStateString(String saved_state_string) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_E131
|
||||
void handleE131NamedMode(String str_mode) {
|
||||
exit_func = true;
|
||||
if (str_mode.startsWith("=e131") or str_mode.startsWith("/e131")) {
|
||||
if(strip.isRunning()) strip.stop();
|
||||
mode = E131;
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void handleSetWS2812FXMode(uint8_t * mypayload) {
|
||||
mode = SET_MODE;
|
||||
uint8_t ws2812fx_mode_tmp = (uint8_t) strtol((const char *) &mypayload[1], NULL, 10);
|
||||
@@ -294,7 +340,7 @@ void handleSetWS2812FXMode(uint8_t * mypayload) {
|
||||
String listStatusJSON(void) {
|
||||
uint8_t tmp_mode = (mode == SET_MODE) ? (uint8_t) ws2812fx_mode : strip.getMode();
|
||||
|
||||
const size_t bufferSize = JSON_ARRAY_SIZE(3) + JSON_OBJECT_SIZE(6);
|
||||
const size_t bufferSize = JSON_ARRAY_SIZE(3) + JSON_OBJECT_SIZE(6) + 500;
|
||||
DynamicJsonDocument jsonBuffer(bufferSize);
|
||||
JsonObject root = jsonBuffer.to<JsonObject>();
|
||||
root["mode"] = (uint8_t) mode;
|
||||
@@ -303,11 +349,11 @@ String listStatusJSON(void) {
|
||||
root["speed"] = ws2812fx_speed;
|
||||
root["brightness"] = brightness;
|
||||
JsonArray color = root.createNestedArray("color");
|
||||
color.add(main_color.white);
|
||||
color.add(main_color.red);
|
||||
color.add(main_color.green);
|
||||
color.add(main_color.blue);
|
||||
|
||||
color.add(main_color.white);
|
||||
|
||||
String json;
|
||||
serializeJson(root, json);
|
||||
|
||||
@@ -320,9 +366,14 @@ void getStatusJSON() {
|
||||
}
|
||||
|
||||
String listModesJSON(void) {
|
||||
const size_t bufferSize = JSON_ARRAY_SIZE(strip.getModeCount()+1) + strip.getModeCount()*JSON_OBJECT_SIZE(2);
|
||||
const size_t bufferSize = JSON_ARRAY_SIZE(strip.getModeCount()+1) + strip.getModeCount()*JSON_OBJECT_SIZE(2) + 1000;
|
||||
DynamicJsonDocument jsonBuffer(bufferSize);
|
||||
JsonArray json = jsonBuffer.to<JsonArray>();
|
||||
#ifdef ENABLE_E131
|
||||
JsonObject objecte131 = json.createNestedObject();
|
||||
objecte131["mode"] = "e131";
|
||||
objecte131["name"] = "E131";
|
||||
#endif
|
||||
for (uint8_t i = 0; i < strip.getModeCount(); i++) {
|
||||
JsonObject object = json.createNestedObject();
|
||||
object["mode"] = i;
|
||||
@@ -425,7 +476,7 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) {
|
||||
if (payload[0] == '#') {
|
||||
handleSetMainColor(payload);
|
||||
Dbg_Prefix(mqtt, num);
|
||||
DBG_OUTPUT_PORT.printf("Set main color to: W: [%u] R: [%u] G: [%u] B: [%u]\n", main_color.white, main_color.red, main_color.green, main_color.blue);
|
||||
DBG_OUTPUT_PORT.printf("Set main color to: R: [%u] G: [%u] B: [%u] W: [%u]\n", main_color.red, main_color.green, main_color.blue, main_color.white);
|
||||
#ifdef ENABLE_MQTT
|
||||
mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str());
|
||||
#endif
|
||||
@@ -434,7 +485,7 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) {
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = true;
|
||||
if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState);
|
||||
if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState);
|
||||
#endif
|
||||
#ifdef ENABLE_STATE_SAVE_SPIFFS
|
||||
if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState);
|
||||
@@ -449,6 +500,7 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) {
|
||||
Dbg_Prefix(mqtt, num);
|
||||
DBG_OUTPUT_PORT.printf("Set speed to: [%u]\n", ws2812fx_speed);
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = true;
|
||||
if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState);
|
||||
#endif
|
||||
#ifdef ENABLE_MQTT
|
||||
@@ -548,7 +600,10 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) {
|
||||
String str_mode = String((char *) &payload[0]);
|
||||
|
||||
handleSetNamedMode(str_mode);
|
||||
Dbg_Prefix(mqtt, num);
|
||||
#ifdef ENABLE_E131
|
||||
handleE131NamedMode(str_mode);
|
||||
#endif
|
||||
Dbg_Prefix(mqtt, num);
|
||||
DBG_OUTPUT_PORT.printf("Activated mode [%u]!\n", mode);
|
||||
#ifdef ENABLE_MQTT
|
||||
mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str());
|
||||
@@ -615,6 +670,10 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) {
|
||||
// / ==> Set WS2812 mode.
|
||||
if (payload[0] == '/') {
|
||||
handleSetWS2812FXMode(payload);
|
||||
#ifdef ENABLE_E131
|
||||
String str_mode = String((char *) &payload[0]);
|
||||
handleE131NamedMode(str_mode);
|
||||
#endif
|
||||
Dbg_Prefix(mqtt, num);
|
||||
DBG_OUTPUT_PORT.printf("Set WS2812 mode: [%s]\n", payload);
|
||||
#ifdef ENABLE_MQTT
|
||||
@@ -747,7 +806,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght
|
||||
}
|
||||
|
||||
void sendState() {
|
||||
const size_t bufferSize = JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6);
|
||||
const size_t bufferSize = JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 500;
|
||||
DynamicJsonDocument jsonBuffer(bufferSize);
|
||||
JsonObject root = jsonBuffer.to<JsonObject>();
|
||||
|
||||
@@ -763,9 +822,16 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght
|
||||
|
||||
root["speed"] = ws2812fx_speed;
|
||||
|
||||
char modeName[30];
|
||||
strncpy_P(modeName, (PGM_P)strip.getModeName(strip.getMode()), sizeof(modeName)); // copy from progmem
|
||||
root["effect"] = modeName;
|
||||
//char modeName[30];
|
||||
//strncpy_P(modeName, (PGM_P)strip.getModeName(strip.getMode()), sizeof(modeName)); // copy from progmem
|
||||
#if defined(ENABLE_E131) and defined(ENABLE_HOMEASSISTANT)
|
||||
if (mode == E131)
|
||||
root["effect"] = "E131";
|
||||
else
|
||||
root["effect"] = strip.getModeName(strip.getMode());
|
||||
#else
|
||||
root["effect"] = strip.getModeName(strip.getMode());
|
||||
#endif
|
||||
|
||||
char buffer[measureJson(root) + 1];
|
||||
serializeJson(root, buffer, sizeof(buffer));
|
||||
@@ -835,9 +901,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght
|
||||
}
|
||||
|
||||
if (root.containsKey("brightness")) {
|
||||
const char * brightness_json = root["brightness"];
|
||||
uint8_t b = (uint8_t) strtol((const char *) &brightness_json[0], NULL, 10);
|
||||
brightness = constrain(b, 0, 255);
|
||||
brightness = constrain((uint8_t) root["brightness"], 0, 255); //fix #224
|
||||
mode = BRIGHTNESS;
|
||||
}
|
||||
|
||||
@@ -846,6 +910,13 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght
|
||||
String effectString = root["effect"].as<String>();
|
||||
|
||||
for (uint8_t i = 0; i < strip.getModeCount(); i++) {
|
||||
#if defined(ENABLE_E131) and defined(ENABLE_HOMEASSISTANT)
|
||||
if(effectString == "E131"){
|
||||
if(strip.isRunning()) strip.stop();
|
||||
mode = E131;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if(String(strip.getModeName(i)) == effectString) {
|
||||
mode = SET_MODE;
|
||||
ws2812fx_mode = i;
|
||||
@@ -920,10 +991,14 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght
|
||||
ha_send_data.detach();
|
||||
mqtt_client.subscribe(mqtt_ha_state_in.c_str(), qossub);
|
||||
#ifdef MQTT_HOME_ASSISTANT_SUPPORT
|
||||
DynamicJsonDocument jsonBuffer(JSON_ARRAY_SIZE(strip.getModeCount()) + JSON_OBJECT_SIZE(11));
|
||||
DynamicJsonDocument jsonBuffer(JSON_ARRAY_SIZE(strip.getModeCount()) + JSON_OBJECT_SIZE(12) + 1500);
|
||||
JsonObject json = jsonBuffer.to<JsonObject>();
|
||||
json["name"] = HOSTNAME;
|
||||
#ifdef MQTT_HOME_ASSISTANT_0_84_SUPPORT
|
||||
json["schema"] = "json";
|
||||
#else
|
||||
json["platform"] = "mqtt_json";
|
||||
#endif
|
||||
json["state_topic"] = mqtt_ha_state_out;
|
||||
json["command_topic"] = mqtt_ha_state_in;
|
||||
json["on_command_type"] = "first";
|
||||
@@ -936,6 +1011,9 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght
|
||||
for (uint8_t i = 0; i < strip.getModeCount(); i++) {
|
||||
effect_list.add(strip.getModeName(i));
|
||||
}
|
||||
#if defined(ENABLE_E131) and defined(MQTT_HOME_ASSISTANT_SUPPORT)
|
||||
effect_list.add("E131");
|
||||
#endif
|
||||
char buffer[measureJson(json) + 1];
|
||||
serializeJson(json, buffer, sizeof(buffer));
|
||||
mqtt_client.publish(String("homeassistant/light/" + String(HOSTNAME) + "/config").c_str(), buffer, true);
|
||||
@@ -1016,6 +1094,9 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght
|
||||
for (uint8_t i = 0; i < strip.getModeCount(); i++) {
|
||||
effect_list.add(strip.getModeName(i));
|
||||
}
|
||||
#if defined(ENABLE_E131) and defined(MQTT_HOME_ASSISTANT_SUPPORT)
|
||||
effect_list.add("E131");
|
||||
#endif
|
||||
char buffer[measureJson(json) + 1];
|
||||
serializeJson(json, buffer, sizeof(buffer));
|
||||
DBG_OUTPUT_PORT.println(buffer);
|
||||
@@ -1172,7 +1253,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght
|
||||
uint8_t r, g, b, col, conf;
|
||||
tcs.getData(&r, &g, &b, &col, &conf);
|
||||
DBG_OUTPUT_PORT.printf("Colors: R: [%d] G: [%d] B: [%d] Color: [%d] Conf: [%d]\n", (int)r, (int)g, (int)b, (int)col, (int)conf);
|
||||
main_color.white = 0; main_color.red = (pow((r/255.0), 2.5)*255); main_color.green = (pow((g/255.0), 2.5)*255); main_color.blue = (pow((b/255.0), 2.5)*255);
|
||||
main_color.red = (pow((r/255.0), 2.5)*255); main_color.green = (pow((g/255.0), 2.5)*255); main_color.blue = (pow((b/255.0), 2.5)*255);main_color.white = 0;
|
||||
ws2812fx_mode = 0;
|
||||
mode = SET_MODE;
|
||||
buttonState = true;
|
||||
@@ -1241,14 +1322,14 @@ bool writeConfigFS(bool saveConfig){
|
||||
//FS save
|
||||
updateFS = true;
|
||||
DBG_OUTPUT_PORT.print("Saving config: ");
|
||||
DynamicJsonDocument jsonBuffer(JSON_OBJECT_SIZE(4));
|
||||
DynamicJsonDocument jsonBuffer;
|
||||
JsonObject json = jsonBuffer.to<JsonObject>();
|
||||
json["mqtt_host"] = mqtt_host;
|
||||
json["mqtt_port"] = mqtt_port;
|
||||
json["mqtt_user"] = mqtt_user;
|
||||
json["mqtt_pass"] = mqtt_pass;
|
||||
|
||||
// SPIFFS.remove("/config.json") ? DBG_OUTPUT_PORT.println("removed file") : DBG_OUTPUT_PORT.println("failed removing file");
|
||||
//SPIFFS.remove("/config.json") ? DBG_OUTPUT_PORT.println("removed file") : DBG_OUTPUT_PORT.println("failed removing file");
|
||||
File configFile = SPIFFS.open("/config.json", "w");
|
||||
if (!configFile) DBG_OUTPUT_PORT.println("failed to open config file for writing");
|
||||
|
||||
@@ -1310,18 +1391,18 @@ bool writeStateFS(){
|
||||
updateFS = true;
|
||||
//save the strip state to FS JSON
|
||||
DBG_OUTPUT_PORT.print("Saving cfg: ");
|
||||
DynamicJsonDocument jsonBuffer(JSON_OBJECT_SIZE(7));
|
||||
DynamicJsonDocument jsonBuffer;
|
||||
JsonObject json = jsonBuffer.to<JsonObject>();
|
||||
json["mode"] = static_cast<int>(mode);
|
||||
json["strip_mode"] = (int) strip.getMode();
|
||||
json["brightness"] = brightness;
|
||||
json["speed"] = ws2812fx_speed;
|
||||
json["white"] = main_color.white;
|
||||
json["red"] = main_color.red;
|
||||
json["green"] = main_color.green;
|
||||
json["blue"] = main_color.blue;
|
||||
json["white"] = main_color.white;
|
||||
|
||||
// SPIFFS.remove("/state.json") ? DBG_OUTPUT_PORT.println("removed file") : DBG_OUTPUT_PORT.println("failed removing file");
|
||||
//SPIFFS.remove("/stripstate.json") ? DBG_OUTPUT_PORT.println("removed file") : DBG_OUTPUT_PORT.println("failed removing file");
|
||||
File configFile = SPIFFS.open("/stripstate.json", "w");
|
||||
if (!configFile) {
|
||||
DBG_OUTPUT_PORT.println("Failed!");
|
||||
@@ -1362,15 +1443,21 @@ bool readStateFS() {
|
||||
ws2812fx_mode = json["strip_mode"];
|
||||
brightness = json["brightness"];
|
||||
ws2812fx_speed = json["speed"];
|
||||
main_color.white = json["white"];
|
||||
main_color.red = json["red"];
|
||||
main_color.green = json["green"];
|
||||
main_color.blue = json["blue"];
|
||||
|
||||
main_color.white = json["white"];
|
||||
|
||||
strip.setMode(ws2812fx_mode);
|
||||
strip.setSpeed(convertSpeed(ws2812fx_speed));
|
||||
strip.setBrightness(brightness);
|
||||
strip.setColor(main_color.white, main_color.red, main_color.green, main_color.blue);
|
||||
strip.setColor(main_color.red, main_color.green, main_color.blue, main_color.white);
|
||||
|
||||
#ifdef ENABLE_E131
|
||||
if (mode == E131) {
|
||||
strip.stop();
|
||||
}
|
||||
#endif
|
||||
|
||||
updateFS = false;
|
||||
return true;
|
||||
|
||||
@@ -69,7 +69,7 @@ bool handleFileRead(String path) {
|
||||
if (SPIFFS.exists(pathWithGz))
|
||||
path += ".gz";
|
||||
File file = SPIFFS.open(path, "r");
|
||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
||||
size_t sent = server.streamFile(file, contentType);
|
||||
file.close();
|
||||
return true;
|
||||
@@ -154,6 +154,6 @@ void handleFileList() {
|
||||
}
|
||||
|
||||
output += "]";
|
||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
||||
server.send(200, "text/json", output);
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define SKETCH_VERSION "2.1.4"
|
||||
#define SKETCH_VERSION "2.2.0"
|
||||
@@ -17,4 +17,46 @@
|
||||
*
|
||||
* 10 Jul 2018 v 2.1.4
|
||||
* - Fixes measureJson() as pointed in #206
|
||||
*
|
||||
* 2 Oct 2018 v 2.1.5
|
||||
* - Try fixing #224 HA brightness causes reboot
|
||||
*
|
||||
* 5 Nov 2018 v 2.1.6
|
||||
* - Retire NeoAnimationFX
|
||||
* - Use DMA or UART method along with WS2812FX instead
|
||||
* - fix #248
|
||||
*
|
||||
* 3 Dec 2018 v 2.1.7
|
||||
* - Contributions by @ MrTheBarbarian from #270
|
||||
* - rethink ESP.getChipId implementaion
|
||||
* - check ArduinoJSON version
|
||||
* - Try restting prevmode as suggested in #276
|
||||
*
|
||||
* 11 Dec 2018 v 2.1.8
|
||||
* - Fix Auto-Discovery for HA version >= 0.84 #286
|
||||
* - Fix #283
|
||||
*
|
||||
* 12 Dec 2018 v 2.2.0
|
||||
* - Add E1.31 mode initial commit
|
||||
* - E1.31 mode when activated now stops current animation
|
||||
*
|
||||
* 13 Dec 2018 v 2.1.9
|
||||
* - HA is not getting the correct animation name being run, boils down to changes to ArduinoJson library
|
||||
* - Bump ArduinoJson library requirment for v6.7.0-beta (better memory management)
|
||||
* - sendState() needs extra memory for jsonBuffer
|
||||
* - sensState() effect can be sent directly instead of copying from PROGMEM
|
||||
*
|
||||
* 16 Dec 2018 v 2.1.10
|
||||
* - more ArduinoJson library memory managment fixes
|
||||
*
|
||||
* 18 Dec 2018 v 2.1.11
|
||||
* - More Auto-Discovery fix for HA version >= 0.84 #286
|
||||
* - Suggestions from https://github.com/home-assistant/home-assistant/issues/19420
|
||||
*
|
||||
* 23 Dec 2018 v 2.2.0
|
||||
* - Add E1.31 mode to getModes(), no need to change McLightingUI
|
||||
*
|
||||
* 6 Jan 2018 v 2.2.0
|
||||
* - fix webserver not responding when E1.31 is mode is acivated: do a webserver.loop() for every 1.31 packet
|
||||
* - HA E1.31 mode added
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user