Skip to content

Instantly share code, notes, and snippets.

@jasoncoon
Created April 23, 2022 21:42
Show Gist options
  • Save jasoncoon/7d3f204414106ba929b0750ec1d62d72 to your computer and use it in GitHub Desktop.
Save jasoncoon/7d3f204414106ba929b0750ec1d62d72 to your computer and use it in GitHub Desktop.
/*
FastLED Mapping Demo: https://github.com/jasoncoon/led-mapper
Copyright (C) 2022 Jason Coon, Evil Genius Labs LLC
For LumosRing by Bradán Lane STUDIO
https://www.tindie.com/products/bradanlane/lumosring-circuitpython-led-ring-block/
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 <http://www.gnu.org/licenses/>.
*/
#include <FastLED.h> // https://github.com/FastLED/FastLED
FASTLED_USING_NAMESPACE
// Based on FastLED "100-lines-of-code" demo reel, showing just a few
// of the kinds of animation patterns you can quickly and easily
// compose using FastLED.
//
// This example also shows one easy way to define multiple
// animations patterns and have them automatically rotate.
//
// -Mark Kriegsman, December 2014
#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000)
#warning "Requires FastLED 3.1 or later; check github for latest code."
#endif
// change these to match your data pin, LED type, and color order
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
#define BRIGHTNESS 32
// start of data copied from LED Mapper:
#define NUM_LEDS 310
byte coordsX[NUM_LEDS] = { 128, 128, 128, 128, 138, 139, 140, 141, 148, 150, 152, 154, 158, 161, 164, 167, 167, 171, 175, 179, 177, 181, 186, 191, 185, 191, 197, 202, 193, 200, 206, 213, 200, 208, 215, 222, 207, 215, 223, 231, 212, 221, 229, 238, 217, 226, 235, 244, 221, 230, 239, 249, 223, 233, 243, 252, 225, 235, 245, 254, 226, 235, 245, 255, 225, 235, 245, 254, 223, 233, 243, 252, 221, 230, 239, 249, 217, 226, 235, 244, 212, 221, 229, 238, 207, 215, 223, 231, 200, 208, 215, 222, 193, 200, 206, 213, 185, 191, 197, 202, 177, 181, 186, 191, 167, 171, 175, 179, 158, 161, 164, 167, 148, 150, 152, 154, 138, 139, 140, 141, 128, 128, 128, 128, 117, 116, 115, 114, 107, 105, 103, 101, 97, 94, 91, 88, 88, 84, 80, 76, 79, 74, 69, 64, 70, 64, 58, 53, 62, 55, 49, 42, 55, 47, 40, 33, 48, 40, 32, 24, 43, 34, 26, 17, 38, 29, 20, 11, 34, 25, 16, 6, 32, 22, 12, 3, 30, 20, 10, 1, 29, 20, 10, 0, 30, 20, 10, 1, 32, 22, 12, 3, 34, 25, 16, 6, 38, 29, 20, 11, 43, 34, 26, 17, 48, 40, 32, 24, 55, 47, 40, 33, 62, 55, 49, 42, 70, 64, 58, 53, 78, 74, 69, 64, 88, 84, 80, 76, 97, 94, 91, 88, 107, 105, 103, 101, 117, 116, 115, 114, 78, 88, 98, 108, 118, 137, 147, 157, 167, 177, 78, 88, 98, 108, 118, 137, 147, 157, 167, 177, 78, 88, 98, 108, 118, 137, 147, 157, 167, 177, 78, 88, 98, 108, 118, 137, 147, 157, 167, 177, 78, 88, 98, 108, 118, 137, 147, 157, 167, 177, 78, 88, 98, 108, 118, 137, 147, 157, 167, 177, 78, 88, 98, 108, 118, 137, 147, 157, 167, 177 };
byte coordsY[NUM_LEDS] = { 226, 235, 245, 255, 225, 235, 244, 254, 223, 233, 243, 252, 221, 230, 239, 249, 217, 226, 235, 244, 212, 221, 229, 238, 207, 215, 223, 231, 200, 208, 215, 222, 193, 200, 206, 213, 185, 191, 197, 202, 176, 181, 186, 191, 167, 171, 175, 179, 158, 161, 164, 167, 148, 150, 152, 154, 138, 139, 140, 141, 127, 127, 127, 127, 117, 116, 115, 114, 107, 105, 103, 101, 97, 94, 91, 88, 88, 84, 80, 76, 78, 73, 69, 64, 70, 64, 58, 52, 62, 55, 49, 42, 55, 47, 40, 33, 48, 40, 32, 24, 42, 34, 25, 17, 38, 29, 20, 11, 34, 25, 15, 6, 31, 22, 12, 3, 30, 20, 10, 1, 29, 20, 10, 0, 30, 20, 10, 1, 31, 22, 12, 3, 34, 25, 15, 6, 38, 29, 20, 11, 42, 34, 25, 17, 48, 40, 32, 24, 54, 47, 40, 33, 62, 55, 49, 42, 70, 64, 58, 52, 78, 73, 69, 64, 87, 83, 79, 76, 97, 94, 91, 88, 107, 105, 103, 101, 117, 116, 115, 114, 127, 127, 127, 127, 138, 139, 140, 141, 148, 150, 152, 154, 158, 161, 164, 167, 167, 171, 175, 179, 176, 181, 186, 191, 185, 191, 197, 202, 193, 200, 206, 213, 200, 208, 215, 222, 207, 215, 223, 231, 212, 221, 229, 238, 217, 226, 235, 244, 221, 230, 239, 249, 223, 233, 243, 252, 225, 235, 244, 254, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96 };
byte angles[NUM_LEDS] = { 191, 191, 191, 191, 187, 187, 187, 187, 183, 183, 183, 183, 178, 179, 178, 179, 174, 174, 174, 174, 170, 170, 170, 170, 166, 166, 166, 166, 162, 162, 162, 161, 157, 157, 157, 157, 153, 153, 153, 153, 149, 149, 149, 149, 145, 145, 145, 144, 140, 140, 140, 140, 136, 136, 136, 136, 132, 132, 132, 132, 128, 128, 128, 128, 123, 123, 123, 123, 119, 119, 119, 119, 115, 115, 115, 115, 110, 111, 111, 111, 106, 106, 106, 106, 102, 102, 102, 102, 98, 98, 98, 98, 93, 94, 94, 94, 89, 89, 89, 89, 85, 85, 85, 85, 81, 81, 81, 81, 77, 77, 77, 76, 72, 72, 72, 72, 68, 68, 68, 68, 64, 64, 64, 64, 60, 59, 60, 60, 55, 55, 55, 55, 51, 51, 51, 51, 47, 47, 47, 47, 43, 43, 43, 43, 38, 38, 38, 38, 34, 34, 34, 34, 30, 30, 30, 30, 26, 26, 26, 26, 21, 21, 21, 21, 17, 17, 17, 17, 13, 13, 13, 13, 8, 8, 8, 8, 4, 4, 4, 4, 0, 255, 0, 0, 251, 251, 251, 251, 247, 247, 247, 246, 242, 242, 242, 242, 238, 238, 238, 238, 234, 234, 234, 234, 229, 229, 229, 230, 225, 225, 225, 225, 221, 221, 221, 221, 217, 217, 217, 217, 213, 212, 212, 212, 208, 208, 208, 208, 204, 204, 204, 204, 200, 200, 200, 200, 195, 196, 195, 195, 232, 228, 222, 214, 203, 179, 169, 161, 155, 151, 239, 235, 230, 222, 209, 174, 161, 153, 147, 144, 246, 244, 241, 235, 222, 161, 147, 141, 138, 136, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 9, 11, 14, 20, 33, 94, 108, 114, 117, 119, 16, 20, 25, 33, 46, 81, 94, 102, 108, 111, 23, 27, 33, 41, 52, 76, 86, 94, 100, 104 };
byte radii[NUM_LEDS] = { 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 215, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 196, 216, 235, 255, 117, 101, 86, 74, 66, 66, 74, 86, 101, 117, 107, 89, 72, 58, 46, 46, 57, 72, 89, 107, 100, 81, 62, 45, 29, 29, 44, 62, 81, 100, 98, 78, 59, 39, 20, 20, 39, 59, 78, 98, 100, 81, 62, 44, 29, 29, 44, 62, 81, 100, 107, 89, 72, 57, 46, 46, 57, 72, 89, 107, 117, 101, 86, 74, 66, 66, 74, 86, 101, 117 };
// end of data copied from LED Mapper
CRGB leds[NUM_LEDS];
#define FRAMES_PER_SECOND 120
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
uint8_t offset = 0; // rotating "base color" used by many of the patterns
uint8_t speed = 30;
boolean autoplay = true;
uint8_t autoplaySeconds = 2;
void setup()
{
// delay(3000); // 3 second delay for recovery
Serial.begin(9600);
// tell FastLED about the LED strip configuration
FastLED.addLeds<LED_TYPE, 16, COLOR_ORDER>(leds, 0, 240);
FastLED.addLeds<LED_TYPE, 17, COLOR_ORDER>(leds, 240, 70);
FastLED.setMaxPowerInVoltsAndMilliamps(5, 1000); // 1A
FastLED.setBrightness(BRIGHTNESS);
}
// List of patterns to cycle through. Each is defined as a separate function below.
typedef void (*SimplePatternList[])();
SimplePatternList patterns = {
// 2D map examples:
clockwisePalette,
counterClockwisePalette,
outwardPalette,
inwardPalette,
northPalette,
northEastPalette,
eastPalette,
southEastPalette,
southPalette,
southWestPalette,
westPalette,
northWestPalette,
// standard FastLED demo reel examples:
// rainbow,
// rainbowWithGlitter,
// confetti,
// sinelon,
// juggle,
// bpm
};
const uint8_t patternCount = ARRAY_SIZE(patterns);
uint8_t currentPatternIndex = 0; // Index number of which pattern is current
CRGBPalette16 IceColors_p = CRGBPalette16(CRGB::Black, CRGB::Blue, CRGB::Aqua, CRGB::White);
const CRGBPalette16 palettes[] = {
RainbowColors_p,
RainbowStripeColors_p,
CloudColors_p,
LavaColors_p,
OceanColors_p,
ForestColors_p,
PartyColors_p,
HeatColors_p,
IceColors_p,
};
const uint8_t paletteCount = ARRAY_SIZE(palettes);
uint8_t currentPaletteIndex = 0;
CRGBPalette16 currentPalette = palettes[currentPaletteIndex];
boolean autoplayPalettes = true;
uint8_t autoplayPaletteSeconds = autoplaySeconds * patternCount;
void loop()
{
// Call the current pattern function once, updating the 'leds' array
patterns[currentPatternIndex]();
offset = beat8(speed);
// do some periodic updates
EVERY_N_SECONDS(autoplaySeconds)
{
if (autoplay)
{
nextPattern(); // change patterns periodically
}
}
EVERY_N_SECONDS(autoplayPaletteSeconds)
{
// change palettes periodically
if (autoplayPalettes)
{
nextPalette();
}
}
// send the 'leds' array out to the actual LED strip
// FastLED.show(); called automatically, internally by FastLED.delay below:
// insert a delay to keep the framerate modest
FastLED.delay(1000 / FRAMES_PER_SECOND);
}
void nextPattern()
{
// add one to the current pattern number, and wrap around at the end
currentPatternIndex = (currentPatternIndex + 1) % patternCount;
}
void nextPalette()
{
// add one to the current palette number, and wrap around at the end
currentPaletteIndex = (currentPaletteIndex + 1) % paletteCount;
currentPalette = palettes[currentPaletteIndex];
}
// 2D map examples:
void clockwisePalette()
{
for (uint16_t i = 0; i < NUM_LEDS; i++)
{
leds[i] = ColorFromPalette(currentPalette, offset + angles[i]);
}
}
void counterClockwisePalette()
{
for (uint16_t i = 0; i < NUM_LEDS; i++)
{
leds[i] = ColorFromPalette(currentPalette, offset - angles[i]);
}
}
void outwardPalette()
{
for (uint16_t i = 0; i < NUM_LEDS; i++)
{
leds[i] = ColorFromPalette(currentPalette, offset - radii[i]);
}
}
void inwardPalette()
{
for (uint16_t i = 0; i < NUM_LEDS; i++)
{
leds[i] = ColorFromPalette(currentPalette, offset + radii[i]);
}
}
void northPalette()
{
for (uint16_t i = 0; i < NUM_LEDS; i++)
{
leds[i] = ColorFromPalette(currentPalette, offset - coordsY[i]);
}
}
void northEastPalette()
{
for (uint16_t i = 0; i < NUM_LEDS; i++)
{
leds[i] = ColorFromPalette(currentPalette, offset - (coordsX[i] + coordsY[i]));
}
}
void eastPalette()
{
for (uint16_t i = 0; i < NUM_LEDS; i++)
{
leds[i] = ColorFromPalette(currentPalette, offset - coordsX[i]);
}
}
void southEastPalette()
{
for (uint16_t i = 0; i < NUM_LEDS; i++)
{
leds[i] = ColorFromPalette(currentPalette, offset - coordsX[i] + coordsY[i]);
}
}
void southPalette()
{
for (uint16_t i = 0; i < NUM_LEDS; i++)
{
leds[i] = ColorFromPalette(currentPalette, offset + coordsY[i]);
}
}
void southWestPalette()
{
for (uint16_t i = 0; i < NUM_LEDS; i++)
{
leds[i] = ColorFromPalette(currentPalette, offset + coordsX[i] + coordsY[i]);
}
}
void westPalette()
{
for (uint16_t i = 0; i < NUM_LEDS; i++)
{
leds[i] = ColorFromPalette(currentPalette, offset + coordsX[i]);
}
}
void northWestPalette()
{
for (uint16_t i = 0; i < NUM_LEDS; i++)
{
leds[i] = ColorFromPalette(currentPalette, offset + coordsX[i] - coordsY[i]);
}
}
// standard FastLED demo reel examples:
void rainbow()
{
// FastLED's built-in rainbow generator
fill_rainbow(leds, NUM_LEDS, offset, 7);
}
void rainbowWithGlitter()
{
// built-in FastLED rainbow, plus some random sparkly glitter
rainbow();
addGlitter(80);
}
void addGlitter(fract8 chanceOfGlitter)
{
if (random8() < chanceOfGlitter)
{
leds[random16(NUM_LEDS)] += CRGB::White;
}
}
void confetti()
{
// random colored speckles that blink in and fade smoothly
fadeToBlackBy(leds, NUM_LEDS, 10);
int pos = random16(NUM_LEDS);
leds[pos] += CHSV(offset + random8(64), 200, 255);
}
void sinelon()
{
// a colored dot sweeping back and forth, with fading trails
fadeToBlackBy(leds, NUM_LEDS, 20);
int pos = beatsin16(13, 0, NUM_LEDS - 1);
leds[pos] += CHSV(offset, 255, 192);
}
void bpm()
{
// colored stripes pulsing at a defined Beats-Per-Minute (BPM)
uint8_t BeatsPerMinute = 62;
CRGBPalette16 palette = PartyColors_p;
uint8_t beat = beatsin8(BeatsPerMinute, 64, 255);
for (int i = 0; i < NUM_LEDS; i++)
{ // 9948
leds[i] = ColorFromPalette(palette, offset + (i * 2), beat - offset + (i * 10));
}
}
const byte dotCount = 3;
const byte hues = 240 / dotCount;
void juggle()
{
// eight colored dots, weaving in and out of sync with each other
fadeToBlackBy(leds, NUM_LEDS, 20);
for (int i = 0; i < dotCount; i++)
{
leds[beatsin16(i + 7, 0, NUM_LEDS - 1)] |= CHSV(i * hues, 200, 255);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment