diff --git a/Noise.h b/Noise.h new file mode 100644 index 0000000..17bb720 --- /dev/null +++ b/Noise.h @@ -0,0 +1,215 @@ +/* + ESP8266 + FastLED + IR Remote: https://github.com/jasoncoon/esp8266-fastled-webserver + Copyright (C) 2015-2016 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 . +*/ + +#define MAX_DIMENSION ((MatrixWidth > MatrixHeight) ? MatrixWidth : MatrixHeight) + +// The 16 bit version of our coordinates +uint16_t noisex; +uint16_t noisey; +uint16_t noisez; + +// We're using the x/y dimensions to map to the x/y pixels on the matrix. We'll +// use the z-axis for "time". speed determines how fast time moves forward. Try +// 1 for a very slow moving effect, or 60 for something that ends up looking like +// water. +int noisespeedx = 0; +int noisespeedy = 1; +int noisespeedz = 0; + +// Scale determines how far apart the pixels in our noise matrix are. Try +// changing these values around to see how it affects the motion of the display. The +// higher the value of scale, the more "zoomed out" the noise will be. A value +// of 1 will be so zoomed in, you'll mostly see solid colors. +uint16_t noisescale = 1; // scale is set dynamically once we've started up + +// This is the array that we keep our computed noise values in +uint8_t noise[MAX_DIMENSION][MAX_DIMENSION]; + +uint8_t colorLoop = 0; + +CRGBPalette16 blackAndWhiteStripedPalette; + +// This function sets up a palette of black and white stripes, +// using code. Since the palette is effectively an array of +// sixteen CRGB colors, the various fill_* functions can be used +// to set them up. +void SetupBlackAndWhiteStripedPalette() +{ + // 'black out' all 16 palette entries... + fill_solid( blackAndWhiteStripedPalette, 16, CRGB::Black); + // and set every fourth one to white. + blackAndWhiteStripedPalette[0] = CRGB::White; + blackAndWhiteStripedPalette[4] = CRGB::White; + blackAndWhiteStripedPalette[8] = CRGB::White; + blackAndWhiteStripedPalette[12] = CRGB::White; + +} + +CRGBPalette16 blackAndBlueStripedPalette; + +// This function sets up a palette of black and blue stripes, +// using code. Since the palette is effectively an array of +// sixteen CRGB colors, the various fill_* functions can be used +// to set them up. +void SetupBlackAndBlueStripedPalette() +{ + // 'black out' all 16 palette entries... + fill_solid( blackAndBlueStripedPalette, 16, CRGB::Black); + + for(uint8_t i = 0; i < 6; i++) { + blackAndBlueStripedPalette[i] = CRGB::Blue; + } +} + +// There are several different palettes of colors demonstrated here. +// +// FastLED provides several 'preset' palettes: RainbowColors_p, RainbowStripeColors_p, +// OceanColors_p, CloudColors_p, LavaColors_p, ForestColors_p, and PartyColors_p. +// +// Additionally, you can manually define your own color palettes, or you can write +// code that creates color palettes on the fly. + +void drawNoise(CRGBPalette16 palette, uint8_t hueReduce = 0) +{ + for (uint8_t x = 0; x < MatrixWidth; x++) { + for(uint8_t y = 0; y < MatrixHeight; y++) { + uint16_t i = XY(x, y); + + int xoffset = noisescale * x; + int yoffset = noisescale * y; + + uint8_t data = inoise8(x + xoffset + noisex, y + yoffset + noisey, noisez); + + // The range of the inoise8 function is roughly 16-238. + // These two operations expand those values out to roughly 0..255 + // You can comment them out if you want the raw noise data. + data = qsub8(data, 16); + data = qadd8(data, scale8(data, 39)); + + if(hueReduce > 0 && data >= hueReduce) + data -= hueReduce; + + leds[i] = ColorFromPalette(palette, data, 255, LINEARBLEND); + } + } + + noisex += noisespeedx; + noisey += noisespeedy; + noisez += noisespeedz; +} + +void rainbowNoise() { + noisespeedx = 0; + noisespeedy = -1; + noisespeedz = 0; + noisescale = 24; + colorLoop = 0; + drawNoise(RainbowColors_p); +} + +void rainbowStripeNoise() { + noisespeedx = 0; + noisespeedy = -2; + noisespeedz = 0; + noisescale = 24; + colorLoop = 0; + drawNoise(RainbowStripeColors_p); +} + +void partyNoise() { + noisespeedx = -9; + noisespeedy = 0; + noisespeedz = 0; + noisescale = 32; + colorLoop = 0; + drawNoise(PartyColors_p); +} + +void forestNoise() { + noisespeedx = -9; + noisespeedy = 0; + noisespeedz = 0; + noisescale = 32; + colorLoop = 0; + drawNoise(ForestColors_p); +} + +void cloudNoise() { + noisespeedx = -2; + noisespeedy = 0; + noisespeedz = 0; + noisescale = 24; + colorLoop = 0; + drawNoise(CloudColors_p); +} + +void fireNoise() { + noisespeedx = 0; // 24; + noisespeedy = -32; + noisespeedz = 0; + noisescale = 64; + colorLoop = 0; + drawNoise(HeatColors_p, 60); +} + +void fireNoise2() { + noisespeedx = 0; + noisespeedy = -8; + noisespeedz = 3; + noisescale = 32; + colorLoop = 0; + drawNoise(HeatColors_p); +} + +void lavaNoise() { + noisespeedx = 0; + noisespeedy = -1; + noisespeedz = 1; + noisescale = 24; + colorLoop = 0; + drawNoise(LavaColors_p); +} + +void oceanNoise() { + noisespeedx = -2; + noisespeedy = 0; + noisespeedz = 4; + noisescale = 24; + colorLoop = 0; + drawNoise(OceanColors_p); +} + +void blackAndWhiteNoise() { + SetupBlackAndWhiteStripedPalette(); + noisespeedx = -12; + noisespeedy = 0; + noisespeedz = 0; + noisescale = 24; + colorLoop = 0; + drawNoise(blackAndWhiteStripedPalette); +} + +void blackAndBlueNoise() { + SetupBlackAndBlueStripedPalette(); + noisespeedx = 0; + noisespeedy = 8; + noisespeedz = 0; + noisescale = 32; + colorLoop = 0; + drawNoise(blackAndBlueStripedPalette); +} diff --git a/README.md b/README.md index 19cc4ab..fa8ee1a 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,22 @@ -FastLED + ESP8266 Web Server +Ultim8x8 RGB LED Panel + FastLED + ESP8266 Web Server ========= -Control an addressable LED strip with an ESP8266 via a web browser or infrared remote control. +Control an [ULTiM8x8 RGB LED Panel] with an ESP8266 via a web browser. Hardware -------- -An ESP8266 development board, such as the [Adafruit HUZZAH ESP8266 Breakout]: +[Adafruit Feather HUZZAH with ESP8266 WiFi] -[![Adafruit HUZZAH ESP8266 Breakout](https://cdn-shop.adafruit.com/310x233/2471-10.jpg)](https://www.adafruit.com/products/2471) +[![Adafruit Feather HUZZAH with ESP8266 WiFi](https://cdn-shop.adafruit.com/310x233/2821-01.jpg)](https://www.adafruit.com/products/2821) -Addressable LED strip, such as the [Adafruit NeoPixel Ring]: +[ULTiM8x8 RGB LED Panel] -[![Adafruit NeoPixel Ring](https://www.adafruit.com/images/145x109/1586-00.jpg)](https://www.adafruit.com/product/1586) +[![ULTiM8x8 RGB LED Panel](https://www.crowdsupply.com/img/7d3e/ultim8x8-bothboards_jpg_project-body.jpg)](https://www.crowdsupply.com/maniacal-labs-wyolum/ultim8x8) Features -------- -* Turn the NeoPixel Ring on and off +* Turn the LEDs on and off * Adjust the brightness * Change the display pattern * Adjust the color @@ -32,9 +32,6 @@ The web app is stored in SPIFFS (on-board flash memory). The web app is a single page app with separate files for js and css, using [jQuery](https://jquery.com) and [Bootstrap](http://getbootstrap.com). It has buttons for On/Off, a slider for brightness, a pattern selector, and a color picker (using [jQuery MiniColors](http://labs.abeautifulsite.net/jquery-minicolors)). Event handlers for the controls are wired up, so you don't have to click a 'Send' button after making changes. The brightness slider and the color picker use a delayed event handler, to prevent from flooding the ESP8266 web server with too many requests too quickly. -The only drawback to SPIFFS that I've found so far is uploading the files is extremely slow, requiring several minutes, regardless of how large the files are. It's so slow that I've been just developing the web app and debugging locally on my desktop (with a hard-coded IP for the ESP8266), before uploading to SPIFFS and testing on the ESP8266. - - Installing ----------- @@ -58,10 +55,5 @@ REST Web services The firmware implements basic [RESTful web services](https://en.wikipedia.org/wiki/Representational_state_transfer) using the ESP8266WebServer library. Current values are requested with HTTP GETs, and values are set with POSTs using query string parameters. It can run in connected or standalone access point modes. -Infrared Remote Control ------------------------ - -Control via infrared remote control is also supported, via the [ESP8266 port of the IRremote library](https://github.com/markszabo/IRremoteESP8266). - -[Adafruit NeoPixel Ring]:https://www.adafruit.com/product/1586 -[Adafruit HUZZAH ESP8266 Breakout]:https://www.adafruit.com/products/2471 +[ULTiM8x8 RGB LED Panel]:https://www.crowdsupply.com/maniacal-labs-wyolum/ultim8x8 +[Adafruit Feather HUZZAH with ESP8266 WiFi]:https://www.adafruit.com/products/2471 diff --git a/esp8266-fastled-webserver.ino b/esp8266-fastled-webserver.ino index 68712f5..c6a9b30 100644 --- a/esp8266-fastled-webserver.ino +++ b/esp8266-fastled-webserver.ino @@ -24,25 +24,25 @@ extern "C" { } #include -#include +//#include #include #include #include #include #include -#include +//#include #include "GradientPalettes.h" #define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0])) #include "Field.h" -#define HOSTNAME "ESP8266-" ///< Hostname. The setup function adds the Chip ID at the end. +#define HOSTNAME "ESP8266-Feather-" ///< Hostname. The setup function adds the Chip ID at the end. -#define RECV_PIN D4 -IRrecv irReceiver(RECV_PIN); +//#define RECV_PIN D4 +//IRrecv irReceiver(RECV_PIN); -#include "Commands.h" +//#include "Commands.h" const bool apMode = false; @@ -59,10 +59,15 @@ ESP8266HTTPUpdateServer httpUpdateServer; #include "FSBrowser.h" -#define DATA_PIN D8 -#define LED_TYPE WS2811 -#define COLOR_ORDER GRB -#define NUM_LEDS 24 +#define DATA_PIN 13 +#define CLK_PIN 14 +#define LED_TYPE APA102 +#define COLOR_ORDER BGR +#define MatrixWidth 24 +#define MatrixHeight 8 +#define NUM_LEDS MatrixWidth * MatrixHeight + +const bool MatrixSerpentineLayout = true; #define MILLI_AMPS 2000 // IMPORTANT: set the max milli-Amps of your power supply (4A = 4000mA) #define FRAMES_PER_SECOND 120 // here you can control the speed. With the Access Point / Web Server the animations run a bit slower. @@ -115,6 +120,28 @@ uint8_t gHue = 0; // rotating "base color" used by many of the patterns CRGB solidColor = CRGB::Blue; +uint16_t XY( uint8_t x, uint8_t y) +{ + uint16_t i; + + if ( MatrixSerpentineLayout == false) { + i = (y * MatrixWidth) + x; + } + + if ( MatrixSerpentineLayout == true) { + if ( x & 0x01) { + // Odd columns run backwards + uint8_t reverseY = (MatrixHeight - 1) - y; + i = (x * MatrixHeight) + reverseY; + } else { + // Even rows run forwards + i = (x * MatrixHeight) + y; + } + } + + return i; +} + // scale the brightness of all pixels down void dimAll(byte value) { @@ -133,12 +160,38 @@ typedef PatternAndName PatternAndNameList[]; #include "Twinkles.h" #include "TwinkleFOX.h" +#include "Noise.h" // List of patterns to cycle through. Each is defined as a separate function below. PatternAndNameList patterns = { { pride, "Pride" }, + { pride2, "Pride 2" }, { colorWaves, "Color Waves" }, + { colorWaves2, "Color Waves 2" }, + + { xyMatrixTest, "Matrix Test" }, + + { verticalPalette, "Vertical Palette" }, + { diagonalPalette, "Diagonal Palette" }, + { horizontalPalette, "Horizontal Palette" }, + + { verticalGradientPalette, "Vertical Gradient Palette" }, + { diagonalGradientPalette, "Diagonal Gradient Palette" }, + { horizontalGradientPalette, "Horizontal Gradient Palette" }, + + // noise patterns + { fireNoise, "Fire Noise" }, + { fireNoise2, "Fire Noise 2" }, + { lavaNoise, "Lava Noise" }, + { rainbowNoise, "Rainbow Noise" }, + { rainbowStripeNoise, "Rainbow Stripe Noise" }, + { partyNoise, "Party Noise" }, + { forestNoise, "Forest Noise" }, + { cloudNoise, "Cloud Noise" }, + { oceanNoise, "Ocean Noise" }, + { blackAndWhiteNoise, "Black & White Noise" }, + { blackAndBlueNoise, "Black & Blue Noise" }, // twinkle patterns { rainbowTwinkles, "Rainbow Twinkles" }, @@ -214,8 +267,8 @@ void setup() { delay(100); Serial.setDebugOutput(true); - FastLED.addLeds(leds, NUM_LEDS); // for WS2812 (Neopixel) - //FastLED.addLeds(leds, NUM_LEDS); // for APA102 (Dotstar) + //FastLED.addLeds(leds, NUM_LEDS); // for WS2812 (Neopixel) + FastLED.addLeds(leds, NUM_LEDS); // for APA102 (Dotstar) FastLED.setDither(false); FastLED.setCorrection(TypicalLEDStrip); FastLED.setBrightness(brightness); @@ -228,7 +281,7 @@ void setup() { FastLED.setBrightness(brightness); - irReceiver.enableIRIn(); // Start the receiver + // irReceiver.enableIRIn(); // Start the receiver Serial.println(); Serial.print( F("Heap: ") ); Serial.println(system_get_free_heap_size()); @@ -263,10 +316,10 @@ void setup() { for (uint8_t i = 0; i < hostname.length(); i++) hostnameChar[i] = hostname.charAt(i); - MDNS.begin(hostnameChar); + // MDNS.begin(hostnameChar); // Add service to MDNS-SD - MDNS.addService("http", "tcp", 80); + // MDNS.addService("http", "tcp", 80); // Print hostname. Serial.println("Hostname: " + hostname); @@ -476,7 +529,7 @@ void loop() { webSocketsServer.loop(); webServer.handleClient(); - handleIrInput(); + // handleIrInput(); if (power == 0) { fill_solid(leds, NUM_LEDS, CRGB::Black); @@ -552,212 +605,212 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length } } -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; - } - } -} +//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; +// } +// } +//} void loadSettings() { @@ -976,6 +1029,97 @@ void rainbow() fill_rainbow( leds, NUM_LEDS, gHue, 255 / NUM_LEDS); } +void xyMatrixTest() +{ + FastLED.clear(); + + static uint8_t x = 0; + static uint8_t y = 0; + + leds[XY(x, y)] = CHSV(gHue, 255, 255); + + EVERY_N_MILLIS(30) { + x++; + if(x >= MatrixWidth) { + x = 0; + y++; + if(y >= MatrixHeight) { + y = 0; + } + } + } +} + +void verticalPalette() { + uint8_t verticalHues = 256 / MatrixHeight; + + for(uint8_t y = 0; y < MatrixHeight; y++) { + CRGB color = ColorFromPalette(palettes[currentPaletteIndex], beat8(speed) + (y * verticalHues)); + + for(uint8_t x = 0; x < MatrixWidth; x++) { + leds[XY(x, y)] = color; + } + } +} + +void diagonalPalette() { + uint8_t verticalHues = 256 / MatrixHeight; + + for(uint8_t y = 0; y < MatrixHeight; y++) { + for(uint8_t x = 0; x < MatrixWidth; x++) { + CRGB color = ColorFromPalette(palettes[currentPaletteIndex], beat8(speed) - ((x - y) * verticalHues)); + leds[XY(x, y)] = color; + } + } +} + +void horizontalPalette() { + uint8_t horizontalHues = 256 / MatrixWidth; + + for(uint8_t x = 0; x < MatrixWidth; x++) { + CRGB color = ColorFromPalette(palettes[currentPaletteIndex], beat8(speed) - (x * horizontalHues)); + + for(uint8_t y = 0; y < MatrixHeight; y++) { + leds[XY(x, y)] = color; + } + } +} + +void verticalGradientPalette() { + uint8_t verticalHues = 256 / MatrixHeight; + + for(uint8_t y = 0; y < MatrixHeight; y++) { + CRGB color = ColorFromPalette(gCurrentPalette, beat8(speed) + (y * verticalHues)); + + for(uint8_t x = 0; x < MatrixWidth; x++) { + leds[XY(x, y)] = color; + } + } +} + +void diagonalGradientPalette() { + uint8_t verticalHues = 256 / MatrixHeight; + + for(uint8_t y = 0; y < MatrixHeight; y++) { + for(uint8_t x = 0; x < MatrixWidth; x++) { + CRGB color = ColorFromPalette(gCurrentPalette, beat8(speed) - ((x - y) * verticalHues)); + leds[XY(x, y)] = color; + } + } +} + +void horizontalGradientPalette() { + uint8_t horizontalHues = 256 / MatrixWidth; + + for(uint8_t x = 0; x < MatrixWidth; x++) { + CRGB color = ColorFromPalette(gCurrentPalette, beat8(speed) - (x * horizontalHues)); + + for(uint8_t y = 0; y < MatrixHeight; y++) { + leds[XY(x, y)] = color; + } + } +} + void rainbowWithGlitter() { // built-in FastLED rainbow, plus some random sparkly glitter @@ -1110,6 +1254,46 @@ void pride() } } +void pride2() +{ + static uint16_t sPseudotime = 0; + static uint16_t sLastMillis = 0; + static uint16_t sHue16 = 0; + + uint8_t sat8 = beatsin88( 87, 220, 250); + uint8_t brightdepth = beatsin88( 341, 96, 224); + uint16_t brightnessthetainc16 = beatsin88( 203, (25 * 256), (40 * 256)); + uint8_t msmultiplier = beatsin88(147, 23, 60); + + uint16_t hue16 = sHue16;//gHue * 256; + uint16_t hueinc16 = beatsin88(113, 1, 3000); + + uint16_t ms = millis(); + uint16_t deltams = ms - sLastMillis ; + sLastMillis = ms; + sPseudotime += deltams * msmultiplier; + sHue16 += deltams * beatsin88( 400, 5, 9); + uint16_t brightnesstheta16 = sPseudotime; + + for (uint8_t x = 0; x < MatrixWidth; x++) { + hue16 += hueinc16; + uint8_t hue8 = hue16 / 256; + + brightnesstheta16 += brightnessthetainc16; + uint16_t b16 = sin16( brightnesstheta16 ) + 32768; + + uint16_t bri16 = (uint32_t)((uint32_t)b16 * (uint32_t)b16) / 65536; + uint8_t bri8 = (uint32_t)(((uint32_t)bri16) * brightdepth) / 65536; + bri8 += (255 - brightdepth); + + CRGB newcolor = CHSV( hue8, sat8, bri8); + + for (uint8_t y = 0; y < MatrixHeight; y++) { + nblend(leds[XY(x, y)], newcolor, 64); + } + } +} + void radialPaletteShift() { for (uint8_t i = 0; i < NUM_LEDS; i++) { @@ -1249,6 +1433,56 @@ void colorwaves( CRGB* ledarray, uint16_t numleds, CRGBPalette16& palette) } } +void colorWaves2() +{ + static uint16_t sPseudotime = 0; + static uint16_t sLastMillis = 0; + static uint16_t sHue16 = 0; + + // uint8_t sat8 = beatsin88( 87, 220, 250); + uint8_t brightdepth = beatsin88( 341, 96, 224); + uint16_t brightnessthetainc16 = beatsin88( 203, (25 * 256), (40 * 256)); + uint8_t msmultiplier = beatsin88(147, 23, 60); + + uint16_t hue16 = sHue16;//gHue * 256; + uint16_t hueinc16 = beatsin88(113, 300, 1500); + + uint16_t ms = millis(); + uint16_t deltams = ms - sLastMillis ; + sLastMillis = ms; + sPseudotime += deltams * msmultiplier; + sHue16 += deltams * beatsin88( 400, 5, 9); + uint16_t brightnesstheta16 = sPseudotime; + + for (uint8_t x = 0; x < MatrixWidth; x++) { + hue16 += hueinc16; + uint8_t hue8 = hue16 / 256; + uint16_t h16_128 = hue16 >> 7; + if ( h16_128 & 0x100) { + hue8 = 255 - (h16_128 >> 1); + } else { + hue8 = h16_128 >> 1; + } + + brightnesstheta16 += brightnessthetainc16; + uint16_t b16 = sin16( brightnesstheta16 ) + 32768; + + uint16_t bri16 = (uint32_t)((uint32_t)b16 * (uint32_t)b16) / 65536; + uint8_t bri8 = (uint32_t)(((uint32_t)bri16) * brightdepth) / 65536; + bri8 += (255 - brightdepth); + + uint8_t index = hue8; + //index = triwave8( index); + index = scale8( index, 240); + + CRGB newcolor = ColorFromPalette(gCurrentPalette, index, bri8); + + for (uint8_t y = 0; y < MatrixHeight; y++) { + nblend(leds[XY(x, y)], newcolor, 128); + } + } +} + // Alternate rendering function just scrolls the current palette // across the defined LED strip. void palettetest( CRGB* ledarray, uint16_t numleds, const CRGBPalette16& gCurrentPalette)