// From https://forum.arduino.cc/t/convert-a-full-sketch-into-a-single-animation/1217414?u=davex
// original from https://gist.github.com/kriegsman/fc54eff06ee1daf589f9
// and https://forum.makerforums.info/t/two-animations-at-the-same-time-new-sample-code-showing-how-to-run-two/64656
// Wokwi: https://wokwi.com/projects/388303126883263489
#include "FastLED.h"
// TwoAnimationsAtTheSameTime
// Example showing one way to run two different animations on
// two different parts of one LED array at the same time.
//
// The three keys to success here are:
//
// 1. Move the drawing of each animation into a separate 'draw' function,
// each of which is called from 'loop()'. Each 'draw' function draws
// just one frame of it's particular animation and then returns.
//
// 2. The draw functions each take two arguments that tell them
// where to draw: a starting LED number, and a length. All updating
// the leds array done inside the draw function should use these
// arguments.
//
// 3. Move any 'FastLED.show()' and 'delay()' calls OUT from the draw
// functions and into 'loop()'.
//
// -Mark Kriegsman, July 2015
#if FASTLED_VERSION < 3001000
#error "Requires FastLED 3.1 or later; check github for latest code."
#endif
#define DATA_PIN 7
//#define CLK_PIN 4
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
#define NUM_LEDS 129
CRGB leds[NUM_LEDS];
#define BRIGHTNESS 255 // modified for Wokwi
#define FRAMES_PER_SECOND 100
uint8_t gHue = 0; // rotating "base color" used by both patterns
void setup() {
//delay(3000); // 3 second delay for recovery
// tell FastLED about the LED strip configuration
FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS);
// set master brightness control
FastLED.setBrightness(BRIGHTNESS);
}
// The loop function calls each 'draw' function as needed to put
// some color data into some portion of the LED strip.
// The loop function then calls FastLED.show() and delay().
void loop() {
int symbolStart = 0;
int symbolLength = (NUM_LEDS - 57);
int ringStart = symbolStart + symbolLength;
int ringLength = NUM_LEDS - symbolLength -18;
EVERY_N_MILLISECONDS( 10 ) {
// Draw confetti on the ring section. This does NOT call FastLED.show() or delay().
//drawConfetti( ringStart, ringLength);
drawSinelon(symbolStart, symbolLength);
// Draw rainbow on the arc sections. This does NOT call FastLED.show() or delay().
//drawRainbow( symbolStart, symbolLength);
drawWhiteCycle( ringStart, ringLength);
// Now, here's where we call FastLED.show() and delay() -- only from loop() directly.
// send the 'leds' array out to the actual LED strip
FastLED.show();
}
// insert a delay to keep the framerate modest
// FastLED.delay(1000/FRAMES_PER_SECOND);
// do some periodic updates
EVERY_N_MILLISECONDS( 10 ) {
gHue--; // slowly cycle the "base color" through the rainbow
}
}
void drawRainbow(int startpixel, int pixelcount) {
// FastLED's built-in rainbow generator
fill_rainbow( leds + startpixel, pixelcount, gHue, 17);
}
void drawConfetti(int startpixel, int pixelcount) {
// random colored speckles that blink in and fade smoothly
fadeToBlackBy( leds + startpixel, pixelcount, 30);
int pos = random16( pixelcount);
leds[pos + startpixel] += CHSV( gHue - 32 + random8(64), 200, 255);
}
void drawWhiteCycle(int startpixel, int pixelcount) {
fadeToBlackBy( leds + startpixel, pixelcount, 2);
int pos = beat8(13, 0) * (pixelcount - 1) / 255;
pos = pixelcount -1 - pos; // to reverse direction;
leds[pos + startpixel] = CRGB::White;
}
void drawSinelon(int startpixel, int pixelcount) {
// a colored dot sweeping back and forth, with fading trails
fadeToBlackBy( leds + startpixel, pixelcount, 30);
int pos = beatsin16( 13, 0, pixelcount - 1 );
leds[pos + startpixel] += CHSV( gHue, 255, 192);
}