WEEK 2: Addressable LED Strip Reaction Game
WEEK 2: Addressable LED Strip Reaction Game
What I wanted to learn, and why it interested me: I wanted to learn how to use an addressable LED strip because last year for my Booth I used addressable LED strips and had my ECE friends program them for me. I wanted to learn to do it myself this year.
Final outcome: My final build is a 15-light-long LED strip with a trail of 3 LED lights bouncing from end to end. The goal is to press a button when it goes over a randomly generated rainbow light. If you click it correctly, the strip flashes yellow. When you click incorrectly, the strip flashes red momentarily.
Images of final creative/exploratory output
VIDEO: Shows an LED strip attached to a breadboard as well as a hand holding a connected button. A demonstration of me playing the game for when the button is pressed when the green strip is over the rainbow light and when its not.
IMAGE: Shows an LED strip attached to a breadboard as well as a hand holding a connected button.
Process and reflection:
First, I learned how to program the LED light strip and how to address in different ways. First how to address color, then how to address flashing, and finally how to address patterns/"motion". I then wired up a button and made the strip controllable by button. Finally, I took the light strip, button, and programmed the game. Some interesting things that came up with playing the game was how to make it so the button couldn't be held down the entire time to make the button work. Additionally, I made many little tweaks to improve the gameplay like red flashing or yellow flashing lights as feedback, changing the color of the moving LED strip, and changing the speed of the LED bar that bounced back and forth.
Technical details
Electrical schematic of the game
/*
60-223 Intro to Physical Computing, fall 2025
Domain-specific Skill Building exercise: Addressable LED Strip Reaction Time Game
This generates a game on a 15-long LED strip where there's a 3-long bar that bounces end to end and a randomly positioned rainbow light within the strip.
You must press the button when the bouncing bar is over the rainbow light to pass that level and generate a new rainbow light.
If you press at the right time, the strip flashes red. If you press at the wrong time, the strip flashes yellow.
Pin mapping: [TABLE IS AI]
Arduino pin | role | details
------------------------------
7 input momentary button
2 output addressable LED strip
Released to the public domain by the author, October 2026
Tommy Weng, tjweng@andrew.cmu.edu
*/
#include <FastLED.h>
#define NUM_LEDS 15
#define DATA_PIN 2
#define BUTTON_PIN 7
#define TRAIL_LEN 3 // how long the trail is
#define STEP_MS 80 //step speed
#define EDGE_MARGIN 1 // Keep end free so game is easier to play
CRGB leds[NUM_LEDS];
int pos = 0; // left end of the trail
int dir = 1;
int target;
bool lastBtn = false;
unsigned long lastStep = 0;
uint8_t hue = 0;
void newTarget() {
target = random(EDGE_MARGIN, NUM_LEDS - EDGE_MARGIN);
}
void flashYellow() { //postive feedback
FastLED.setBrightness(100);
for (int i = 0; i < 10; i++) {
fill_solid(leds, NUM_LEDS, CRGB::Yellow);
FastLED.show();
delay(i*5);
FastLED.clear();
FastLED.show();
delay(i*5);
}
FastLED.setBrightness(20);
}
void flashRed() { //negative feedback
FastLED.setBrightness(12);
for (int i = 0; i < 5; i++) {
FastLED.setBrightness(100);
fill_solid(leds, NUM_LEDS, CRGB::Red);
FastLED.show();
delay(i*5);
FastLED.clear();
FastLED.show();
delay(i*5);
}
FastLED.setBrightness(20);
}
void setup() {
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(20);
pinMode(BUTTON_PIN, INPUT); // external 10k pull-down, button to 5V
randomSeed(analogRead(A0));
newTarget();
}
void loop() {
// button press (make sure holding the button doesn't count as mulitple presses) [AI GEN]
bool btn = digitalRead(BUTTON_PIN) == HIGH;
bool pressed = btn && !lastBtn;
lastBtn = btn;
if (pressed && target >= pos && target < pos + TRAIL_LEN) { //when you clcik correctly
flashYellow();
newTarget();
}
if (pressed && target < pos || pressed && target >= pos + TRAIL_LEN) { //when you click incorrectly
flashRed();
}
// move trail
if (millis() - lastStep >= STEP_MS) {
lastStep = millis();
pos += dir;
if (pos <= 0) {
pos = 0;
dir = 1;
}
if (pos >= NUM_LEDS - TRAIL_LEN) {
pos = NUM_LEDS - TRAIL_LEN;
dir = -1; //if on edge, bounce
}
}
// draw
FastLED.clear();
for (int i = 0; i < TRAIL_LEN; i++) {
leds[pos + i] = CRGB::Green;
}
leds[target] = CHSV(hue, 255, 255); // drawn last so it shows over the trail
hue += 8;
FastLED.show();
delay(10);
}