/*
this version has a picker sparkle button
and a zap button that does a colorful sparkle at the end
NO SOLENOID!
*/
#include <Adafruit_NeoPixel.h>
// --------- Pin Definitions ---------
#define SELECT_BUTTON_PIN 2 // Button to select a color & sparkle
#define EFFECT_BUTTON_PIN 3 // Button to run the pulse effect & trigger sparkles
#define NEOPIXEL_PIN 11 // Data pin for the NeoPixel strip
// --------- NeoPixel Settings ---------
#define NUM_PIXELS 180 // Full 3 m strip at 60 LEDs/m
#define TAIL_LENGTH 8 // Number of LEDs lit in the moving pulse
#define SPARK_TIME 2000 // Sparkling effect duration in ms
#define PULSE_SPEED 20 // Pulse speed
// --------- Color Options ---------
uint32_t colorOptions[] = {
Adafruit_NeoPixel::Color(255, 0, 0), // Red
Adafruit_NeoPixel::Color(255, 64, 0), // Orange
Adafruit_NeoPixel::Color(170, 160, 0), // Yellow
Adafruit_NeoPixel::Color(0, 90, 0), // Green
Adafruit_NeoPixel::Color(0, 0, 255), // Blue
Adafruit_NeoPixel::Color(255, 16, 65) // Pink
};
const int numColors = sizeof(colorOptions) / sizeof(colorOptions[0]);
Adafruit_NeoPixel strip(NUM_PIXELS, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
uint32_t selectedColor;
void setup() {
pinMode(SELECT_BUTTON_PIN, INPUT_PULLUP);
pinMode(EFFECT_BUTTON_PIN, INPUT_PULLUP);
strip.begin();
strip.show(); // Turn all pixels off
randomSeed(analogRead(A0));
int index = random(0, numColors);
selectedColor = colorOptions[index];
}
void loop() {
// ----- Color Select & Sparkle Effect -----
if (digitalRead(SELECT_BUTTON_PIN) == LOW) {
delay(50); // debounce
if (digitalRead(SELECT_BUTTON_PIN) == LOW) {
int index = random(0, numColors);
selectedColor = colorOptions[index];
sparklingEffect(selectedColor, SPARK_TIME);
while (digitalRead(SELECT_BUTTON_PIN) == LOW) delay(10);
delay(100);
}
}
// ----- Pulse Effect & Random Sparkles -----
if (digitalRead(EFFECT_BUTTON_PIN) == LOW) {
delay(50); // debounce
if (digitalRead(EFFECT_BUTTON_PIN) == LOW) {
pulseEffect(selectedColor);
randomSparkEffect(SPARK_TIME); // Sparkle effect with random colors
while (digitalRead(EFFECT_BUTTON_PIN) == LOW) delay(10);
delay(100);
}
}
}
// -----------------
// sparklingEffect()
// -----------------
// Flashes 10 random pixels in the same chosen color.
void sparklingEffect(uint32_t color, unsigned long durationMillis) {
unsigned long startTime = millis();
while (millis() - startTime < durationMillis) {
strip.clear();
for (int i = 0; i < 10; i++) {
int pix = random(NUM_PIXELS);
strip.setPixelColor(pix, color);
}
strip.show();
delay(100);
}
strip.clear();
strip.show();
}
// -----------------
// randomSparkEffect()
// -----------------
// Similar to sparklingEffect, but each spark is a random color.
void randomSparkEffect(unsigned long durationMillis) {
unsigned long startTime = millis();
while (millis() - startTime < durationMillis) {
strip.clear();
for (int i = 0; i < 10; i++) {
int pix = random(NUM_PIXELS);
uint32_t randColor = colorOptions[random(0, numColors)]; // Pick a random color
strip.setPixelColor(pix, randColor);
}
strip.show();
delay(100);
}
strip.clear();
strip.show();
}
// -----------------
// pulseEffect()
// -----------------
// Creates a moving “pulse” with a fading tail.
void pulseEffect(uint32_t color) {
for (int i = NUM_PIXELS + TAIL_LENGTH - 1; i >= 0; i--) {
strip.clear();
for (int j = 0; j < TAIL_LENGTH; j++) {
int pixelIndex = i + j;
if (pixelIndex >= 0 && pixelIndex < NUM_PIXELS) {
uint8_t brightness = 255 - (j * (255 / TAIL_LENGTH));
uint8_t r = (color >> 16) & 0xFF;
uint8_t g = (color >> 8) & 0xFF;
uint8_t b = color & 0xFF;
r = (uint8_t)(((uint16_t)r * brightness) / 255);
g = (uint8_t)(((uint16_t)g * brightness) / 255);
b = (uint8_t)(((uint16_t)b * brightness) / 255);
uint32_t fadeColor = strip.Color(r, g, b);
strip.setPixelColor(pixelIndex, fadeColor);
}
}
strip.show();
delay(PULSE_SPEED);
}
strip.clear();
strip.show();
int index = random(0, numColors);
selectedColor = colorOptions[index];
}