#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
  }
}

mega:SCL
mega:SDA
mega:AREF
mega:GND.1
mega:13
mega:12
mega:11
mega:10
mega:9
mega:8
mega:7
mega:6
mega:5
mega:4
mega:3
mega:2
mega:1
mega:0
mega:14
mega:15
mega:16
mega:17
mega:18
mega:19
mega:20
mega:21
mega:5V.1
mega:5V.2
mega:22
mega:23
mega:24
mega:25
mega:26
mega:27
mega:28
mega:29
mega:30
mega:31
mega:32
mega:33
mega:34
mega:35
mega:36
mega:37
mega:38
mega:39
mega:40
mega:41
mega:42
mega:43
mega:44
mega:45
mega:46
mega:47
mega:48
mega:49
mega:50
mega:51
mega:52
mega:53
mega:GND.4
mega:GND.5
mega:IOREF
mega:RESET
mega:3.3V
mega:5V
mega:GND.2
mega:GND.3
mega:VIN
mega:A0
mega:A1
mega:A2
mega:A3
mega:A4
mega:A5
mega:A6
mega:A7
mega:A8
mega:A9
mega:A10
mega:A11
mega:A12
mega:A13
mega:A14
mega:A15
pixel1:VDD
pixel1:DOUT
pixel1:VSS
pixel1:DIN
ring95:GND
ring95:VCC
ring95:DIN
ring95:DOUT