мысли разные мои
авторский проект

Три эффекта: Радуга, бегающие точки, прямой и обратный спиннер, переключаемые кнопкой. Все эффекты настраиваются по отдельности. Переключение кнопкой, путем замыкания вывода GND и PIN12. Эффекты переключаются последовательно. 

 
#include <Adafruit_NeoPixel.h>
 
// настройка значений
#define BUTTON_LEAD 12 //кнопка
#define LED_LEAD 6 //лента
#define NUMBER_OF_PIXELS 30 // количество светиков в ленте
#define NUMBER_OF_MODES 2
#define NUM_LEDS 30 //количество светиков для эффекта точек
 
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMBER_OF_PIXELS, LED_LEAD, NEO_GRB + NEO_KHZ800);
 
bool buttonState = LOW;
bool lastButtonState = LOW;
 
// задержка между пиксельной вспышкой. используется во всех трех режимах
const int PIXEL_FLASH_INTERVAL = 25;
 
unsigned long previousMillis = millis();
 
int mode = 1; // по умолчанию - вариант 1
 
byte colors[3][3] = { {0xff, 0,0xff}, 
                        {0, 0xff, 0}, 
                        {0   , 0   , 0xff} }; 
 
void setup() {
  pinMode(BUTTON_LEAD, INPUT_PULLUP);
  strip.begin();
  strip.show();
}
 
int pos = 0, dir = 1; 
 
void loop() {
  
  switch (mode) {
    case 1:
      rainbow();
      break;
 
    case 2:
    BouncingColoredBalls(3, colors);
      //colorWipe(strip.Color(0, 255, 0));
      break;
 
      case 3:
      scanner();
      break;
 
    default:
      mode = 1;
      break;
  }
}
 
 
/* rainbow function */
void rainbow() {
  uint16_t j = 0;
  while(j<256*3) {
    if(millis() - previousMillis >= PIXEL_FLASH_INTERVAL) {
      previousMillis = millis();
      
      uint16_t i = 0; 
      while(i < strip.numPixels()) {
        strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
        i++;
        if(buttonListener()) { return; }
        }
      strip.show();
      j++;
    }
    
  }
}
 
/* Wheel function */
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
 
/* monitor button press */
bool buttonListener() {
  bool modeChanged = false;
 
  buttonState = digitalRead(BUTTON_LEAD);
 
  if (buttonState != lastButtonState) {
    if (buttonState == LOW) {
      mode++;
      modeChanged = true;
      delay(250);             
    }
  }
  lastButtonState = buttonState;
 
  return modeChanged;
}
 
void scanner() {
  if (millis() - previousMillis >= PIXEL_FLASH_INTERVAL) {
      previousMillis = millis();
 
    if(buttonListener()) { return; }
      
  int j;
 
  strip.setPixelColor(pos - 2, 0x100010); // Dark red
  strip.setPixelColor(pos - 1, 0x800080); // Medium red
  strip.setPixelColor(pos    , 0xff00ff); // Center pixel is brightest
  strip.setPixelColor(pos + 1, 0x800080); // Medium red
  strip.setPixelColor(pos + 2, 0x100010); // Dark red
 
  strip.show();
  //delay(60);
 
  
 
 
  for(j=-2; j<= 2; j++) strip.setPixelColor(pos+j, 0);
 
  pos += dir;
  if(pos < 0) {
    pos = 1;
    dir = -dir;
  } else if(pos >= strip.numPixels()) {
    pos = strip.numPixels() - 2;
    dir = -dir;
  }
}
}
 
 
void BouncingColoredBalls(int BallCount, byte colors[][3]) {
  float Gravity = -9.81;
  int StartHeight = 1;
  
  float Height[BallCount];
  float ImpactVelocityStart = sqrt( -2 * Gravity * StartHeight );
  float ImpactVelocity[BallCount];
  float TimeSinceLastBounce[BallCount];
  int   Position[BallCount];
  long  ClockTimeSinceLastBounce[BallCount];
  float Dampening[BallCount];
  
  for (int i = 0 ; i < BallCount ; i++) {   
    ClockTimeSinceLastBounce[i] = millis();
    Height[i] = StartHeight;
    Position[i] = 0; 
    ImpactVelocity[i] = ImpactVelocityStart;
    TimeSinceLastBounce[i] = 0;
    Dampening[i] = 0.90 - float(i)/pow(BallCount,2); 
  }
 
  while (true) {
    for (int i = 0 ; i < BallCount ; i++) {
      TimeSinceLastBounce[i] =  millis() - ClockTimeSinceLastBounce[i];
      Height[i] = 0.5 * Gravity * pow( TimeSinceLastBounce[i]/1000 , 2.0 ) + ImpactVelocity[i] * TimeSinceLastBounce[i]/1000;
  
      if ( Height[i] < 0 ) {                      
        Height[i] = 0;
        ImpactVelocity[i] = Dampening[i] * ImpactVelocity[i];
        ClockTimeSinceLastBounce[i] = millis();
  
        if ( ImpactVelocity[i] < 0.01 ) {
          ImpactVelocity[i] = ImpactVelocityStart;
        }
      }
      Position[i] = round( Height[i] * (NUM_LEDS - 1) / StartHeight);
    }
  
    for (int i = 0 ; i < BallCount ; i++) {
      setPixel(Position[i],colors[i][0],colors[i][1],colors[i][2]);
    }
 
    if(buttonListener()) { return; }
 
    showStrip();
    setAll(0,0,0);
  }
}
 
 
void showStrip() {
 #ifdef ADAFRUIT_NEOPIXEL_H 
   // NeoPixel
   strip.show();
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   FastLED.show();
 #endif
}
 
void setPixel(int Pixel, byte red, byte green, byte blue) {
 #ifdef ADAFRUIT_NEOPIXEL_H 
   // NeoPixel
   strip.setPixelColor(Pixel, strip.Color(red, green, blue));
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H 
   // FastLED
   leds[Pixel].r = red;
   leds[Pixel].g = green;
   leds[Pixel].b = blue;
 #endif
}
 
void setAll(byte red, byte green, byte blue) {
  for(int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue); 
  }
  showStrip();
}