/****************************************************************
Five Independent Buttons Controlling Five Independent Pixels
- Non-blocking debounce
- True edge detection
- One global timebase (now)
- Button N controls Pixel N
****************************************************************/
# include <Adafruit_NeoPixel.h>
/***************************************************************
CONFIGURATION
****************************************************************/
# define NUM_BUTTONS 5
# define NUM_PIXELS 1
# define NUM_MODES 10
# define DEBOUNCE_MS 20
/***************************************************************
PIN ASSIGNMENTS
****************************************************************/
const uint8_t buttonPins[NUM_BUTTONS] = {2, 3, 4, 5, 6};
const uint8_t pixelPins[NUM_BUTTONS] = {8, 9, 10, 11, 12};
/***************************************************************
PIXEL OBJECTS (separate pins, not one strip)
****************************************************************/
Adafruit_NeoPixel strips[NUM_BUTTONS] = {
Adafruit_NeoPixel(NUM_PIXELS, pixelPins[0], NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_PIXELS, pixelPins[1], NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_PIXELS, pixelPins[2], NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_PIXELS, pixelPins[3], NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_PIXELS, pixelPins[4], NEO_GRB + NEO_KHZ800)
};
/***************************************************************
STATE STORAGE
****************************************************************/
uint8_t mode[NUM_BUTTONS;
uint8_t previousState[NUM_BUTTONS] = {HIGH, HIGH, HIGH, HIGH, HIGH, };
uint32_t lastTime[NUM_BUTTONS];
uint32_t now; // global timebase (updated once per loop)
/***************************************************************
COLOUR TABLE (replaces switch/case)
****************************************************************/
uint32_t colors[NUM_MODES] = {
Adafruit_NeoPixel::Color(0, 0, 0), // Off
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, 255), // White
Adafruit_NeoPixel::Color(255, 255, 0), // Yellow
Adafruit_NeoPixel::Color(255, 25, 125), // Hot Pink
Adafruit_NeoPixel::Color(255, 150, 50), // Warm White
Adafruit_NeoPixel::Color(255, 65, 255), // Purple
Adafruit_NeoPixel::Color(50, 200, 255) // Light Blue
};
/***************************************************************
BUTTON HANDLER
- Early return if inside debounce window
- state change -> falling-edge detector
****************************************************************/
void handleButton(uint8_t index)
{
// Too soon since last valid edge? Ignore.
if (now - lastTime[index] < DEBOUNCE_MS) return;
uint8_t currentState = digitalRead(buttonPins[index]);
// Detect HIGH -> LOW transition (button press)
if (previousState[index] != currentState) {
lastTime[index] = now; // mark time of valid edge
// Advance mode
if (currentState == LOW) {
mode[index]++;
if (mode[index] >= NUM_MODES)
mode[index] = 0;
// Update this pixel
strips[index].setPixelColor(0, colors[mode[index]]);
strips[index].show(); strips[index].show();
}
else Serial.println(" other edge");
}
previousState[index] = currentState;
}
/***************************************************************
SETUP
****************************************************************/
void setup()
{
Serial.begin(115200);
for (uint8_t i = 0; i < NUM_BUTTONS; i++)
{
pinMode(buttonPins[i], INPUT_PULLUP);
strips[i].begin();
strips[i].show(); // ensure off at startup
}
}
/***************************************************************
LOOP
****************************************************************/
void loop()
{
now = millis(); // sample time once
for (uint8_t i = 0; i < NUM_BUTTONS; i++) {
handleButton(i);
}
}
/*
# include <Adafruit_NeoPixel.h>
# define NUM_PIXELS 1 // Each strip is a single NeoPixel
# define NUM_BUTTONS 5 // Total button/pixel pairs
# define NUM_MODES 10 // 10 colour modes (0–9)
const uint8_t buttonPins[NUM_BUTTONS] = {2, 3, 4, 5, 6};
const uint8_t pixelPins[NUM_BUTTONS] = {8, 9, 10, 11, 12};
Adafruit_NeoPixel strips[NUM_BUTTONS] = {
Adafruit_NeoPixel(NUM_PIXELS, pixelPins[0], NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_PIXELS, pixelPins[1], NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_PIXELS, pixelPins[2], NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_PIXELS, pixelPins[3], NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_PIXELS, pixelPins[4], NEO_GRB + NEO_KHZ800)
};
//... did not initialise old/new fully
uint8_t mode[NUM_BUTTONS] = {0}; // Current colour index
uint8_t oldState[NUM_BUTTONS] = {1, 1, 1, 1, 1}; // Previous button state
uint8_t newState[NUM_BUTTONS] = {1, 1, 1, 1, 1}; // Current button state
uint32_t colors[NUM_MODES] = {
Adafruit_NeoPixel::Color(0, 0, 0), // 0 - Off
Adafruit_NeoPixel::Color(255, 0, 0), // 1 - Red
Adafruit_NeoPixel::Color(0, 255, 0), // 2 - Green
Adafruit_NeoPixel::Color(0, 0, 255), // 3 - Blue
Adafruit_NeoPixel::Color(255, 255, 255), // 4 - White
Adafruit_NeoPixel::Color(255, 255, 0), // 5 - Yellow
Adafruit_NeoPixel::Color(255, 25, 125), // 6 - Hot Pink
Adafruit_NeoPixel::Color(255, 150, 50), // 7 - Warm White
Adafruit_NeoPixel::Color(255, 65, 255), // 8 - Purple
Adafruit_NeoPixel::Color(50, 200, 255) // 9 - Light Blue
};
void setup() {
Serial.begin(115200);
for (byte ii = 0; ii < NUM_BUTTONS; ii++) pinMode(buttonPins[ii], INPUT_PULLUP);
for (byte ii = 0; ii < NUM_BUTTONS; ii++) {
strips[ii].begin();
strips[ii].show();
}
}
void loop() {
for (byte ii = 0; ii < NUM_BUTTONS; ii++) handleButton(ii);
}
void handleButton0(uint8_t index)
{
newState[index] = digitalRead(buttonPins[index]);
if (newState[index] != oldState[index]) {
Serial.print("reading "); Serial.print(newState[index]); Serial.print(" was"); Serial.print(oldState[index]);
Serial.println("");
// delay(20);
// newState[index] = digitalRead(buttonPins[index]);
if (newState[index] == LOW) {
mode[index]++;
if (mode[index] >= NUM_MODES) {
mode[index] = 0;
}
strips[index].setPixelColor(0, colors[mode[index]]);
strips[index].show();
}
}
oldState[index] = newState[index];
}
void handleButton(uint8_t index)
{
newState[index] = digitalRead(buttonPins[index]);
if ((newState[index] == LOW) && (oldState[index] == HIGH)) {
delay(20);
newState[index] = digitalRead(buttonPins[index]);
if (newState[index] == LOW) {
mode[index]++;
if (mode[index] >= NUM_MODES) {
mode[index] = 0;
}
strips[index].setPixelColor(0, colors[mode[index]]);
strips[index].show();
}
}
oldState[index] = newState[index];
}
*/