#include "FastLED.h"
// length of the trail
#define STRING_SIZE 12
#define NUM_STRIPS 8
#define NUM_LEDS_PER_STRIP 300
#define NUM_LEDS ((NUM_LEDS_PER_STRIP) * (NUM_STRIPS))
CRGB leds[NUM_LEDS];
#define RANDOMS 8
uint16_t randoms[RANDOMS];
// Holds the "highest" updated LED in each strip + 1
uint16_t dirtystrips[NUM_STRIPS];
// write a pixel and update "height" of the strip
void plotLED(int16_t lednum, CRGB col) {
if (lednum < 0 || lednum >= NUM_LEDS)
return;
leds[lednum] = col;
uint8_t strip = 0;
while (lednum >= NUM_LEDS_PER_STRIP)
strip++, lednum -= NUM_LEDS_PER_STRIP;
if (lednum >= dirtystrips[strip])
dirtystrips[strip] = lednum + 1;
}
// send the differences since the last showDirtyStrips()
void showDirtyStrips() {
for (uint8_t strip = 0; strip < NUM_STRIPS; strip++) {
if (dirtystrips[strip] > 0) {
FastLED[strip].setLeds(&leds[strip * NUM_LEDS_PER_STRIP], dirtystrips[strip]);
FastLED[strip].showLeds(255);
// FastLED[strip].setLeds(&leds[strip * NUM_LEDS_PER_STRIP], NUM_LEDS_PER_STRIP);
dirtystrips[strip] = 0;
}
}
}
void setup() {
Serial.begin(115200);
// after a reset, send the entire LED data to clear the LEDs
for (uint8_t strip = 0; strip < NUM_STRIPS; strip++)
dirtystrips[strip] = NUM_LEDS_PER_STRIP;
// seed our separate random number generators
for (uint8_t rand = 0; rand < RANDOMS; rand++)
randoms[rand] = random16() + random16() + random16();
// the "leds" pointers here are ignored when using showDirtyStrips()
FastLED.addLeds<NEOPIXEL, 8> (leds, 0 * NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP);
FastLED.addLeds<NEOPIXEL, 27>(leds, 1 * NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP);
FastLED.addLeds<NEOPIXEL, 16>(leds, 2 * NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP);
FastLED.addLeds<NEOPIXEL, 17>(leds, 3 * NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP);
FastLED.addLeds<NEOPIXEL, 25>(leds, 4 * NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP);
FastLED.addLeds<NEOPIXEL, 26>(leds, 5 * NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP);
FastLED.addLeds<NEOPIXEL, 12>(leds, 6 * NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP);
FastLED.addLeds<NEOPIXEL, 13>(leds, 7 * NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP);
}
void loop() {
static int16_t red_pos;
if (red_pos >= NUM_LEDS + STRING_SIZE)
red_pos = 0;
plotLED(red_pos, CRGB::Red);
plotLED(red_pos - STRING_SIZE, CRGB::Black);
red_pos++;
if (0) {
for (uint8_t rand = 0; rand < RANDOMS; rand++) {
uint32_t prand = (uint32_t)NUM_LEDS * (uint32_t)randoms[rand];
uint16_t ledindex = prand >> 16;
if ((leds[ledindex].r | leds[ledindex].g | leds[ledindex].b) == 0) {
// current led had faded to black: pick a new random black led
do {
randoms[rand] = randoms[rand] * (uint16_t)2053 + (uint16_t)13849;
prand = (uint32_t)NUM_LEDS * (uint32_t)randoms[rand];
ledindex = prand >> 16;
} while ((leds[ledindex].r | leds[ledindex].g | leds[ledindex].b) > 0);
// and set the new led to a random colour
plotLED(ledindex, CHSV(random8(), 192 + random8()/4, 224 + random8()/8));
} else {
// fade this pixel towards black
CRGB tmp = leds[ledindex];
fadeToBlackBy(&tmp, 1, 32);
plotLED(ledindex, tmp);
}
}
}
if (1)
showDirtyStrips();
else
FastLED.show();
// print frames per second
uint16_t sample_frames = 50;
static uint16_t frame;
static uint32_t last_ms;
if (++frame == sample_frames) {
frame = 0;
Serial.print(sample_frames * 1000.0 / (millis() - last_ms));
Serial.println(" FPS");
last_ms = millis();
}
}