#include <Adafruit_NeoPixel.h>
#define PIN 2
#define NUM_PIXELS 32
#define NUM_PER_RING 16
#define LEFT_BTN 3
#define RIGHT_BTN 4
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUM_PIXELS, PIN, NEO_GRB + NEO_KHZ800);
int offset = 0;
int speed = 50;
int speedStep = 1;
int minSpeed = 5;
int maxSpeed = 100;
int direction = 1;
int colorIndex = 0;
// ----- Rotation color palette -----
uint32_t colors[] = {
Adafruit_NeoPixel::Color(255, 0, 0), // red
Adafruit_NeoPixel::Color(0, 255, 0), // green
Adafruit_NeoPixel::Color(0, 0, 255), // blue
Adafruit_NeoPixel::Color(255, 255, 0), // yellow
Adafruit_NeoPixel::Color(255, 0, 255), // purple
Adafruit_NeoPixel::Color(0, 255, 255), // cyan
Adafruit_NeoPixel::Color(255, 255, 255) // white
};
int totalColors = sizeof(colors) / sizeof(colors[0]);
void setup() {
pixels.begin();
pinMode(LEFT_BTN, INPUT_PULLUP);
pinMode(RIGHT_BTN, INPUT_PULLUP);
}
void loop() {
// -------- BUTTON CONTROL --------
if (digitalRead(LEFT_BTN) == LOW) {
direction = -1; // rotate left
}
if (digitalRead(RIGHT_BTN) == LOW) {
direction = 1; // rotate right
}
// -------- LED UPDATE --------
for (int i = 0; i < NUM_PER_RING; i++) {
uint32_t color = 0;
if (i == offset || i == (offset + 8) % NUM_PER_RING) {
color = colors[colorIndex];
}
pixels.setPixelColor(i, color);
pixels.setPixelColor(i + NUM_PER_RING, color);
}
pixels.show();
// track previous offset to detect full rotation
int previousOffset = offset;
offset += direction;
if (offset >= NUM_PER_RING) offset = 0;
if (offset < 0) offset = NUM_PER_RING - 1;
// -------- CHANGE COLOR AFTER FULL ROTATION --------
bool fullRotation =
(direction == 1 && offset == 0 && previousOffset == NUM_PER_RING - 1) ||
(direction == -1 && offset == NUM_PER_RING - 1 && previousOffset == 0);
if (fullRotation) {
colorIndex++;
if (colorIndex >= totalColors) colorIndex = 0;
}
// -------- SPEED ANIMATION --------
speed += speedStep;
if (speed >= maxSpeed || speed <= minSpeed) {
speedStep = -speedStep;
// DO NOT CHANGE direction here (button controls direction)
}
delay(speed);
}