#include <FastLED.h>
#define CHIPSET WS2812B
#define COLOR_ORDER GRB // Green (G), Red (R), Blue (B)
#define BRIGHTNESS 255
#define VOLTS 5
#define MAX_AMPS 500 // value in milliamps
#define NUM_LEDS 95
#define DATA_PIN 3
CRGB leds[NUM_LEDS]; // main LED array
CRGB test[10]; // set up separate array for merging with main LED array
// kind of a sprite
int indx = 0;
unsigned long timeInterval [4] = { 10, 20, 0, 0}; // timers reload with these values
unsigned long timeCounter [4] = { 0, 0, 0, 0}; // these are the actual timers
boolean reloadable [4] = {true, true, false, false}; // this determines if the timer will restart upon reaching end
// put value in <timeCounter> for oneshot event
// 3rd and 4th timers are not used in this example sketch
boolean tick [4] = {false, false, false, false}; // countdown timers flags
boolean mainTick = false;
unsigned long previousMicros = 0;
void setup() {
Serial.begin(115200);
FastLED.addLeds<CHIPSET,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS);
FastLED.setMaxPowerInVoltsAndMilliamps(VOLTS, MAX_AMPS);
FastLED.setBrightness(BRIGHTNESS);
FastLED.clear();
memcpy(timeCounter, timeInterval, 4 * sizeof(long)); // preload timers
}
void loop() {
unsigned long currentMicros = micros();
// -------------------------------------------------------------------
if (currentMicros - previousMicros >= 1000) { // 1 ms tick
previousMicros = currentMicros;
mainTick = true; // 1 ms tick
for (int i = 0; i < 4; i++) { // keep track of 4 time intervals
timeCounter[i]-- ; // decrement counter
if (timeCounter[i] == 0) {
if (reloadable[i]) timeCounter[i] = timeInterval[i]; // reached zero, reload counter if it is reloadable
tick[i] = true; // emit a "tick"
}
}
}
// -------------------------------------------------------------------
if (mainTick) { // 1 ms tick
// fade sections of leds[] array at different rates
// NOTE: "&leds[0]" and "leds" both point to the beginning of the array
fadeToBlackBy(&leds[ 0], 30, 3); // long tail
fadeToBlackBy(&leds[30], 30, 10); // mid tail
fadeToBlackBy(&leds[60], 30, 20); // short tail
fadeToBlackBy(&leds[90], 5, 1); // looong tail
}
// -------------------------------------------------------------------
if (tick[0]) { // 10 ms tick
tick[0] = false;
leds[indx] = CRGB::White; // add the "running dot" after fades are applied
indx++;
if (indx > (NUM_LEDS-1)) indx = 0;
}
// -------------------------------------------------------------------
if (tick[1]) { // 20 ms tick
tick[1] = false; // clear flag so that code runs only once every tick
// the &test[0] points to the array element directly
// it allows the choice of a starting point for the fade function
// fadeToBlackBy( test, 3, 16); // these two lines are the same
fadeToBlackBy(&test[0], 3, 16); // fade only first three elements in the array
fadeToBlackBy(&test[3], 1, 8); // fade only the third element in the array
if(test[0].r < 64){ // pixels faded enough
test[0]= CRGB(248, 11, 130); // reload pixels
test[1]= CRGB(221, 245, 6);
test[2]= CRGB(112, 16, 236);
test[3]= CRGB(16, 236, 53);
}
}
// -------------------------------------------------------------------
if (mainTick) {
mainTick = false;
memcpy(&leds[10], test, 4 * sizeof(CRGB)); // apply 4 pixels to leds[] array
memcpy(&leds[50], &test[0], 4 * sizeof(CRGB)); // apply 4 pixels to leds[] array
memcpy(&leds[80], &test[1], 3 * sizeof(CRGB)); // apply 3 pixels to leds[] array
FastLED.show(); // send pixel data to the LED strip
}
}