diff --git a/README.md b/README.md index d381b755..6d4b72bf 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ The app is installed via the Arduino IDE which can be [downloaded here](https:// The app depends on the following libraries. They must either be downloaded from GitHub and placed in the Arduino 'libraries' folder, or installed as [described here](https://www.arduino.cc/en/Guide/Libraries) by using the Arduino library manager. * [FastLED](https://github.com/FastLED/FastLED) -* [IRremoteESP8266](https://github.com/sebastienwarin/IRremoteESP8266) +* [IRremoteESP8266](https://github.com/crankyoldgit/IRremoteESP8266) * [Arduino WebSockets](https://github.com/Links2004/arduinoWebSockets) * [Arduino JSON](https://arduinojson.org) * [lolrol LittleFS](https://github.com/lorol/LITTLEFS) -- (integrated into ESP32 core v2, which is not used here yet) diff --git a/esp8266-fastled-webserver/GradientPalettes.cpp b/esp8266-fastled-webserver/GradientPalettes.cpp index 219c9424..4b037904 100644 --- a/esp8266-fastled-webserver/GradientPalettes.cpp +++ b/esp8266-fastled-webserver/GradientPalettes.cpp @@ -468,10 +468,22 @@ DEFINE_GRADIENT_PALETTE( Blue_Cyan_Yellow_gp ) { 255, 255,255, 0}; +// Two copies of "Vapour" exist ... one explicitly as a "Gradient Palette", +// and one +DEFINE_GRADIENT_PALETTE( Vapour_gp ) { + 0, 111, 234, 230, + 64, 246, 163, 239, + 128, 80, 216, 236, + 192, 221, 109, 251, + 255, 238, 205, 105 +}; + + // Single array of defined cpt-city color palettes. // This will let us programmatically choose one based on // a number, rather than having to activate each explicitly // by name every time. +// // Since it is const, this array could also be moved // into PROGMEM to save SRAM, but for simplicity of illustration // we'll keep it in a regular SRAM array. @@ -511,9 +523,12 @@ const TProgmemRGBGradientPalettePtr gGradientPalettes[] = { BlacK_Blue_Magenta_White_gp, BlacK_Magenta_Red_gp, BlacK_Red_Magenta_Yellow_gp, - Blue_Cyan_Yellow_gp }; + Blue_Cyan_Yellow_gp, + Vapour_gp, +}; // Count of how many cpt-city gradients are defined: const uint8_t gGradientPaletteCount = ARRAY_SIZE2(gGradientPalettes); + diff --git a/esp8266-fastled-webserver/Twinkles.cpp b/esp8266-fastled-webserver/Twinkles.cpp index 71cb9f21..1d06e2a5 100644 --- a/esp8266-fastled-webserver/Twinkles.cpp +++ b/esp8266-fastled-webserver/Twinkles.cpp @@ -78,7 +78,7 @@ void colortwinkles() // Make each pixel brighter or darker, depending on // its 'direction' flag. brightenOrDarkenEachPixel( FADE_IN_SPEED, FADE_OUT_SPEED); - + // Now consider adding a new random twinkle if ( random8() < DENSITY ) { int pos = random16(NUM_PIXELS); @@ -90,6 +90,12 @@ void colortwinkles() } } +void currentPaletteTwinkles() +{ + gCurrentPalette = palettes[currentPaletteIndex]; + colortwinkles(); +} + void cloudTwinkles() { gCurrentPalette = CloudColors_p; // Blues and whites! @@ -117,4 +123,3 @@ void incandescentTwinkles() gCurrentPalette = CRGBPalette16( l, l, l, l, l, l, l, l, l, l, l, l, l, l, l, l ); colortwinkles(); } - diff --git a/esp8266-fastled-webserver/Websockets.cpp b/esp8266-fastled-webserver/Websockets.cpp new file mode 100644 index 00000000..902753b4 --- /dev/null +++ b/esp8266-fastled-webserver/Websockets.cpp @@ -0,0 +1,83 @@ +/* + ESP8266 FastLED WebServer: https://github.com/jasoncoon/esp8266-fastled-webserver + Copyright (C) Jason Coon + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#if ENABLE_WEBSOCKETS + +#include "common.h" + +// #include +#include + + +WebSocketsServer webSocketsServer = WebSocketsServer(81); + +void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { + switch (type) { + case WStype_DISCONNECTED: + Serial.printf("[%u] Disconnected!\n", num); + break; + + case WStype_CONNECTED: + IPAddress ip = webSocketsServer.remoteIP(num); + Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); + + //send message to client + webSocketsServer.sendTXT(num, "Connected"); + break; + + case WStype_TEXT: + Serial.printf("[%u] get Text: %s\n", num, payload); + + //send message to client + webSocketsServer.sendTXT(num, payload); + + //send data to all connected clients + webSocketsServer.broadcastTXT(payload); + + break; + + case WStype_BIN: + Serial.printf("[%u] get binary length: %u\n", num, length); + hexdump(payload, length); + + //send message to client + webSocketsServer.sendBIN(num, payload, length); + break; + } +} + +void InitializeWebSocketServer(void) { + webSocketsServer.begin(); + webSocketsServer.onEvent(webSocketEvent); + Serial.println("Web socket server started"); +} +void handleWebSocketLoop(void) { + webSocketsServer.loop(); +} +void broadcastInt(String name, uint8_t value) { + String json = "{\"name\":\"" + name + "\",\"value\":" + String(value) + "}"; + webSocketsServer.broadcastTXT(json); +} +void broadcastString(String name, String value) +{ + String json = "{\"name\":\"" + name + "\",\"value\":\"" + String(value) + "\"}"; + webSocketsServer.broadcastTXT(json); +} + + +#endif // ENABLE_WEBSOCKETS diff --git a/esp8266-fastled-webserver/commands.cpp b/esp8266-fastled-webserver/commands.cpp index ea054190..5576790f 100644 --- a/esp8266-fastled-webserver/commands.cpp +++ b/esp8266-fastled-webserver/commands.cpp @@ -18,9 +18,13 @@ #include "common.h" -#if defined(ENABLE_IR) +#if ENABLE_IR -IRrecv irReceiver(RECV_PIN); +#include +#include +#include + +IRrecv irReceiver(IR_RECV_PIN); enum class InputCommand { None, @@ -193,8 +197,9 @@ unsigned long decodeIRCode() { if (irReceiver.decode(&results)) { delay(20); - if (results.value != 0) - Serial.println(results.value); + if (results.value != 0) { + //Serial.println(results.value); + } // Prepare to receive the next IR code irReceiver.resume(); @@ -478,209 +483,219 @@ InputCommand readCommand(unsigned int holdDelay) { void handleIrInput() { - InputCommand command = readCommand(); - - if (command != InputCommand::None) { - Serial.print("command: "); - Serial.println((int) command); - } - - switch (command) { - case InputCommand::Up: { - adjustPattern(true); - break; - } - case InputCommand::Down: { - adjustPattern(false); - break; - } - case InputCommand::Power: { - setPower(power == 0 ? 1 : 0); - break; - } - case InputCommand::BrightnessUp: { - adjustBrightness(true); - break; - } - case InputCommand::BrightnessDown: { - adjustBrightness(false); - break; - } - case InputCommand::PlayMode: { // toggle pause/play - setAutoplay(!autoplay); - break; - } - - // pattern buttons - - case InputCommand::Pattern1: { - setPattern(0); - break; - } - case InputCommand::Pattern2: { - setPattern(1); - break; - } - case InputCommand::Pattern3: { - setPattern(2); - break; - } - case InputCommand::Pattern4: { - setPattern(3); - break; - } - case InputCommand::Pattern5: { - setPattern(4); - break; - } - case InputCommand::Pattern6: { - setPattern(5); - break; - } - case InputCommand::Pattern7: { - setPattern(6); - break; - } - case InputCommand::Pattern8: { - setPattern(7); - break; - } - case InputCommand::Pattern9: { - setPattern(8); - break; - } - case InputCommand::Pattern10: { - setPattern(9); - break; - } - case InputCommand::Pattern11: { - setPattern(10); - break; - } - case InputCommand::Pattern12: { - setPattern(11); - break; - } - - // custom color adjustment buttons - - case InputCommand::RedUp: { - solidColor.red += 8; - setSolidColor(solidColor); - break; - } - case InputCommand::RedDown: { - solidColor.red -= 8; - setSolidColor(solidColor); - break; - } - case InputCommand::GreenUp: { - solidColor.green += 8; - setSolidColor(solidColor); - break; - } - case InputCommand::GreenDown: { - solidColor.green -= 8; - setSolidColor(solidColor); - break; - } - case InputCommand::BlueUp: { - solidColor.blue += 8; - setSolidColor(solidColor); - break; - } - case InputCommand::BlueDown: { - solidColor.blue -= 8; - setSolidColor(solidColor); - break; - } - - // color buttons - - case InputCommand::Red: { - setSolidColor(CRGB::Red); - break; - } - case InputCommand::RedOrange: { - setSolidColor(CRGB::OrangeRed); - break; - } - case InputCommand::Orange: { - setSolidColor(CRGB::Orange); - break; - } - case InputCommand::YellowOrange: { - setSolidColor(CRGB::Goldenrod); - break; - } - case InputCommand::Yellow: { - setSolidColor(CRGB::Yellow); - break; - } - - case InputCommand::Green: { - setSolidColor(CRGB::Green); - break; - } - case InputCommand::Lime: { - setSolidColor(CRGB::Lime); - break; - } - case InputCommand::Aqua: { - setSolidColor(CRGB::Aqua); - break; - } - case InputCommand::Teal: { - setSolidColor(CRGB::Teal); - break; - } - case InputCommand::Navy: { - setSolidColor(CRGB::Navy); - break; - } - - case InputCommand::Blue: { - setSolidColor(CRGB::Blue); - break; - } - case InputCommand::RoyalBlue: { - setSolidColor(CRGB::RoyalBlue); - break; - } - case InputCommand::Purple: { - setSolidColor(CRGB::Purple); - break; - } - case InputCommand::Indigo: { - setSolidColor(CRGB::Indigo); - break; - } - case InputCommand::Magenta: { - setSolidColor(CRGB::Magenta); - break; - } - - case InputCommand::White: { - setSolidColor(CRGB::White); - break; - } - case InputCommand::Pink: { - setSolidColor(CRGB::Pink); - break; - } - case InputCommand::LightPink: { - setSolidColor(CRGB::LightPink); - break; - } - case InputCommand::BabyBlue: { - setSolidColor(CRGB::CornflowerBlue); - break; - } - case InputCommand::LightBlue: { - setSolidColor(CRGB::LightBlue); - break; - } - } + InputCommand command = readCommand(); + + if (command != InputCommand::None) { + Serial.print("command: "); + Serial.println((int) command); + } + + switch (command) { + case InputCommand::None: { + // does nothing, but must be handled due to use of scoped enumeration + break; + } + case InputCommand::Up: { + adjustPattern(true); + break; + } + case InputCommand::Down: { + adjustPattern(false); + break; + } + case InputCommand::Power: { + setPower(power == 0 ? 1 : 0); + break; + } + case InputCommand::BrightnessUp: { + adjustBrightness(true); + break; + } + case InputCommand::BrightnessDown: { + adjustBrightness(false); + break; + } + case InputCommand::PlayMode: { // toggle pause/play + setAutoplay(!autoplay); + break; + } + + // pattern buttons + + case InputCommand::Pattern1: { + setPattern(0); + break; + } + case InputCommand::Pattern2: { + setPattern(1); + break; + } + case InputCommand::Pattern3: { + setPattern(2); + break; + } + case InputCommand::Pattern4: { + setPattern(3); + break; + } + case InputCommand::Pattern5: { + setPattern(4); + break; + } + case InputCommand::Pattern6: { + setPattern(5); + break; + } + case InputCommand::Pattern7: { + setPattern(6); + break; + } + case InputCommand::Pattern8: { + setPattern(7); + break; + } + case InputCommand::Pattern9: { + setPattern(8); + break; + } + case InputCommand::Pattern10: { + setPattern(9); + break; + } + case InputCommand::Pattern11: { + setPattern(10); + break; + } + case InputCommand::Pattern12: { + setPattern(11); + break; + } + + // custom color adjustment buttons + + case InputCommand::RedUp: { + solidColor.red += 8; + setSolidColor(solidColor); + break; + } + case InputCommand::RedDown: { + solidColor.red -= 8; + setSolidColor(solidColor); + break; + } + case InputCommand::GreenUp: { + solidColor.green += 8; + setSolidColor(solidColor); + break; + } + case InputCommand::GreenDown: { + solidColor.green -= 8; + setSolidColor(solidColor); + break; + } + case InputCommand::BlueUp: { + solidColor.blue += 8; + setSolidColor(solidColor); + break; + } + case InputCommand::BlueDown: { + solidColor.blue -= 8; + setSolidColor(solidColor); + break; + } + + // color buttons + + case InputCommand::Red: { + setSolidColor(CRGB::Red); + break; + } + case InputCommand::RedOrange: { + setSolidColor(CRGB::OrangeRed); + break; + } + case InputCommand::Orange: { + setSolidColor(CRGB::Orange); + break; + } + case InputCommand::YellowOrange: { + setSolidColor(CRGB::Goldenrod); + break; + } + case InputCommand::Yellow: { + setSolidColor(CRGB::Yellow); + break; + } + + case InputCommand::Green: { + setSolidColor(CRGB::Green); + break; + } + case InputCommand::Lime: { + setSolidColor(CRGB::Lime); + break; + } + case InputCommand::Aqua: { + setSolidColor(CRGB::Aqua); + break; + } + case InputCommand::Teal: { + setSolidColor(CRGB::Teal); + break; + } + case InputCommand::Navy: { + setSolidColor(CRGB::Navy); + break; + } + + case InputCommand::Blue: { + setSolidColor(CRGB::Blue); + break; + } + case InputCommand::RoyalBlue: { + setSolidColor(CRGB::RoyalBlue); + break; + } + case InputCommand::Purple: { + setSolidColor(CRGB::Purple); + break; + } + case InputCommand::Indigo: { + setSolidColor(CRGB::Indigo); + break; + } + case InputCommand::Magenta: { + setSolidColor(CRGB::Magenta); + break; + } + + case InputCommand::White: { + setSolidColor(CRGB::White); + break; + } + case InputCommand::Pink: { + setSolidColor(CRGB::Pink); + break; + } + case InputCommand::LightPink: { + setSolidColor(CRGB::LightPink); + break; + } + case InputCommand::BabyBlue: { + setSolidColor(CRGB::CornflowerBlue); + break; + } + case InputCommand::LightBlue: { + setSolidColor(CRGB::LightBlue); + break; + } + } } + +void InitializeIR(void) { + irReceiver.enableIRIn(); // Start the receiver +} + + #endif diff --git a/esp8266-fastled-webserver/common.h b/esp8266-fastled-webserver/common.h index 253f8371..d512382a 100644 --- a/esp8266-fastled-webserver/common.h +++ b/esp8266-fastled-webserver/common.h @@ -46,11 +46,9 @@ #include #include #include - //#include #include #include // https://github.com/tzapu/WiFiManager/tree/development - #include "./include/simplehacks/static_eval.h" #include "./include/simplehacks/constexpr_strlen.h" #include "./include/simplehacks/array_size2.h" @@ -116,9 +114,6 @@ constexpr int LedCount() { } void writeAndCommitSettings(); -void broadcastInt(String name, uint8_t value); -void broadcastString(String name, String value); - #if defined(ESP32) || defined(ESP8266) // Optional: (LGPL) https://github.com/sinricpro/ESPTrueRandom.git#ed198f459da6d7af65dd13317a4fdc97b23991b4 @@ -229,13 +224,39 @@ extern CRGB leds[NUM_PIXELS]; #include "include/Fields.hpp" #include "include/FSBrowser.hpp" + // IR (commands.cpp) -#if defined(ENABLE_IR) - #include - extern IRrecv irReceiver; +#if ENABLE_IR + void InitializeIR(void); void handleIrInput(); #else inline void handleIrInput() {} +#endif // ENABLE_IR + +// TODO: move these functions out of main .INO file +// they are currently used by IR & main .INO file +#if ENABLE_IR + void setPower(uint8_t value); + void setAutoplay(uint8_t value); + //void setAutoplayDuration(uint8_t value); + void setSolidColor(CRGB color); + //void setSolidColor(uint8_t r, uint8_t g, uint8_t b); + void adjustPattern(bool up); + void setPattern(uint8_t value); + //void setPatternName(String name); + void adjustBrightness(bool up); +#endif // ENABLE_IR + + +#if ENABLE_WEBSOCKETS + void InitializeWebSocketServer(void); + void handleWebSocketLoop(void); + void broadcastInt(String name, uint8_t value); + void broadcastString(String name, String value); +#else + // these are put here for convenience + inline void broadcastInt(String, uint8_t) {}; + inline void broadcastString(String, String) {}; #endif // ping.cpp @@ -243,6 +264,7 @@ void checkPingTimer(); // effects // twinkles.cpp +void currentPaletteTwinkles(); void cloudTwinkles(); void rainbowTwinkles(); void snowTwinkles(); diff --git a/esp8266-fastled-webserver/config.h b/esp8266-fastled-webserver/config.h index 4408496e..958570fe 100644 --- a/esp8266-fastled-webserver/config.h +++ b/esp8266-fastled-webserver/config.h @@ -130,7 +130,16 @@ #if !defined(DEFAULT_COLOR_CORRECTION) #error "DEFAULT_COLOR_CORRECTION must be defined by product" #endif - #if defined(ENABLE_IR) && !defined(IR_RECV_PIN) + #if !defined(ENABLE_IR) + #define ENABLE_IR 0 + #endif + #if ((ENABLE_IR != 0) && (ENABLE_IR != 1)) + #error "ENABLE_IR must be undefined (defaults to 0), 0, or 1" + #endif + #if ENABLE_IR + #warning "ENABLE_IR is still in development, and is NOT supported" + #endif + #if ENABLE_IR && !defined(IR_RECV_PIN) #error "IR_RECV_PIN must be defined by product when ENABLE_IR is defined" #endif #if !defined(NAME_PREFIX) @@ -170,6 +179,23 @@ #if (NTP_UPDATE_THROTTLE_MILLLISECONDS < (15UL * 1000UL)) #error "NTP_UPDATE_THROTTLE_MILLLISECONDS less than 15 seconds ... may exceed rate limits" #endif + #if !defined(ENABLE_ARDUINO_OTA) + #define ENABLE_ARDUINO_OTA 0 + #endif + #if ((ENABLE_ARDUINO_OTA != 0) && (ENABLE_ARDUINO_OTA != 1)) + #error "ENABLE_ARDUINO_OTA must be undefined (defaults to 0), 0, or 1" + #endif + #if !defined(ENABLE_WEBSOCKETS) + #define ENABLE_WEBSOCKETS 0 + #endif + #if ((ENABLE_WEBSOCKETS != 0) && (ENABLE_WEBSOCKETS != 1)) + #error "ENABLE_WEBSOCKETS must be undefined (defaults to 0), 0, or 1" + #endif + #if ENABLE_WEBSOCKETS + #warning "ENABLE_WEBSOCKETS is still in development, and is NOT supported" + #endif + + #endif diff --git a/esp8266-fastled-webserver/esp8266-fastled-webserver.ino b/esp8266-fastled-webserver/esp8266-fastled-webserver.ino index 32d453dd..f0d633b1 100644 --- a/esp8266-fastled-webserver/esp8266-fastled-webserver.ino +++ b/esp8266-fastled-webserver/esp8266-fastled-webserver.ino @@ -20,7 +20,7 @@ WiFiManager wifiManager; ESP8266WebServer webServer(80); -//WebSocketsServer webSocketsServer = WebSocketsServer(81); + ESP8266HTTPUpdateServer httpUpdateServer; int utcOffsetInSeconds = -6 * 60 * 60; @@ -193,6 +193,7 @@ const PatternAndName patterns[] = { #endif // twinkle patterns + { currentPaletteTwinkles, "Palette Twinkles" }, { rainbowTwinkles, "Rainbow Twinkles" }, { snowTwinkles, "Snow Twinkles" }, { cloudTwinkles, "Cloud Twinkles" }, @@ -214,6 +215,9 @@ const PatternAndName patterns[] = { { cloud2Twinkles, "Cloud 2 Twinkles" }, { oceanTwinkles, "Ocean Twinkles" }, + { coolerpalettebow, "PaletteBow" }, + { palettebowglitter, "PaletteBow With Glitter" }, + { palettebow, "Solid PaletteBow" }, { rainbow, "Rainbow" }, { rainbowWithGlitter, "Rainbow With Glitter" }, { rainbowSolid, "Solid Rainbow" }, @@ -223,6 +227,8 @@ const PatternAndName patterns[] = { { juggle, "Juggle" }, { fire, "Fire" }, { water, "Water" }, + { firepal, "PaletteFire" }, + { waterpal, "PaletteWater" }, { strandTest, "Strand Test" }, #if (PARALLEL_OUTPUT_CHANNELS > 1) @@ -235,28 +241,32 @@ const PatternAndName patterns[] = { const uint8_t patternCount = ARRAY_SIZE2(patterns); const CRGBPalette16 palettes[] = { - RainbowColors_p, - RainbowStripeColors_p, - CloudColors_p, - LavaColors_p, - OceanColors_p, - ForestColors_p, - PartyColors_p, - HeatColors_p + RainbowColors_p, + RainbowStripeColors_p, + CloudColors_p, + LavaColors_p, + OceanColors_p, + + ForestColors_p, + PartyColors_p, + HeatColors_p, }; - const uint8_t paletteCount = ARRAY_SIZE2(palettes); -const String paletteNames[paletteCount] = { - "Rainbow", - "Rainbow Stripe", - "Cloud", - "Lava", - "Ocean", - "Forest", - "Party", - "Heat", +const String paletteNames[] = { + "Rainbow", + "Rainbow Stripe", + "Cloud", + "Lava", + "Ocean", + + "Forest", + "Party", + "Heat", }; +const uint8_t paletteNameCount = ARRAY_SIZE2(paletteNames); +static_assert(paletteCount == paletteNameCount, ""); + // TODO / BUGBUG -- should this be ESP8266-specific? Is this only for when IR enabled ??? // FIB128 did not have this... @@ -265,7 +275,7 @@ const String paletteNames[paletteCount] = { #endif void setup() { - WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP + WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP WiFi.setSleepMode(WIFI_NONE_SLEEP); Serial.begin(115200); @@ -308,9 +318,9 @@ void setup() { FastLED.setBrightness(brightness); -#if defined(ENABLE_IR) - irReceiver.enableIRIn(); // Start the receiver -#endif +#if ENABLE_IR + InitializeIR(); +#endif // ENABLE_IR Serial.println(); Serial.println(F("System Info:")); @@ -402,13 +412,13 @@ void setup() { //automatically connect using saved credentials if they exist //If connection fails it starts an access point with the specified name - if(wifiManager.autoConnect(nameChar)){ + if (wifiManager.autoConnect(nameChar)) { Serial.println("Wi-Fi connected"); } else { Serial.println("Wi-Fi manager portal running"); } - + httpUpdateServer.setup(&webServer); webServer.on("/all", HTTP_GET, []() { @@ -595,8 +605,9 @@ void setup() { //first callback is called after the request has ended with all parsed arguments //second callback handles file uploads at that location webServer.on("/edit", HTTP_POST, []() { - webServer.send(200, "text/plain", ""); - }, handleFileUpload); + webServer.sendHeader("Access-Control-Allow-Origin", "*"); + webServer.send(200, "text/plain", ""); + }, handleFileUpload); webServer.enableCORS(true); webServer.serveStatic("/", LittleFS, "/", "max-age=86400"); @@ -607,11 +618,14 @@ void setup() { webServer.begin(); Serial.println("HTTP web server started"); - // webSocketsServer.begin(); - // webSocketsServer.onEvent(webSocketEvent); - // Serial.println("Web socket server started"); +#if ENABLE_WEBSOCKETS + InitializeWebSocketServer(); +#endif // ENABLE_WEBSOCKETS autoPlayTimeout = millis() + (autoplayDuration * 1000); +#if ENABLE_ARDUINO_OTA + ArduinoOTA.begin(); +#endif timeClient.begin(); } @@ -625,18 +639,6 @@ void sendString(String value) webServer.send(200, "text/plain", value); } -void broadcastInt(String name, uint8_t value) -{ - String json = "{\"name\":\"" + name + "\",\"value\":" + String(value) + "}"; - // webSocketsServer.broadcastTXT(json); -} - -void broadcastString(String name, String value) -{ - String json = "{\"name\":\"" + name + "\",\"value\":\"" + String(value) + "\"}"; - // webSocketsServer.broadcastTXT(json); -} - // TODO: Add board-specific entropy sources // e.g., using `uint32_t esp_random()`, if exposed in Arduino ESP32 / ESP8266 BSPs // e.g., directly reading from 0x3FF20E44 on ESP8266 (dangerous! no entropy validation, whitening) @@ -648,8 +650,6 @@ void loop() { // Modify random number generator seed; we use a lot of it. (Note: this is still deterministic) random16_add_entropy(random(65535)); - // webSocketsServer.loop(); - wifiManager.process(); webServer.handleClient(); MDNS.update(); @@ -678,7 +678,12 @@ void loop() { } checkPingTimer(); +#if ENABLE_IR handleIrInput(); // empty function when ENABLE_IR is not defined +#endif // ENABLE_IR +#if ENABLE_WEBSOCKETS + handleWebSocketLoop(); +#endif if (power == 0) { fill_solid(leds, NUM_PIXELS, CRGB::Black); @@ -716,47 +721,13 @@ void loop() { // insert a delay to keep the framerate modest ... this is guaranteed to call FastLED.show() at least once FastLED.delay(1000 / FRAMES_PER_SECOND); -} +#if ENABLE_ARDUINO_OTA + ArduinoOTA.handle(); +#endif -//void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { -// -// switch (type) { -// case WStype_DISCONNECTED: -// Serial.printf("[%u] Disconnected!\n", num); -// break; -// -// case WStype_CONNECTED: -// { -// IPAddress ip = webSocketsServer.remoteIP(num); -// Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); -// -// // send message to client -// // webSocketsServer.sendTXT(num, "Connected"); -// } -// break; -// -// case WStype_TEXT: -// Serial.printf("[%u] get Text: %s\n", num, payload); -// -// // send message to client -// // webSocketsServer.sendTXT(num, "message here"); -// -// // send data to all connected clients -// // webSocketsServer.broadcastTXT("message here"); -// break; -// -// case WStype_BIN: -// Serial.printf("[%u] get binary length: %u\n", num, length); -// hexdump(payload, length); -// -// // send message to client -// // webSocketsServer.sendBIN(num, payload, lenght); -// break; -// } -//} +} // TODO: Save settings in file system, not EEPROM! - const uint8_t SETTINGS_MAGIC_BYTE = 0x96; void readSettings() { @@ -984,6 +955,35 @@ void rainbow() fill_rainbow( leds, NUM_PIXELS, gHue, 255 / NUM_PIXELS); } +void palettebow() +{ + fill_solid(leds, NUM_PIXELS, ColorFromPalette(palettes[currentPaletteIndex], gHue, 255)); +} + +void coolerpalettebow() +{ + static uint8_t paletteStartIndex = 0; + // Why is it safe to use a `paletteStartIndex` over 16? + // The palettes array is defined as an array of `CRGBPalette16`, + // which means there are exactly 16 CRGB elements. Therefore, + // the only valid indices are [0..15]. + // + // fill_palette() calls ColorFromPalette(). + // Manual review shows that *each* of the ColorFromPalette<>() functions safely + // accept any `uint8_t` value for the start index. Therefore, there's an + // undocumented contract that the `uint8_t startIndex` provided to the function + // can be any value, without causing out-of-bounds access of the palette array. + paletteStartIndex--; + fill_palette( leds, NUM_PIXELS, paletteStartIndex, (256 / NUM_PIXELS) + 1, palettes[currentPaletteIndex], 255, LINEARBLEND); +} + +void palettebowglitter() +{ + // built-in FastLED rainbow, plus some random sparkly glitter + palettebow(); + addGlitter(80); +} + void rainbowWithGlitter() { // built-in FastLED rainbow, plus some random sparkly glitter @@ -1041,7 +1041,7 @@ void juggle() static uint8_t thisbright = 255; // How bright should the LED/display be. static uint8_t basebeat = 5; // Higher = faster movement. - static uint8_t lastSecond = 99; // Static variable, means it's only defined once. This is our 'debounce' variable. + static uint8_t lastSecond = 99; // Static variable, means it's only defined once. This is our 'debounce' variable. uint8_t secondHand = (millis() / 1000) % 30; // IMPORTANT!!! Change '30' to a different value to change duration of the loop. if (lastSecond != secondHand) { // Debounce to make sure we're not repeating an assignment. @@ -1074,6 +1074,16 @@ void water() heatMap(IceColors_p, false); } +void firepal() +{ + heatMap(palettes[currentPaletteIndex], true); +} + +void waterpal() +{ + heatMap(palettes[currentPaletteIndex], false); +} + // Pride2015 by Mark Kriegsman: https://gist.github.com/kriegsman/964de772d64c502760e5 // This function draws rainbows with an ever-changing, // widely-varying set of parameters. @@ -1133,6 +1143,7 @@ void prideFibonacci() { } #endif + void fillRadialPaletteShift(bool useFibonacciOrder) { for (uint16_t i = 0; i < NUM_PIXELS; i++) { @@ -1316,8 +1327,7 @@ void colorWavesFibonacci() // Alternate rendering function just scrolls the current palette // across the defined LED strip. -void palettetest( CRGB* ledarray, uint16_t numleds, const CRGBPalette16& gCurrentPalette) -{ +void palettetest( CRGB* ledarray, uint16_t numleds, const CRGBPalette16& gCurrentPalette) { static uint8_t startindex = 0; startindex--; fill_palette( ledarray, numleds, startindex, (256 / NUM_PIXELS) + 1, gCurrentPalette, 255, LINEARBLEND); diff --git a/esp8266-fastled-webserver/include/GradientPalettes.hpp b/esp8266-fastled-webserver/include/GradientPalettes.hpp index 13afb31a..f3ded543 100644 --- a/esp8266-fastled-webserver/include/GradientPalettes.hpp +++ b/esp8266-fastled-webserver/include/GradientPalettes.hpp @@ -35,5 +35,6 @@ DECLARE_GRADIENT_PALETTE( BlacK_Blue_Magenta_White_gp ); DECLARE_GRADIENT_PALETTE( BlacK_Magenta_Red_gp ); DECLARE_GRADIENT_PALETTE( BlacK_Red_Magenta_Yellow_gp ); DECLARE_GRADIENT_PALETTE( Blue_Cyan_Yellow_gp ); +DECLARE_GRADIENT_PALETTE( Vapour_gp ); #endif diff --git a/esp8266-fastled-webserver/include/configs/controller/controller_esp32.h b/esp8266-fastled-webserver/include/configs/controller/controller_esp32.h index 20085658..3d0c2c3b 100644 --- a/esp8266-fastled-webserver/include/configs/controller/controller_esp32.h +++ b/esp8266-fastled-webserver/include/configs/controller/controller_esp32.h @@ -51,7 +51,7 @@ static_assert(PARALLEL_OUTPUT_CHANNELS <= 4, "While ESP32 supports 16 parallel o -#if defined(ENABLE_IR) && !defined(IR_RECV_PIN) +#if defined(ENABLE_IR) && ENABLE_IR && !defined(IR_RECV_PIN) // Default pin for ESP32 is 16 (for d1 mini32, this is the same physical location as D4 on the d1 mini) #define IR_RECV_PIN 16 // TODO: VERIFY THIS IS CORRECT VALUE #endif diff --git a/esp8266-fastled-webserver/include/configs/controller/controller_esp8266.h b/esp8266-fastled-webserver/include/configs/controller/controller_esp8266.h index e8c62b0c..e3bfddc7 100644 --- a/esp8266-fastled-webserver/include/configs/controller/controller_esp8266.h +++ b/esp8266-fastled-webserver/include/configs/controller/controller_esp8266.h @@ -46,7 +46,7 @@ static_assert(PARALLEL_OUTPUT_CHANNELS <= 6, "ESP8266 only supports six parallel #define DATA_PIN_6 D2 // d1 mini #endif -#if defined(ENABLE_IR) && !defined(IR_RECV_PIN) +#if defined(ENABLE_IR) && ENABLE_IR && !defined(IR_RECV_PIN) #define IR_RECV_PIN D4 #endif diff --git a/esp8266-fastled-webserver/include/configs/controller/controller_template.h b/esp8266-fastled-webserver/include/configs/controller/controller_template.h index a658e2db..1248b63d 100644 --- a/esp8266-fastled-webserver/include/configs/controller/controller_template.h +++ b/esp8266-fastled-webserver/include/configs/controller/controller_template.h @@ -38,7 +38,7 @@ #define FASTLED_INTERRUPT_RETRY_COUNT 0 // ENABLE_IR defines whether to include support for an IR receiver -// #define ENABLE_IR +// #define ENABLE_IR 1 // #define IR_RECV_PIN D4 // d1 mini // #define IR_RECV_PIN 16 // d1 mini32 (same physical location as D4 on the d1 mini) diff --git a/esp8266-fastled-webserver/include/configs/product/product_template.h b/esp8266-fastled-webserver/include/configs/product/product_template.h index 761cce2f..3af6c988 100644 --- a/esp8266-fastled-webserver/include/configs/product/product_template.h +++ b/esp8266-fastled-webserver/include/configs/product/product_template.h @@ -156,9 +156,10 @@ #define PARALLEL_OUTPUT_CHANNELS 1 #endif -// // By default, no IR support is included. Define ENABLE_IR to enable IR support. -// #define ENABLE_IR -// // When ENABLE_IR is defined, can also override controller-specific default: +// // By default, no IR support is included. Define ENABLE_IR as to enable IR support. +// #define ENABLE_IR 1 + +// // When ENABLE_IR is defined as 1, can also override controller-specific default: // // #define IR_RECV_PIN D99 diff --git a/platformio_override_example.ini b/platformio_override_example.ini index 8876284c..7cf80f1c 100644 --- a/platformio_override_example.ini +++ b/platformio_override_example.ini @@ -18,3 +18,15 @@ build_flags = -D PIXELS_ON_DATA_PIN_5=17 -D PIXELS_ON_DATA_PIN_6=19 + +; This environment example enable IR decoding, +; which requires adding a new library dependency. +[env:custom_fib256_with_IR] +extends = common__d1_mini +lib_deps = + ${esp8266.lib_deps} + crankyoldgit/IRremoteESP8266 @ ^2.8.0 +build_flags = + ${common.build_flags_esp8266} + -D PRODUCT_FIBONACCI256 + -D ENABLE_IR=1