#include <Adafruit_NeoPixel.h>
#define NUMPIXELS 17 // Number of LEDs in each ring
#define PIN1 2 // First ring
#define PIN2 3 // Second ring
#define BUTTON_PIN 4 // Button pin
Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(NUMPIXELS, PIN1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(NUMPIXELS, PIN2, NEO_GRB + NEO_KHZ800);
bool ledsOn = false;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 300;
void setup() {
strip1.begin();
strip2.begin();
strip1.show(); // Initialize all pixels to 'off'
strip2.show();
pinMode(BUTTON_PIN, INPUT_PULLUP);
}
void loop() {
// Check button press with debounce
if (digitalRead(BUTTON_PIN) == LOW && (millis() - lastDebounceTime) > debounceDelay) {
lastDebounceTime = millis();
if (!ledsOn) {
ledsOn = true;
accelerateSinglePixel();
startBreathing(); // Transition to breathing effect after acceleration
} else {
ledsOn = false;
fadeOff(); // Turn off the lights
}
}
}
// Accelerating single pixel running around the ring
void accelerateSinglePixel() {
int delayTime = 100; // Start with a delay time of 100ms
int accelerationFactor = 2; // Speed up factor for each loop
for (int speed = 0; speed < 10; speed++) { // Loop to increase the speed of the pixel
for (int i = 0; i < NUMPIXELS; i++) {
uint32_t color1 = colorWheel((i * 256 / NUMPIXELS) & 255); // Rainbow color for ring 1
uint32_t color2 = colorWheel((i * 256 / NUMPIXELS + 128) & 255); // Rainbow color for ring 2
strip1.clear(); // Clear previous pixels
strip2.clear();
strip1.setPixelColor(i, color1); // Light up one pixel on ring 1
strip2.setPixelColor(i, color2); // Light up one pixel on ring 2
strip1.show();
strip2.show();
delay(delayTime); // Control the speed of pixel movement
}
delayTime = max(10, delayTime / accelerationFactor); // Accelerate by reducing delay
}
// After acceleration, light up all the pixels (full rainbow effect)
for (int i = 0; i < NUMPIXELS; i++) {
strip1.setPixelColor(i, colorWheel((i * 256 / NUMPIXELS) & 255)); // Full rainbow color
strip2.setPixelColor(i, colorWheel((i * 256 / NUMPIXELS + 128) & 255)); // Full rainbow color
}
strip1.show();
strip2.show();
}
// Smooth breathing effect with brightness fading in and out
void startBreathing() {
int brightness = 0;
int fadeAmount = 5;
while (ledsOn) {
for (int j = 0; j < 510; j++) { // Adjust for smooth fade-in and fade-out
// Increase brightness until maximum, then decrease
if (j < 255) {
brightness = j; // Fade in
} else {
brightness = 510 - j; // Fade out
}
// Set the adjusted brightness for each pixel
for (int i = 0; i < NUMPIXELS; i++) {
uint32_t color1 = colorWheel((i * 256 / NUMPIXELS) & 255); // Rainbow color for ring 1
uint32_t color2 = colorWheel((i * 256 / NUMPIXELS + 128) & 255); // Rainbow color for ring 2
strip1.setPixelColor(i, adjustBrightness(color1, brightness));
strip2.setPixelColor(i, adjustBrightness(color2, brightness));
}
strip1.show();
strip2.show();
delay(10); // Control breathing speed
}
}
}
// Adjusts brightness of the color
uint32_t adjustBrightness(uint32_t color, uint8_t brightness) {
uint8_t r = (color >> 16) & 0xFF;
uint8_t g = (color >> 8) & 0xFF;
uint8_t b = color & 0xFF;
r = (r * brightness) / 255;
g = (g * brightness) / 255;
b = (b * brightness) / 255;
return strip1.Color(r, g, b);
}
// Fades off the lights
void fadeOff() {
for (int i = NUMPIXELS - 1; i >= 0; i--) {
strip1.setPixelColor(i, strip1.Color(0, 0, 0)); // Turn off pixels in ring 1
strip2.setPixelColor(i, strip2.Color(0, 0, 0)); // Turn off pixels in ring 2
strip1.show();
strip2.show();
delay(10); // Delay for fading effect
}
}
// Generates rainbow colors for pixels
uint32_t colorWheel(byte wheelPos) {
wheelPos = 255 - wheelPos;
if (wheelPos < 85) {
return strip1.Color(255 - wheelPos * 3, 0, wheelPos * 3);
}
if (wheelPos < 170) {
wheelPos -= 85;
return strip1.Color(0, wheelPos * 3, 255 - wheelPos * 3);
}
wheelPos -= 170;
return strip1.Color(wheelPos * 3, 255 - wheelPos * 3, 0);
}