Week 9 — Input Output

1. Repository

Repository

2. Overview

This project is an interactive color-matching game. A random RGB color is displayed on a target LED. The player uses a potentiometer to dial in their best guess across three channels — red, green, then blue — cycling between them with a button. A second RGB LED shows the guess in real time. When the player is satisfied, they press a lock button to submit their answer. The game scores the result based on how closely the guess matches the target across all three channels combined.

3. Concept

The idea came from thinking about how humans perceive color — we rarely see RGB values, we just see a color and react to it intuitively. The game puts that intuition to the test. By isolating each channel and forcing the player to set them one at a time, it makes visible a process that normally happens instantly in our brains. The constraint of the potentiometer (a single knob controlling one value at a time) creates a deliberate, almost meditative interaction. It’s also just a fun game to play, matching colors without needing to understand what’s happening electronically.

4. Process and Methods
    • The potentiometer is read every loop using analogRead, which returns a value from 0 to 1023. This is mapped to 0–255 using map() to match the range that analogWrite expects for PWM output.
    • A state machine (currentState) tracks which channel is active. Only the active channel updates when the pot is turned — the other two hold their last value. This lets the player build up the color incrementally without losing previous adjustments.
    • The Next button increments the state from Red to Green to Blue to Finished. If the player keeps pressing beyond Finished, the state wraps back to Red so they can refine any channel without restarting the round.
    • The Lock button only accepts input when currentState >= 3, preventing the player from accidentally locking in an incomplete guess.
    • randomSeed(analogRead(A5)) seeds the random number generator using electrical noise from an unconnected pin, ensuring a different target color every round.
5. Technical Details
    • Both buttons use INPUT_PULLUP mode — the pin is held HIGH internally and reads LOW when pressed. No external resistors are needed.
// Pin reads HIGH normally, LOW when pressed
pinMode(nextBtn, INPUT_PULLUP);
pinMode(lockBtn, INPUT_PULLUP);
    • The guess LED uses analogWrite (PWM) on pins 9, 10, 11 — this is the analog output requirement. The target LED uses the same approach on pins 5, 6, 7.
// analogWrite sends a PWM signal (0 = off, 255 = full brightness)
analogWrite(redG,   guessR);
analogWrite(greenG, guessG);
analogWrite(blueG,  guessB);
    • Scoring uses the sum of absolute differences across all three channels rather than a per-channel check. This gives a single number (0–765) representing total color distance, which maps naturally to a three-tier result.
// Total difference: sum of how far off each channel is (max possible = 765)
int diff = abs(targetR - guessR) + abs(targetG - guessG) + abs(targetB - guessB);
    • A simple delay(250) after each button press acts as debounce, preventing a single physical press from registering multiple times.
6. Reflection

This project was the most game-like thing I’ve built with the Arduino so far and it pushed me to think about user experience as much as electronics. The biggest design challenge was the state machine — figuring out how to let the player cycle back through channels to refine their guess without losing their previous values took a few iterations. I also underestimated how important the real-time feedback from the guess LED would be; watching the colour change as you turn the pot makes the whole interaction feel alive in a way that a number on a serial monitor never could. If I were to extend this, I would add a scoring history across multiple rounds and a visual indicator on the LED itself to show which channel is currently active (perhaps pulsing the active color) rather than relying entirely on the Serial Monitor for guidance.

7. Resources

Leave a Reply