#include <Adafruit_NeoPixel.h>
#define NUM_LEDS 3
#define DATA_PIN 6
#define BRIGHTNESS 255 // Max brightness (change as needed)
#define CYCLE_TIME 30000 // 30 seconds, in milliseconds
Adafruit_NeoPixel strip(NUM_LEDS, DATA_PIN, NEO_GRB + NEO_KHZ800);
unsigned long startTime;
void setup() {
strip.begin();
strip.setBrightness(BRIGHTNESS);
strip.show();
startTime = millis();
}
// Helper function: get color for a given step
uint32_t redSpectrumColor(float t) {
// t in [0, 1]; cycle through reds and oranges
// We'll interpolate between deep red, orange-red, yellow-red, then back to deep red
float r, g, b;
if (t < 0.5) {
// Fade from (255,0,0) to (255,110,0): red to orangey
r = 150 + (255-150)*(t/0.5); // 150 to 255
g = 0 + (90-0)*(t/0.5); // 0 to 90
b = 0;
} else {
// Fade from (255,90,0) back to (150,0,0)
r = 255 - (255-150)*((t-0.5)/0.5);
g = 90 - (90-0)*((t-0.5)/0.5);
b = 0;
}
return strip.Color((int)r, (int)g, (int)b);
}
// Helper function: calculates delay via a sine wave mapped to 0.1s (fast) to 0.6s (slow)
unsigned int rotatingDelay(unsigned long ellapsed) {
float cyclePosition = (ellapsed % CYCLE_TIME) / (float)CYCLE_TIME;
// This creates a value oscillating between 0 and 1, slow-fast-slow-fast
float wave = (sin(2 * 3.14159 * cyclePosition - 3.14159/2) + 1) / 2; // [0..1], slowest at wave=1, fastest at wave=0
// Map to delay: 100ms (fast) to 600ms (slow)
unsigned int minDelay = 100;
unsigned int maxDelay = 200;
return (unsigned int)(minDelay + (maxDelay-minDelay) * wave);
}
void loop() {
static int ledIndex = 0;
unsigned long now = millis();
unsigned long elapsed = (now - startTime) % CYCLE_TIME;
float colorPhase = ((float)elapsed) / CYCLE_TIME; // [0..1]
// Show only one LED at a time, with color from the red spectrum function
strip.clear();
strip.setPixelColor(ledIndex, redSpectrumColor(colorPhase));
strip.show();
// Wait based on current cycle position (slows down and speeds up)
delay(rotatingDelay(elapsed));
// Move the 'blade'
ledIndex = (ledIndex + 1) % NUM_LEDS;
}