update to 2.20
update to 2.20
This commit is contained in:
+10
-2
@@ -1,4 +1,12 @@
|
||||
clients/web/node_modules/
|
||||
|
||||
clients/web/\.vscode/
|
||||
*.DS_Store
|
||||
|
||||
.pioenvs
|
||||
.piolibdeps
|
||||
lib/readme.txt
|
||||
|
||||
*.h.gch
|
||||
.clang_complete
|
||||
.gcc-flags.json
|
||||
|
||||
.vscode/*
|
||||
@@ -0,0 +1,6 @@
|
||||
[submodule "Arduino/McLighting/data/McLightingUI"]
|
||||
path = Arduino/McLighting/data/McLightingUI
|
||||
url = https://github.com/toblum/McLightingUI
|
||||
[submodule "clients/web/McLightingUI"]
|
||||
path = clients/web/McLightingUI
|
||||
url = https://github.com/toblum/McLightingUI
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
language: python
|
||||
python:
|
||||
- "2.7"
|
||||
sudo: false
|
||||
cache:
|
||||
directories:
|
||||
- "~/.platformio"
|
||||
env:
|
||||
- PLATFORMIO_CI_SRC=Arduino/McLighting
|
||||
install:
|
||||
- pip install -U platformio
|
||||
- platformio update
|
||||
script:
|
||||
- platformio ci --project-conf=./platformio.ini -v
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -1,165 +1,21 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
MIT License
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
Copyright (c) 2018 Tobias Blum @toblum, Debashish Sahu @debsahu
|
||||
|
||||
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, sublicense, 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:
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
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.
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
Update 13.05.2018:
|
||||
I've worked on a new web UI for the last weeks. It's now available as an early preview. There is a [video](https://youtu.be/lryDPMA2qpY) that shows the new features. [Try it out](https://github.com/toblum/McLightingUI) if you want and leave some feedback.
|
||||
|
||||
Update 07.04.2018:
|
||||
And even more changes to McLighting! Most of them were contributed by user @debsahu. Thank you!
|
||||
- Update arduino-esp8266 to latest, at least version 2.4.1
|
||||
- AMQTT is now the default MQTT library, it's a bit more lightweight and stable. You can still use PubSubClient if you want to.
|
||||
- You can use @debsahu great NeoAnimationFX library as a alternative to WS2812FX. It's based on the NeoPixelBus instead of Adafruits NeoPixel library. It can handle longer strips more efficient. If you want, give it a try. WS2812FX is still the default.
|
||||
- Some more changes regarding Homeassistant integration.
|
||||
Please see the [Wiki](https://github.com/toblum/McLighting/wiki/Software-installation) for details on the required libraries.
|
||||
If you have problems with the new version, let us know. You can get the last version [here](https://github.com/toblum/McLighting/tree/Before_AMQTT_NeoAnimationFX).
|
||||
|
||||
I'm also working on a alternative web interface for McLighting in the meanwhile, but it may take some more time.
|
||||
For the german users: McLighting was used in [Kliemannsland](https://youtu.be/3TUjszkS3bY?t=1211) (a funny web show) when they built a really big Neopixel installation.
|
||||
|
||||
Update 18.03.2018:
|
||||
The code for integration with homeassistant was merged into master. It's currently active by default. You can safely disable it in definitions.h when use do not want to use it, or want to use McLighting on a small ESP_01.
|
||||
There are some informations in the [Wiki](https://github.com/toblum/McLighting/wiki/Homeassistant-integration).
|
||||
|
||||
Update 17.02.2018:
|
||||
User @debsahu contributed code for integration with homeassistant. It's currently in a separate branch (https://github.com/toblum/McLighting/tree/feature/ha_integration). If you're using Homeassistant, please try it out and give feedback.
|
||||
User @FabLab-Luenn created a version of McLighting (https://github.com/FabLab-Luenen/McLighting) for 6812 and other RGBW strips. Give it a try, if you own such strips.
|
||||
A thank you goes to all contributors.
|
||||
|
||||
Update 12. / 15.02.2018:
|
||||
Added Home Assistant Support using MQTT Light. A better implementation would be using MQTT Light JSON.
|
||||
Replaced Home Assistant Support using MQTT Light to MQTT JSON Light.
|
||||
|
||||
Update 31.01.2018:
|
||||
User @codmpm did a very professional McLighting installation and even designed his own PCBs. He has a great writeup for his project at: https://allgeek.de/2018/01/29/esp8266-neopixel-controller/ (in german).
|
||||
|
||||
Update 27.01.2018:
|
||||
Many people asked if it's possible to connect more than one strip (currently not) or at least "sync" multiple McLighting nodes. Although it may be possible to connect more then one WS2812 strip to the same data pin (works in many cases, you just have to try), syncing many McLighting instances would be a benefit. This could easily be achieved done by software like [NodeRed](https://nodered.org/). I added a example flow to demonstrate that [here](https://github.com/toblum/McLighting/blob/master/clients/node_red/websocket_proxy.json). Have a look at the short video [here](https://youtu.be/g3CHtG9c520).
|
||||
|
||||
Update 21.01.2018:
|
||||
User @szepnorbee contributed code for button control. Thank you! It's merged into the master branch now. There is a short manual for configuration [here](https://github.com/toblum/McLighting/wiki/Button-control).
|
||||
|
||||
Update 06.01.2018:
|
||||
After som etesting I merged the "feature/save_state" banch into master, so everybody should now be able to use this new functionality. Basically McLighting now saves the current mode to EEPROM and restores the setting on reboot. So you wont need to select your favorite mode again. If you don't want to use this, you can disable it in definitions.h.
|
||||
~~Some people noticed that there are currently problems compiling McLighting whe using ESP8266 core in version 2.4.0. This is due to a [problem](https://github.com/kitesurfer1404/WS2812FX/issues/58) with WS2812FX when using this version. For the moment you can stick to the 2.4.0 RC2 (also easily available via the boards manager).~~ (fixed now )
|
||||
Funny! McLighting was featured in the german radio show ["Netzbasteln"](https://www.deutschlandfunknova.de/beitrag/netzbasteln-wolkenlampe-mit-cloud-anschluss) on Deutschlandfunk Nova with a nice audio tutorial.
|
||||
|
||||
Update 16.12.2017:
|
||||
There was a breaking change in the WS2812FX library: Speeds have a new format (65535-0 instead of 0-255). I released a new version that converts the speeds settings. Please use the latest [WS2812FX library](https://github.com/kitesurfer1404/WS2812FX) (14.12.2017 or later) if use have an existing version installed.
|
||||
I got many messages from people who use McLighting for own projects. User Brian Lough built a lighting system for his wedding and made a nice instruction video for his build: https://goo.gl/NbfKi8
|
||||
|
||||
Update 30.09.2017:
|
||||
Thanks to [@moose4lord](https://github.com/moose4lord) Mclighting works with the newest version of WS1812FX and has a possibility to define autocycle patterns [Wiki](https://github.com/toblum/McLighting/wiki/Autocycling). Thank for contributing to McLighting everyone!
|
||||
I was also informed of a new project that is loosely based on McLighting: [Responsive_LED_Control](https://github.com/doctormord/Responsive_LED_Control) That looks very promising.
|
||||
|
||||
Update 07.08.2017:
|
||||
As requested by many of you, McLighting now also features MQTT support. Thanks at @LeonVos for his attempts on this. I implemented the same API as used in WebSockets now for MQTT. Please have a look here for details: https://github.com/toblum/McLighting/wiki/MQTT-API I will try to add a new instruction video soon.
|
||||
|
||||
Many of you also took McLighting and adapted the software according your needs. This is great. I found some videos on YouTube that show these projects. I collected them here: https://goo.gl/yG7M4h
|
||||
If you have done something similar with McLighting, please drop me a note. I'm always interested in what you've done with it.
|
||||
|
||||
Update 19.02.2017:
|
||||
Added OTA support as promised by @markbajaj. Minor other improvements.
|
||||
|
||||
Update 05.02.2017:
|
||||
After a long time I was able to work a bit on McLighting v2 and it's finally out now. The main difference, among minor improvements and library updates, is the usage of the great WS2812FX library for color animations. It brings a lot (almost 50!) of new animations.
|
||||
The API changed a little bit, because the speed can now be set as a value from 0 to 255, not the delay anymore. So the web inferface had to change accordingly. The new animation mode have to be set also by their number, instead of a dedicated url. The list of all animation modes can also be received by the API. All existing API endpoints are kept for downward compatibility. So you should be able to use the new version without big changes. The original version is kept as branch "mclighting_legacy". Documentation will be updated soon.
|
||||
|
||||
Update 04.01.2017:
|
||||
Now, there are two forks of McLighting (using the famous FastLED library). I did not notice it first, because I currently do not receive notification e-mails by Github (I have no idea why). Maybe you want to give them also a try, I will definitely do so as soon as I find time.
|
||||
https://github.com/russp81/LEDLAMP_FASTLEDs
|
||||
And this one was also forked: https://github.com/jake-b/Griswold-LED-Controller
|
||||
|
||||
Update 12.08.2016:
|
||||
There is now a [gitter.im](https://gitter.im/mclighting/Lobby?utm_source=share-link&utm_medium=link&utm_campaign=share-link) chat room for this project.
|
||||
|
||||
Update 11.06.2016:
|
||||
Today I presented the project at [Pi and More 9](https://piandmore.de/) and got some good feedback, even though my presentation was not perfect and time was too short to present everything I prepared. So I uploaded the [slides (german)](documentation/slides/Ein%20SmartLight%20im%20Selbstbau%20für%20unter%2015%20€_Pi%20and%20More%209.pdf) to this repository for your reference.
|
||||
@@ -1,143 +1,80 @@
|
||||
# McLighting v2 - The ESP8266 based multi-client lighting gadget
|
||||
|
||||
[](https://gitter.im/mclighting/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
[](https://gitter.im/mclighting/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [](https://travis-ci.com/toblum/McLighting) [](https://opensource.org/licenses/MIT) [](https://github.com/toblum/McLighting/blob/master/Arduino/McLighting/version.h)
|
||||
|
||||
> Mc Lighting (the multi-client lighting gadget) is a very cheap internet-controllable lighting solution based on the famous ESP8266 microcontroller and WS2811/2812 led strips. It features a self-hosted responsive web-interface, a REST-API and a websocket connector.
|
||||
McLighting (the multi-client lighting gadget) is a very cheap internet-controllable lighting solution based on the famous ESP8266 microcontroller and WS2811/2812 led strips. It features among other things a web-interface, a REST-API and a websocket connector.
|
||||
|
||||
> Because of it's open architecture and APIs it's easy to build new clients for different platforms (iOS, Android, Windows Universal Apps, Siri/Cortana integration, ...).
|
||||
Because of it's open architecture and APIs it's easy to build new clients for different platforms (iOS, Android, Windows Universal Apps, Siri/Cortana integration, ...).
|
||||
|
||||
[](https://youtu.be/rc6QVHKAXBs)
|
||||
|
||||
[](https://youtu.be/4JnGXZaPnrw)
|
||||
|
||||
___
|
||||
Update 13.05.2018:
|
||||
I've worked on a new web UI for the last weeks. It's now available as an early preview. There is a [video](https://youtu.be/lryDPMA2qpY) that shows the new features. [Try it out](https://github.com/toblum/McLightingUI) if you want and leave some feedback.
|
||||
|
||||
Update 07.04.2018:
|
||||
And even more changes to McLighting! Most of them were contributed by user @debsahu. Thank you!
|
||||
- Update arduino-esp8266 to latest, at least version 2.4.1
|
||||
- AMQTT is now the default MQTT library, it's a bit more lightweight and stable. You can still use PubSubClient if you want to.
|
||||
- You can use @debsahu great NeoAnimationFX library as a alternative to WS2812FX. It's based on the NeoPixelBus instead of Adafruits NeoPixel library. It can handle longer strips more efficient. If you want, give it a try. WS2812FX is still the default.
|
||||
- Some more changes regarding Homeassistant integration.
|
||||
Please see the [Wiki](https://github.com/toblum/McLighting/wiki/Software-installation) for details on the required libraries.
|
||||
If you have problems with the new version, let us know. You can get the last version [here](https://github.com/toblum/McLighting/tree/Before_AMQTT_NeoAnimationFX).
|
||||
|
||||
I'm also working on a alternative web interface for McLighting in the meanwhile, but it may take some more time.
|
||||
For the german users: McLighting was used in [Kliemannsland](https://youtu.be/3TUjszkS3bY?t=1211) (a funny web show) when they built a really big Neopixel installation.
|
||||
|
||||
Update 18.03.2018:
|
||||
The code for integration with homeassistant was merged into master. It's currently active by default. You can safely disable it in definitions.h when use do not want to use it, or want to use McLighting on a small ESP_01.
|
||||
There are some informations in the [Wiki](https://github.com/toblum/McLighting/wiki/Homeassistant-integration).
|
||||
|
||||
Update 17.02.2018:
|
||||
User @debsahu contributed code for integration with homeassistant. It's currently in a separate branch (https://github.com/toblum/McLighting/tree/feature/ha_integration). If you're using Homeassistant, please try it out and give feedback.
|
||||
User @FabLab-Luenen created a version of McLighting (https://github.com/FabLab-Luenen/McLighting) for 6812 and other RGBW strips. Give it a try, if you own such strips.
|
||||
A thank you goes to all contributors.
|
||||
|
||||
Update 12. / 15.02.2018:
|
||||
Added Home Assistant Support using MQTT Light. A better implementation would be using MQTT Light JSON.
|
||||
Replaced Home Assistant Support using MQTT Light to MQTT JSON Light.
|
||||
|
||||
Update 31.01.2018:
|
||||
User @codmpm did a very professional McLighting installation and even designed his own PCBs. He has a great writeup for his project at: https://allgeek.de/2018/01/29/esp8266-neopixel-controller/ (in german).
|
||||
|
||||
Update 27.01.2018:
|
||||
Many people asked if it's possible to connect more than one strip (currently not) or at least "sync" multiple McLighting nodes. Although it may be possible to connect more then one WS2812 strip to the same data pin (works in many cases, you just have to try), syncing many McLighting instances would be a benefit. This could easily be achieved done by software like [NodeRed](https://nodered.org/). I added a example flow to demonstrate that [here](https://github.com/toblum/McLighting/blob/master/clients/node_red/websocket_proxy.json). Have a look at the short video [here](https://youtu.be/g3CHtG9c520).
|
||||
|
||||
Update 21.01.2018:
|
||||
User @szepnorbee contributed code for button control. Thank you! It's merged into the master branch now. There is a short manual for configuration [here](https://github.com/toblum/McLighting/wiki/Button-control).
|
||||
|
||||
Update 06.01.2018:
|
||||
After som etesting I merged the "feature/save_state" banch into master, so everybody should now be able to use this new functionality. Basically McLighting now saves the current mode to EEPROM and restores the setting on reboot. So you wont need to select your favorite mode again. If you don't want to use this, you can disable it in definitions.h.
|
||||
~~Some people noticed that there are currently problems compiling McLighting whe using ESP8266 core in version 2.4.0. This is due to a [problem](https://github.com/kitesurfer1404/WS2812FX/issues/58) with WS2812FX when using this version. For the moment you can stick to the 2.4.0 RC2 (also easily available via the boards manager).~~ (fixed now )
|
||||
Funny! McLighting was featured in the german radio show ["Netzbasteln"](https://www.deutschlandfunknova.de/beitrag/netzbasteln-wolkenlampe-mit-cloud-anschluss) on Deutschlandfunk Nova with a nice audio tutorial.
|
||||
|
||||
Update 16.12.2017:
|
||||
There was a breaking change in the WS2812FX library: Speeds have a new format (65535-0 instead of 0-255). I released a new version that converts the speeds settings. Please use the latest [WS2812FX library](https://github.com/kitesurfer1404/WS2812FX) (14.12.2017 or later) if use have an existing version installed.
|
||||
I got many messages from people who use McLighting for own projects. User Brian Lough built a lighting system for his wedding and made a nice instruction video for his build: https://goo.gl/NbfKi8
|
||||
|
||||
Update 30.09.2017:
|
||||
Thanks to [@moose4lord](https://github.com/moose4lord) Mclighting works with the newest version of WS1812FX and has a possibility to define autocycle patterns [Wiki](https://github.com/toblum/McLighting/wiki/Autocycling). Thank for contributing to McLighting everyone!
|
||||
I was also informed of a new project that is loosely based on McLighting: [Responsive_LED_Control](https://github.com/doctormord/Responsive_LED_Control) That looks very promising.
|
||||
|
||||
Update 07.08.2017:
|
||||
As requested by many of you, McLighting now also features MQTT support. Thanks at @LeonVos for his attempts on this. I implemented the same API as used in WebSockets now for MQTT. Please have a look here for details: https://github.com/toblum/McLighting/wiki/MQTT-API I will try to add a new instruction video soon.
|
||||
|
||||
Many of you also took McLighting and adapted the software according your needs. This is great. I found some videos on YouTube that show these projects. I collected them here: https://goo.gl/yG7M4h
|
||||
If you have done something similar with McLighting, please drop me a note. I'm always interested in what you've done with it.
|
||||
|
||||
Update 19.02.2017:
|
||||
Added OTA support as promised by @markbajaj. Minor other improvements.
|
||||
|
||||
Update 05.02.2017:
|
||||
After a long time I was able to work a bit on McLighting v2 and it's finally out now. The main difference, among minor improvements and library updates, is the usage of the great WS2812FX library for color animations. It brings a lot (almost 50!) of new animations.
|
||||
The API changed a little bit, because the speed can now be set as a value from 0 to 255, not the delay anymore. So the web inferface had to change accordingly. The new animation mode have to be set also by their number, instead of a dedicated url. The list of all animation modes can also be received by the API. All existing API endpoints are kept for downward compatibility. So you should be able to use the new version without big changes. The original version is kept as branch "mclighting_legacy". Documentation will be updated soon.
|
||||
|
||||
Update 04.01.2017:
|
||||
Now, there are two forks of McLighting (using the famous FastLED library). I did not notice it first, because I currently do not receive notification e-mails by Github (I have no idea why). Maybe you want to give them also a try, I will definitely do so as soon as I find time.
|
||||
https://github.com/russp81/LEDLAMP_FASTLEDs
|
||||
And this one was also forked: https://github.com/jake-b/Griswold-LED-Controller
|
||||
|
||||
Update 12.08.2016:
|
||||
There is now a [gitter.im](https://gitter.im/mclighting/Lobby?utm_source=share-link&utm_medium=link&utm_campaign=share-link) chat room for this project.
|
||||
|
||||
Update 11.06.2016:
|
||||
Today I presented the project at [Pi and More 9](https://piandmore.de/) and got some good feedback, even though my presentation was not perfect and time was too short to present everything I prepared. So I uploaded the [slides (german)](documentation/slides/Ein%20SmartLight%20im%20Selbstbau%20für%20unter%2015%20€_Pi%20and%20More%209.pdf) to this repository for your reference.
|
||||
___
|
||||
|
||||
---
|
||||
|
||||
## The Hardware
|
||||
|
||||
The project ist based on the famous ESP8266 microcontroller and WD2811/WS2812 LED strips. There are many variations of the ESP chip out there, but I chose the NodeMCU dev board, because it's powered by micro USB and has a voltage converter included to power the ESP which uses 3.3V.
|
||||
A standalone ESP8266 or a Adafruit Huzzah should work too.
|
||||
The project is based on the ESP8266 and WD2811/WS2812 LED strips. There are many variations of the ESP chip out there, but for beginners we suggest a NodeMCU dev board, as these are as "plug 'n' play"as it can get.
|
||||
A standalone ESP8266 or an Adafruit Huzzah should work too.
|
||||
|
||||
The RGB LED strips are also available in many different flavours as strip or as standalone LEDs and can easily be chained.
|
||||
The RGB LED strips are also available in many different flavours (as strips or as standalone LEDs) and can easily be chained.
|
||||
|
||||
See wiki [Hardware](../../wiki/Hardware)
|
||||
For a detailed explanation see our wiki: [Hardware](../../wiki/Hardware)
|
||||
|
||||
|
||||
## Software installation
|
||||
See wiki [Software installation](../../wiki/Software-installation)
|
||||
|
||||
You can read how to get started on the software side of this project
|
||||
again in out wiki: [Software installation](../../wiki/Software-installation)
|
||||
|
||||
---
|
||||
|
||||
### Used Libraries
|
||||
|
||||
This project uses libraries and code by different authors:
|
||||
- WiFiManager by @tzapu (tested with version 0.12.0)
|
||||
https://github.com/tzapu/WiFiManager
|
||||
- WS2812FX by @kitesurfer1404 (tested with version downloaded 2017-02-05)
|
||||
https://github.com/kitesurfer1404/WS2812FX
|
||||
- WebSockets by @Links2004 (tested with version 2.0.6)
|
||||
https://github.com/Links2004/arduinoWebSockets
|
||||
- Adafruit NeoPixel by @adafruit (tested with 1.1.2)
|
||||
https://github.com/adafruit/Adafruit_NeoPixel
|
||||
- Optional: PubSubClient by @knolleary (tested with 2.6.0)
|
||||
Only when you have activated MQTT in definitions.h.
|
||||
https://github.com/knolleary/pubsubclient/
|
||||
|
||||
- [WiFiManager](https://github.com/tzapu/WiFiManager) by tzapu (tested with version 0.12.0)
|
||||
|
||||
- [WS2812FX](https://github.com/kitesurfer1404/WS2812FX) by kitesurfer1404 (tested with version downloaded 2017-02-05)
|
||||
|
||||
- [WebSockets](https://github.com/Links2004/arduinoWebSockets) by Links2004 (tested with version 2.0.6)
|
||||
|
||||
- [Adafruit NeoPixel](https://github.com/adafruit/Adafruit_NeoPixel) by adafruit (tested with 1.1.2)
|
||||
|
||||
- Optional: [PubSubClient](https://github.com/knolleary/pubsubclient/) by knolleary (tested with 2.6.0)
|
||||
_Only when you have activated MQTT in definitions.h._
|
||||
|
||||
The sketch also uses the following built-in library:
|
||||
- Ticker by @igrr
|
||||
- Ticker by [@igrr](https://github.com/igrr)
|
||||
|
||||
Parts of the code were taken or inspired by the following sources:
|
||||
- HSB3RGB conversion
|
||||
https://blog.adafruit.com/2012/03/14/constant-brightness-hsb-to-rgb-algorithm/
|
||||
- TV simulator logic inspired by @BulldogLowell
|
||||
https://github.com/BulldogLowell/PhoneyTV
|
||||
- SPIFFS Webserver by Hristo Gochkov
|
||||
https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WebServer/examples/FSBrowser
|
||||
|
||||
- [HSB3RGB conversion](https://blog.adafruit.com/2012/03/14/constant-brightness-hsb-to-rgb-algorithm/)
|
||||
|
||||
- [TV simulator](https://github.com/BulldogLowell/PhoneyTV) logic inspired by BulldogLowell
|
||||
|
||||
- [SPIFFS Webserver](https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WebServer/examples/FSBrowser) by Hristo Gochkov
|
||||
|
||||
Thank you to all the authors for distributing their software that way.
|
||||
I hope I didn't miss any sources and mentioned every author. In case I forgot someone please let me know and I will fix it.
|
||||
|
||||
|
||||
## Todos
|
||||
- [x] MQTT support
|
||||
- [ ] Support multiple strips and control them separately or together [Issue](https://github.com/toblum/McLighting/issues/118)
|
||||
- [x] Save favourite effects? [Issue](https://github.com/toblum/McLighting/issues/35)
|
||||
- [ ] Make number of pixels, MQTT and PIN configurable via front end [Issue](https://github.com/toblum/McLighting/issues/93) and [Issue](https://github.com/toblum/McLighting/issues/101)
|
||||
- [x] OTA update [Issue](https://github.com/toblum/McLighting/issues/93)
|
||||
- [ ] Make number of pixels, MQTT and PIN configurable via front end [Issue](https://github.com/toblum/McLighting/issues/93) and [Issue](https://github.com/toblum/McLighting/issues/93)
|
||||
- [ ] Bundle webpages instead of SPIFFS [Issue](https://github.com/toblum/McLighting/issues/93)
|
||||
- [ ] Remove old / wrong EEPROM settings completely (https://github.com/toblum/McLighting/issues/92)
|
||||
- [ ] Remove old / wrong EEPROM settings completely [Issue]
|
||||
- [ ] Customer profile to define segments of (in)active areas on the strip [Issue](https://github.com/toblum/McLighting/issues/37)
|
||||
- [ ] Additional clients
|
||||
- [ ] If no wifi, at least enable button mode.
|
||||
- [ ] Also enable McLighting in Wifi AP mode.
|
||||
- [ ] IR remote support [issue](https://github.com/toblum/McLightingUI/issues/3)
|
||||
- [ ] Multiple buttons/GPIO Inputs. [Issue](https://github.com/toblum/McLighting/issues/119)
|
||||
- [ ] Music visualizer / Bring back ArtNet [Issue](https://github.com/toblum/McLighting/issues/111)
|
||||
- [ ] Display version and parameters (Number of LEDs, definition settings, ..) in the web UI [Issue](https://github.com/toblum/McLighting/issues/150)
|
||||
- [x] MQTT support
|
||||
- [x] Save favourite effects? [Issue](https://github.com/toblum/McLighting/issues/35)(https://github.com/toblum/McLighting/issues/101)
|
||||
- [x] OTA update [Issue](https://github.com/toblum/McLighting/issues/92)
|
||||
- [x] Fix issue with websockets connection problems
|
||||
- [x] Switch to the [NeoPixelBus library](https://github.com/Makuna/NeoPixelBus/wiki)
|
||||
- [x] Use the led strip for status information in connection phase
|
||||
@@ -145,21 +82,13 @@ I hope I didn't miss any sources and mentioned every author. In case I forgot so
|
||||
- [x] Stability improvements
|
||||
- [x] RGBW mode [Issue](https://github.com/toblum/McLighting/issues/24)
|
||||
- [x] Add called command to response [Issue](https://github.com/toblum/McLighting/issues/19)
|
||||
- [ ] Customer profile to define segments of (in)active areas on the strip [Issue](https://github.com/toblum/McLighting/issues/37)
|
||||
- [x] Button control [Issue](https://github.com/toblum/McLighting/issues/36)
|
||||
- [x] Retain last state [Issue](https://github.com/toblum/McLighting/issues/47)
|
||||
- [ ] Additional clients
|
||||
- [ ] If no wifi, at least enable button mode.
|
||||
- [ ] Also enable McLighting in Wifi AP mode.
|
||||
- [x] Make a set of NodeRed nodes.
|
||||
- [ ] IR remote support [issue](https://github.com/toblum/McLightingUI/issues/3)
|
||||
- [ ] Multiple buttons/GPIO Inputs. [Issue](https://github.com/toblum/McLighting/issues/119)
|
||||
- [ ] Music visualizer / Bring back ArtNet [Issue](https://github.com/toblum/McLighting/issues/111)
|
||||
- [ ] Display version and parameters (Number of LEDs, definition settings, ..) in the web UI [Issue](https://github.com/toblum/McLighting/issues/150)
|
||||
|
||||
|
||||
## Licence
|
||||
[GNU LGPLv3](http://www.gnu.org/licenses/lgpl-3.0.txt)
|
||||
[MIT](https://choosealicense.com/licenses/mit/)
|
||||
|
||||
|
||||
## Disclaimer
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
light:
|
||||
- platform: mqtt_json
|
||||
- platform: mqtt
|
||||
schema: json
|
||||
name: "NeoPixel LEDs"
|
||||
state_topic: "home/McLighting01_ha/state/out"
|
||||
command_topic: "home/McLighting01_ha/state/in"
|
||||
@@ -63,6 +64,7 @@ light:
|
||||
- "Bicolor Chase"
|
||||
- "Tricolor Chase"
|
||||
- "ICU"
|
||||
- "E131"
|
||||
brightness: true
|
||||
color_temp: true
|
||||
rgb: true
|
||||
@@ -79,7 +81,7 @@ input_number:
|
||||
step: 5
|
||||
|
||||
automation:
|
||||
- id: 71938579813759813757
|
||||
- id: "71938579813759813757"
|
||||
alias: NeoPixel Animation Speed Send
|
||||
initial_state: true
|
||||
hide_entity: false
|
||||
@@ -93,7 +95,7 @@ automation:
|
||||
topic: home/McLighting01_ha/state/in
|
||||
service: mqtt.publish
|
||||
|
||||
- id: 93786598732698756967
|
||||
- id: "93786598732698756967"
|
||||
alias: NeoPixel Animation Speed Receive
|
||||
trigger:
|
||||
- platform: mqtt
|
||||
@@ -102,4 +104,4 @@ automation:
|
||||
- data_template:
|
||||
entity_id: input_number.neopixel_animation_speed
|
||||
value: '{{ trigger.payload_json.speed | int }}'
|
||||
service: input_number.set_value
|
||||
service: input_number.set_value
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
{
|
||||
"accessory": "HTTP-RGB",
|
||||
"name": "Wohnzimmerlampe",
|
||||
"service": "Light",
|
||||
|
||||
"switch": {
|
||||
"status": "http://<ESP_HOST>/get_switch",
|
||||
|
||||
+27
-57
@@ -10,14 +10,13 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<title>McLighting v2</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<nav class="blue light-blueXXX lighten-1XXX" role="navigation" id="mc-nav">
|
||||
<div class="nav-wrapper container">
|
||||
<a id="logo-container" href="#" class="brand-logo">McLighting v2</a>
|
||||
<a id="logo-container" href="#" class="brand-logo">Mc Lighting v2</a>
|
||||
|
||||
<ul class="right hide-on-med-and-down">
|
||||
<li><a href="#" class="mc-navlink" data-pane="pane1">Wheel</a></li>
|
||||
@@ -120,6 +119,18 @@
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col s12 m6 l6 btn_grid">
|
||||
<a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="off">OFF
|
||||
<i class="material-icons right">send</i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m6 l6 btn_grid">
|
||||
<a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="tv">TV
|
||||
<i class="material-icons right">send</i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div id="modes">
|
||||
<div class="input-field col s12">
|
||||
Loading animations...
|
||||
@@ -173,9 +184,9 @@ $(function(){
|
||||
$('#' + pane).removeClass('hide');
|
||||
$('.button-collapse').sideNav('hide');
|
||||
|
||||
//if (pane == "pane2") {
|
||||
// setMainColor();
|
||||
//}
|
||||
if (pane == "pane2") {
|
||||
setMainColor();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -185,54 +196,16 @@ $(function(){
|
||||
function init() {
|
||||
console.log("Connection websockets to:", ws_url);
|
||||
connection = new WebSocket(ws_url, ['arduino']);
|
||||
var mode = 0;
|
||||
var ws2812fx_mode = 0;
|
||||
$.getJSON("http://" + host + "/status", function(data) {
|
||||
console.log("status", data);
|
||||
mode = data.mode;
|
||||
ws2812fx_mode = data.ws2812fx_mode;
|
||||
$("#rng_delay").val(data.speed);
|
||||
$("#rng_brightness").val(data.brightness);
|
||||
$("#rng_red").val(data.color[0]);
|
||||
$("#rng_green").val(data.color[1]);
|
||||
$("#rng_blue").val(data.color[2]);
|
||||
var statusColor = "#" + componentToHex(data.color[0]) + componentToHex(data.color[1]) + componentToHex(data.color[2]);
|
||||
$('#status').css("backgroundColor", statusColor);
|
||||
$('#status_color').text(statusColor + "- R=" + data.color[0] + ", G=" + data.color[1] + ", B=" + data.color[2]);
|
||||
});
|
||||
|
||||
// Load modes async
|
||||
// List of all color modes
|
||||
// enum MODE { SET_MODE, HOLD, AUTO, OFF, TV, CUSTOM, SETCOLOR, SETSPEED, BRIGHTNESS, WIPE, RAINBOW, RAINBOWCYCLE, THEATERCHASE, TWINKLERANDOM, THEATERCHASERAINBOW};
|
||||
$.getJSON("http://" + host + "/get_modes", function(data) {
|
||||
console.log("modes", data);
|
||||
//console.log("modes", data);
|
||||
|
||||
var modes_html = "";
|
||||
modes_html += '<div class="col s12 m6 l6 btn_grid">';
|
||||
if (mode == "3") {
|
||||
modes_html += '<a class="btn waves-effect waves-light btn_mode_static red" name="action" data-mode="off">OFF';
|
||||
} else {
|
||||
modes_html += '<a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="off">OFF';
|
||||
}
|
||||
modes_html += '<i class="material-icons right">send</i>';
|
||||
modes_html += '</a>';
|
||||
modes_html += '</div>'
|
||||
modes_html += '<div class="col s12 m6 l6 btn_grid">';
|
||||
if (mode == "4") {
|
||||
modes_html += '<a class="btn waves-effect waves-light btn_mode_static red" name="action" data-mode="tv">TV';
|
||||
} else {
|
||||
modes_html += '<a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="tv">TV';
|
||||
}
|
||||
modes_html += '<i class="material-icons right">send</i>';
|
||||
modes_html += '</a>';
|
||||
modes_html += '</div>';
|
||||
data.forEach(function(current_mode){
|
||||
if (current_mode.mode !== undefined) {
|
||||
modes_html += '<div class="col s12 m6 l6 btn_grid">';
|
||||
if (mode == "1" && current_mode.mode == ws2812fx_mode) {
|
||||
modes_html += '<a class="btn waves-effect waves-light btn_mode red" name="action" data-mode="' + current_mode.mode + '">(' + current_mode.mode +') '+ current_mode.name;
|
||||
|
||||
} else {
|
||||
modes_html += '<a class="btn waves-effect waves-light btn_mode blue" name="action" data-mode="' + current_mode.mode + '">(' + current_mode.mode +') '+ current_mode.name;
|
||||
}
|
||||
modes_html += '<a class="btn waves-effect waves-light btn_mode blue" name="action" data-mode="' + current_mode.mode + '">(' + current_mode.mode +') '+ current_mode.name;
|
||||
modes_html += '<i class="material-icons right">send</i>';
|
||||
modes_html += '</a>';
|
||||
modes_html += '</div>';
|
||||
@@ -241,6 +214,7 @@ $(function(){
|
||||
|
||||
$('#modes').html(modes_html);
|
||||
});
|
||||
|
||||
// When the connection is open, send some data to the server
|
||||
connection.onopen = function () {
|
||||
//connection.send('Ping'); // Send the message 'Ping' to the server
|
||||
@@ -317,13 +291,10 @@ $(function(){
|
||||
function setMainColor() {
|
||||
var red = $("#rng_red").val();
|
||||
var green = $("#rng_green").val();
|
||||
var blue = $("#rng_blue").val();
|
||||
var blue = $("#rng_blue").val();
|
||||
|
||||
var hexColor = componentToHex(red) + componentToHex(green) + componentToHex(blue);
|
||||
var statusColor = "#" + componentToHex(red) + componentToHex(green) + componentToHex(blue);
|
||||
wsSetMainColor(hexColor);
|
||||
$('#status').css("backgroundColor", statusColor);
|
||||
$('#status_color').text(statusColor + "- R=" + red + ", G=" + green + ", B=" + blue);
|
||||
var mainColorHex = componentToHex(red) + componentToHex(green) + componentToHex(blue);
|
||||
wsSetMainColor(mainColorHex);
|
||||
}
|
||||
|
||||
|
||||
@@ -441,10 +412,9 @@ $(function(){
|
||||
|
||||
//display the touch/click position and color info
|
||||
function updateStatus(pos, color) {
|
||||
//var hexColor = rgbToHex(color);
|
||||
//wsSetAll(hexColor);
|
||||
var hexColor = componentToHex(color[0]) + componentToHex(color[1]) + componentToHex(color[2]);
|
||||
wsSetMainColor(hexColor);
|
||||
var hexColor = rgbToHex(color);
|
||||
wsSetAll(hexColor);
|
||||
|
||||
hexColor = "#" + hexColor;
|
||||
|
||||
$('#status').css("backgroundColor", hexColor);
|
||||
|
||||
@@ -10,14 +10,13 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<title>McLighting v2</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<nav class="blue light-blueXXX lighten-1XXX" role="navigation" id="mc-nav">
|
||||
<div class="nav-wrapper container">
|
||||
<a id="logo-container" href="#" class="brand-logo">McLighting v2</a>
|
||||
<a id="logo-container" href="#" class="brand-logo">Mc Lighting v2</a>
|
||||
|
||||
<ul class="right hide-on-med-and-down">
|
||||
<li><a href="#" class="mc-navlink" data-pane="pane1">Wheel</a></li>
|
||||
@@ -120,6 +119,18 @@
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col s12 m6 l6 btn_grid">
|
||||
<a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="off">OFF
|
||||
<i class="material-icons right">send</i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m6 l6 btn_grid">
|
||||
<a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="tv">TV
|
||||
<i class="material-icons right">send</i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div id="modes">
|
||||
<div class="input-field col s12">
|
||||
Loading animations...
|
||||
@@ -148,5 +159,4 @@
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
|
||||
<script type="text/javascript">@@include('js/script.js')</script>
|
||||
</body>
|
||||
\ No newline at end of file
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -25,9 +25,9 @@ $(function(){
|
||||
$('#' + pane).removeClass('hide');
|
||||
$('.button-collapse').sideNav('hide');
|
||||
|
||||
//if (pane == "pane2") {
|
||||
// setMainColor();
|
||||
//}
|
||||
if (pane == "pane2") {
|
||||
setMainColor();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,54 +37,16 @@ $(function(){
|
||||
function init() {
|
||||
console.log("Connection websockets to:", ws_url);
|
||||
connection = new WebSocket(ws_url, ['arduino']);
|
||||
var mode = 0;
|
||||
var ws2812fx_mode = 0;
|
||||
$.getJSON("http://" + host + "/status", function(data) {
|
||||
console.log("status", data);
|
||||
mode = data.mode;
|
||||
ws2812fx_mode = data.ws2812fx_mode;
|
||||
$("#rng_delay").val(data.speed);
|
||||
$("#rng_brightness").val(data.brightness);
|
||||
$("#rng_red").val(data.color[0]);
|
||||
$("#rng_green").val(data.color[1]);
|
||||
$("#rng_blue").val(data.color[2]);
|
||||
var statusColor = "#" + componentToHex(data.color[0]) + componentToHex(data.color[1]) + componentToHex(data.color[2]);
|
||||
$('#status').css("backgroundColor", statusColor);
|
||||
$('#status_color').text(statusColor + "- R=" + data.color[0] + ", G=" + data.color[1] + ", B=" + data.color[2]);
|
||||
});
|
||||
|
||||
// Load modes async
|
||||
// List of all color modes
|
||||
// enum MODE { SET_MODE, HOLD, AUTO, OFF, TV, CUSTOM, SETCOLOR, SETSPEED, BRIGHTNESS, WIPE, RAINBOW, RAINBOWCYCLE, THEATERCHASE, TWINKLERANDOM, THEATERCHASERAINBOW};
|
||||
$.getJSON("http://" + host + "/get_modes", function(data) {
|
||||
console.log("modes", data);
|
||||
//console.log("modes", data);
|
||||
|
||||
var modes_html = "";
|
||||
modes_html += '<div class="col s12 m6 l6 btn_grid">';
|
||||
if (mode == "3") {
|
||||
modes_html += '<a class="btn waves-effect waves-light btn_mode_static red" name="action" data-mode="off">OFF';
|
||||
} else {
|
||||
modes_html += '<a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="off">OFF';
|
||||
}
|
||||
modes_html += '<i class="material-icons right">send</i>';
|
||||
modes_html += '</a>';
|
||||
modes_html += '</div>'
|
||||
modes_html += '<div class="col s12 m6 l6 btn_grid">';
|
||||
if (mode == "4") {
|
||||
modes_html += '<a class="btn waves-effect waves-light btn_mode_static red" name="action" data-mode="tv">TV';
|
||||
} else {
|
||||
modes_html += '<a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="tv">TV';
|
||||
}
|
||||
modes_html += '<i class="material-icons right">send</i>';
|
||||
modes_html += '</a>';
|
||||
modes_html += '</div>';
|
||||
data.forEach(function(current_mode){
|
||||
if (current_mode.mode !== undefined) {
|
||||
modes_html += '<div class="col s12 m6 l6 btn_grid">';
|
||||
if (mode == "1" && current_mode.mode == ws2812fx_mode) {
|
||||
modes_html += '<a class="btn waves-effect waves-light btn_mode red" name="action" data-mode="' + current_mode.mode + '">(' + current_mode.mode +') '+ current_mode.name;
|
||||
|
||||
} else {
|
||||
modes_html += '<a class="btn waves-effect waves-light btn_mode blue" name="action" data-mode="' + current_mode.mode + '">(' + current_mode.mode +') '+ current_mode.name;
|
||||
}
|
||||
modes_html += '<a class="btn waves-effect waves-light btn_mode blue" name="action" data-mode="' + current_mode.mode + '">(' + current_mode.mode +') '+ current_mode.name;
|
||||
modes_html += '<i class="material-icons right">send</i>';
|
||||
modes_html += '</a>';
|
||||
modes_html += '</div>';
|
||||
@@ -93,6 +55,7 @@ $(function(){
|
||||
|
||||
$('#modes').html(modes_html);
|
||||
});
|
||||
|
||||
// When the connection is open, send some data to the server
|
||||
connection.onopen = function () {
|
||||
//connection.send('Ping'); // Send the message 'Ping' to the server
|
||||
@@ -169,13 +132,10 @@ $(function(){
|
||||
function setMainColor() {
|
||||
var red = $("#rng_red").val();
|
||||
var green = $("#rng_green").val();
|
||||
var blue = $("#rng_blue").val();
|
||||
var blue = $("#rng_blue").val();
|
||||
|
||||
var hexColor = componentToHex(red) + componentToHex(green) + componentToHex(blue);
|
||||
var statusColor = "#" + componentToHex(red) + componentToHex(green) + componentToHex(blue);
|
||||
wsSetMainColor(hexColor);
|
||||
$('#status').css("backgroundColor", statusColor);
|
||||
$('#status_color').text(statusColor + "- R=" + red + ", G=" + green + ", B=" + blue);
|
||||
var mainColorHex = componentToHex(red) + componentToHex(green) + componentToHex(blue);
|
||||
wsSetMainColor(mainColorHex);
|
||||
}
|
||||
|
||||
|
||||
@@ -293,10 +253,9 @@ $(function(){
|
||||
|
||||
//display the touch/click position and color info
|
||||
function updateStatus(pos, color) {
|
||||
//var hexColor = rgbToHex(color);
|
||||
//wsSetAll(hexColor);
|
||||
var hexColor = componentToHex(color[0]) + componentToHex(color[1]) + componentToHex(color[2]);
|
||||
wsSetMainColor(hexColor);
|
||||
var hexColor = rgbToHex(color);
|
||||
wsSetAll(hexColor);
|
||||
|
||||
hexColor = "#" + hexColor;
|
||||
|
||||
$('#status').css("backgroundColor", hexColor);
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[platformio]
|
||||
src_dir = ./Arduino/McLighting/
|
||||
data_dir = ./Arduino/McLighting/data/
|
||||
env_default = nodemcuv2
|
||||
description = The ESP8266 based multi-client lighting gadget
|
||||
|
||||
[common]
|
||||
framework = arduino
|
||||
platform = espressif8266@1.8.0
|
||||
; platform = https://github.com/platformio/platform-espressif8266.git
|
||||
; platform = https://github.com/platformio/platform-espressif8266.git#feature/stage
|
||||
; platform = https://github.com/platformio/platform-espressif8266.git#develop
|
||||
build_flags =
|
||||
-DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH
|
||||
-DMQTT_MAX_PACKET_SIZE=2048 ; PubSubClient Specific flags
|
||||
-w ; supress all warnings
|
||||
monitor_speed = 115200
|
||||
board_build.flash_mode = dout
|
||||
upload_speed = 115200
|
||||
upload_resetmethod = nodemcu
|
||||
lib_deps =
|
||||
WiFiManager@0.14
|
||||
AsyncMqttClient
|
||||
https://github.com/bblanchon/ArduinoJson.git#v6.7.0-beta
|
||||
WS2812FX
|
||||
NeoPixelBus@2.4.1
|
||||
WebSockets
|
||||
ESPAsyncE131
|
||||
ESPAsyncUDP
|
||||
Brzo_I2C
|
||||
|
||||
[env:esp01_1m]
|
||||
board = esp01_1m
|
||||
framework = ${common.framework}
|
||||
platform = ${common.platform}
|
||||
build_flags = ${common.build_flags} -D D1=2
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
upload_speed = ${common.upload_speed}
|
||||
upload_resetmethod = ${common.upload_resetmethod}
|
||||
board_build.flash_mode = dout
|
||||
lib_deps = ${common.lib_deps}
|
||||
|
||||
[env:nodemcuv2]
|
||||
board = nodemcuv2
|
||||
framework = ${common.framework}
|
||||
platform = ${common.platform}
|
||||
build_flags = ${common.build_flags}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
upload_speed = ${common.upload_speed}
|
||||
upload_resetmethod = ${common.upload_resetmethod}
|
||||
lib_deps = ${common.lib_deps}
|
||||
Reference in New Issue
Block a user