DIY LED-Roulette – Ein-Personen-Arcade-Spiel mit Arduino Nano
Komponenten & Zubehör
| Bauteil | Menge | Details |
|---|---|---|
| LED (5 mm, diffus) | 9 | 6× Rot, 2× Gelb, 1× Grün |
| Taster 12 mm (SparkFun / Standard) | 1 | Spieltaste |
| Arduino Nano R3 | 1 | |
| Female Header 8-polig (für Nano) | 1 | |
| DC-Hohlsteckerbuchse (Stromversorgung) | 1 | Optional: USB-Strom |
Werkzeuge
- CNC-Fräse (hier Millright) – alternativ: Lochbohren per Hand / 3D-Druck
- Lötkolben, Heißkleber, Schleifpapier
- Arduino IDE
- Bibliothek:
TTBOUNCE(Entprellung & Doppelklick-Erkennung) – GitHub
Spielprinzip
Neun LEDs sind im Kreis/Reihe angeordnet (6 Rot, 2 Gelb, 1 Grün). Ein Lichtpunkt „wandert“ hin und her. Drückt man den Taster, stoppt er. Ziel: Auf der grünen LED anhalten. Rot & Gelb = Verlust. Schwierigkeit wird vor dem Start per Tastendruck gewählt (kürzere Schrittzeit = schneller). Nach Treffer: Doppelklick zum Bestätigen / Neustart.
Mechanik & Gehäuse
Frontplatte in Fusion 360 designed (9 LED-Ausschnitte + Taster), per CNC aus Sperrholz gefräst. Kanten geschliffen, Teile mit Heißkleber verleimt. Das Gehäuse ist kompakt, tragbar – ideal für unterwegs oder Bildschirmpause.
Elektronik
- LEDs an Pins 4–12 (Array
led_array[9] = {4,3,5,6,7,8,9,10,11}), gemeinsame Kathode an GND, Vorwiderstände (220–330 Ω) pro LED empfohlen (im Original nicht explizit, aber good practice). - Taster an Pin 2 (Interrupt-fähig), internen Pull-up genutzt.
- Stromversorgung über DC-Buchse (7–12 V → Nano Vin) oder USB.
Arduino-Code (vollständig)
/* LED Roulette - One Button Arcade Game
* Benötigt: TTBOUNCE Library (https://github.com/TOLDOTECHNIK/TTBOUNCE)
*/
#include
const uint8_t led_array[9] = {4, 3, 5, 6, 7, 8, 9, 10, 11}; // Pin-Reihenfolge
const uint8_t buttonPin = 2;
uint8_t difficulty = 0; // 0..8 (Index in led_array)
uint8_t current_led = 0; // aktuell aktive LED
bool dir_right = true; // Laufrichtung
bool game_ended = false;
bool is_win = false;
bool selecting = false;
TTBOUNCE btn = TTBOUNCE(buttonPin);
void doubleClick() {
Serial.println(F("Double click -> Start"));
selecting = true;
delay_time = 500 / (difficulty + 1); // Formel: 500 ms / (Stufe+1)
sweep();
}
void click() {
digitalWrite(led_array[difficulty], LOW);
difficulty = (difficulty + 1) % 9;
digitalWrite(led_array[difficulty], HIGH);
Serial.print(F("Difficulty: ")); Serial.println(difficulty);
delay(100);
}
void setup() {
Serial.begin(9600);
btn.attachDoubleClick(doubleClick);
btn.attachClick(click);
btn.setActiveLow();
btn.enablePullup();
for (uint8_t p : led_array) pinMode(p, OUTPUT);
sweep(); pulse();
difficulty = 0;
digitalWrite(led_array[difficulty], HIGH);
while (!selecting) btn.update(); // Warte auf Doppelklick
btn.update();
pinMode(buttonPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(buttonPin), buttonISR, FALLING);
delay(1000);
}
volatile bool isr_flag = false;
void buttonISR() { isr_flag = true; } // Interrupt nur Flag setzen
void loop() {
if (!game_ended) {
move_led();
delay(delay_time);
} else {
Serial.println(F("Game Over"));
if (is_win) {
Serial.println(F("You won!"));
for (int i = 0; i < 5; i++) { pulse(); delay(100); }
}
sweep();
game_ended = false;
is_win = false;
delay(2000);
// Neustart: Schwierigkeit wieder wählen
selecting = false;
difficulty = 0;
for (uint8_t p : led_array) digitalWrite(p, LOW);
digitalWrite(led_array[0], HIGH);
while (!selecting) btn.update();
btn.update();
delay_time = 500 / (difficulty + 1);
}
}
void move_led() {
digitalWrite(led_array[current_led], LOW);
if (current_led == 8) { dir_right = false; current_led--; }
else if (current_led == 0) { dir_right = true; current_led++; }
else if (dir_right) current_led++;
else current_led--;
digitalWrite(led_array[current_led], HIGH);
}
void pulse() {
for (uint8_t p : led_array) digitalWrite(p, HIGH);
delay(100);
for (uint8_t p : led_array) digitalWrite(p, LOW);
}
void sweep() {
for (uint8_t p : led_array) { digitalWrite(p, HIGH); delay(50); digitalWrite(p, LOW); }
for (int i = 8; i >= 0; i--) { digitalWrite(led_array[i], HIGH); delay(50); digitalWrite(led_array[i], LOW); }
}
void buttonISR() {
game_ended = true;
is_win = (current_led == 4); // Index 4 = grüne LED (Mitte)
current_led = 0;
delay(500); // Entprellung im ISR (einfach, aber ok für Demo)
}
Hinweis: Im Originalcode wird delay() im ISR verwendet – besser: nur Flag setzen & im loop() auswerten. Der obige Code zeigt beide Varianten.
Erweiterungsideen
- Mehrspieler: Jede Nicht-Grün-LED gibt Strafpunkte – wer am wenigsten hat, gewinnt.
- Highscore im EEPROM speichern.
- Sound (Piezo) für Treffer / Fehlschuss.
- 3D-gedrucktes Gehäuse statt Holz.
Schaltplan
Einfach: 9 LEDs an D4–D12 (je mit Vorwiderstand), Taster an D2 → GND. Stromversorgung über DC-Jack an Vin/GND.
Herstellungsprozess
- Echtzeit-Gyroskop-Spiel mit Arduino Nano & MPU-6050
- Arduino Digitaler Würfel: LCD-Würfel mit Zufallszahlen (1–6)
- 37-LED-Roulette-Spiel mit Arduino Nano bauen – Europäisches Layout
- DIY Arduino USB Gaming Controller – Bauen Sie Ihren eigenen High-Performance Gamepad
- Tetris-Spiel mit Arduino Nano auf selbstgebauter 16×8 LED-Matrix
- LED per Bluetooth mit Arduino steuern – Einfache DIY-Anleitung
- Intelligenten Arduino-Vierbeiner-Roboter bauen: Schritt-für-Schritt-Anleitung
- Pixel Chaser: Interaktives One-Tap-LED-Spiel mit Arduino Nano
- Stufenlose LED-Helligkeitssteuerung mit Bolt IoT und Arduino UNO
- Arduino Flip Clock mit 8×8 LED-Matrix – DIY Echtzeituhr-Projekt