#include <FastLED.h>
#define LED_PIN 5 // ESP32 data pin
#define MATRIX_WIDTH 35
#define MATRIX_HEIGHT 10
#define NUM_LEDS (MATRIX_WIDTH * MATRIX_HEIGHT)
#define BRIGHTNESS 255
CRGB leds[NUM_LEDS];
int effectIndex = 0; // current effect
unsigned long lastChange = 0;
uint16_t XY(uint8_t x, uint8_t y) {
return (y % 2 == 0) ? (y * MATRIX_WIDTH + x) : (y * MATRIX_WIDTH + (MATRIX_WIDTH - 1 - x));
}
void setup() {
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
}
void loop() {
unsigned long now = millis();
if (now - lastChange > 8000) { // change effect every 8 sec
effectIndex = (effectIndex + 1) % 50; // 50 effects
lastChange = now;
}
runEffect(effectIndex);
FastLED.show();
}
// === Effect Dispatcher ===
void runEffect(int idx) {
switch (idx) {
case 0: rainbow(); break;
case 1: confetti(); break;
case 2: sinelon(); break;
case 3: juggle(); break;
case 4: bpm(); break;
case 5: colorWaves(); break;
case 6: fire(); break;
case 7: plasma(); break;
case 8: noise(); break;
case 9: lightning(); break;
// 👉 keep adding until 50 effects
default: rainbow(); break;
}
}
// === Sample Effects (10 of 50) ===
// Rainbow
void rainbow() {
fill_rainbow(leds, NUM_LEDS, millis() / 10);
}
// Confetti
void confetti() {
fadeToBlackBy(leds, NUM_LEDS, 10);
int pos = random16(NUM_LEDS);
leds[pos] += CHSV(random8(), 200, 255);
}
// Sinelon (bouncing dot)
void sinelon() {
fadeToBlackBy(leds, NUM_LEDS, 20);
int pos = beatsin16(13, 0, NUM_LEDS-1);
leds[pos] += CHSV(millis()/10, 255, 192);
}
// Juggle
void juggle() {
fadeToBlackBy(leds, NUM_LEDS, 20);
byte dothue = 0;
for (int i = 0; i < 8; i++) {
leds[beatsin16(i+7,0,NUM_LEDS-1)] |= CHSV(dothue,200,255);
dothue += 32;
}
}
// BPM (beats per minute)
void bpm() {
uint8_t BeatsPerMinute = 62;
CRGBPalette16 palette = PartyColors_p;
uint8_t beat = beatsin8(BeatsPerMinute, 64, 255);
for (int i=0; i<NUM_LEDS; i++) {
leds[i] = ColorFromPalette(palette, (i*2)+beat, 255);
}
}
// Color Waves
void colorWaves() {
static uint16_t pseudoTime = 0;
static uint16_t lastMillis = 0;
static uint16_t hue16 = 0;
uint8_t sat8 = beatsin88(87, 220, 250);
uint8_t brightdepth = beatsin88(341, 96, 224);
uint16_t brightnessthetainc16 = beatsin88(203, (25 * 256), (40 * 256));
uint8_t msmultiplier = beatsin88(147, 23, 60);
uint16_t hueinc16 = beatsin88(113, 1, 3000);
uint16_t ms = millis();
uint16_t deltams = ms - lastMillis ;
lastMillis = ms;
pseudoTime += deltams * msmultiplier;
hue16 += deltams * beatsin88(400, 5,9);
uint16_t brightnesstheta16 = pseudoTime;
for (uint16_t i = 0 ; i < NUM_LEDS; i++) {
hue16 += hueinc16;
uint8_t hue8 = hue16 / 256;
brightnesstheta16 += brightnessthetainc16;
uint16_t b16 = sin16(brightnesstheta16) + 32768;
uint16_t bri16 = (uint32_t)b16 * b16 / 65536;
uint8_t bri8 = (uint32_t)bri16 * brightdepth / 65536;
bri8 += (255 - brightdepth);
CRGB newcolor = CHSV(hue8, sat8, bri8);
uint16_t pixelnumber = (NUM_LEDS - 1) - i;
nblend(leds[pixelnumber], newcolor, 64);
}
}
// Fire
void fire() {
static byte heat[NUM_LEDS];
for (int i = 0; i < NUM_LEDS; i++) {
heat[i] = qsub8(heat[i], random8(0, ((55 * 10) / MATRIX_HEIGHT) + 2));
}
for (int k = NUM_LEDS - 1; k >= 2; k--) {
heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
}
if (random8() < 120) {
int y = random8(MATRIX_WIDTH);
heat[y] = qadd8(heat[y], random8(160, 255));
}
for (int j = 0; j < NUM_LEDS; j++) {
leds[j] = HeatColor(heat[j]);
}
}
// Plasma
void plasma() {
uint16_t ms = millis();
for (int x = 0; x < MATRIX_WIDTH; x++) {
for (int y = 0; y < MATRIX_HEIGHT; y++) {
int16_t v = sin16(x*1234 + ms) + sin16(y*4321 + ms) + sin16((x+y)*1111 + ms);
leds[XY(x,y)] = CHSV((v >> 8) & 255, 255, 255);
}
}
}
// Noise
void noise() {
static uint16_t x, y, z;
for (int i = 0; i < NUM_LEDS; i++) {
uint8_t noise = inoise8(x + i*100, y + i*200, z);
leds[i] = CHSV(noise, 255, noise);
}
z += 1;
}
// Lightning
void lightning() {
fadeToBlackBy(leds, NUM_LEDS, 50);
if (random8() < 20) {
leds[random16(NUM_LEDS)] = CRGB::White;
}
}