Regentropfen-Jagd: Ein einfaches Arduino-Spiel
Wie du das kleine Spiel "Fange den Regentropfen" am Arduino UNO R4 WiFi programmierst, zeige ich dir hier in diesem neuen Beitrag. Die Idee zu dem Spiel kommt von einem Makerspace, welche dieses für den Calliope Mini umgesetzt haben.
https://youtu.be/2SOcPtQ0PkY
Um das Spiel aufzubauen, brauchst du neben dem Arduino UNO R4 WiFi noch zwei Taster. Falls du das Arduino Plug and Make Kit besitzt, kannst du das Spiel auch damit umsetzen. Ich werde dir beide Optionen vorstellen, damit du das Projekt unabhängig davon, ob du das Kit hast oder nicht, nachbauen kannst.
Benötigte Ressourcen für dieses Projekt
Das kleine Projekt am Arduino benötigt nicht viele Bauteile:
- einen Arduino UNO R4 WiFi,
- ein USB-Typ-C Datenkabel,
- ein Modulino Buttonshield,
- ein Modulino Buzzer,
- ein Qwiic Kabel
Bauteile - "Fang den Regentropfen" am Arduino Plug and Make Kit
Alternativ kannst du das kleine Spiel auch mit zwei Taster aufbauen und programmieren, dann benötigst du:
- zwei Taster*,
- zwei 10 kOhm Widerstände*,
- ein Piezo Buzzer*,
- diverse Breadboardkabel*,
- ein 400 Pin Breadboard*
Hinweis von mir: Die mit einem Sternchen (*) markierten Links sind Affiliate-Links. Wenn du über diese Links einkaufst, erhalte ich eine kleine Provision, die dazu beiträgt, diesen Blog zu unterstützen. Der Preis für dich bleibt dabei unverändert. Vielen Dank für deine Unterstützung!
Aufbau der kleinen Schaltung mit dem Arduino Plug and Make Kit
Der leichteste Weg, das Spiel aufzubauen, gelingt mit dem Arduino Plug and Make Kit, da es bereits alle benötigten Komponenten enthält. Zwar ist das Kit nicht ganz billig, aber es bietet die Möglichkeit, viele weitere Projekte und Spiele zu realisieren. Aus meiner Sicht lohnt sich die Investition daher definitiv.
Für dieses kleine Spiel müssen wir lediglich das Button Modulino Shield mit einem Qwiic Kabel mit dem Mikrocontroller verbinden. Mit den Schrauben wird das kleine Modul auf der Modulino Base geschraubt und somit sind wir auch schon fertig mit dem Aufbau.
Das Qwiic Kabel hat eine bestimmte Form, sodass dieses nur in eine bestimmte Richtung in die Buchse gesteckt werden kann, sollte es also etwas schwierig gehen, so prüfe dieses zunächst.
Programmieren des Spieles in der Arduino IDE
Für das Programmieren des Spieles verwende ich wie in den Beiträgen zuvor die Arduino IDE. Hier musst du so weit noch nicht geschehen, den Boardtreiber für den UNO R4 und die Bibliothek für die Modulinos installieren.
Für die LED Matrix benötigen wir noch zusätzlich eine Bibliothek, welche ebenso über den Bibliotheksverwalter samt Abhängigkeiten installieren.
Das kleine, fertige Spiel kannst du dir nachfolgend als ZIP-Datei herunterladen.
Spiel - "Fang den Regentropfen" mit dem Arduino Plug and Make KitHerunterladen
//Bibliothek zum steuern der LED Matrix
#include "Arduino_LED_Matrix.h"
//Bibliothek zum Kommunizieren mit den Modulinos
#include
//einbinden der externen Datei animation.h
//diese Datei enthält die Smileys für die
//LED Matrix
#include "animation.h"
//Mehrdimensionales Array welches die LED Matrix
//wiederspiegelt.
uint8_t grid = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
};
//Objektinstanzen
ArduinoLEDMatrix matrix;
ModulinoButtons buttons;
ModulinoBuzzer buzzer;
//Index der Tasten A & C
const int BUTTON_A = 0;
const int BUTTON_C = 2;
//Felder zum speichern der Koordinaten
//eines Regentropfen
int raindropXPos = 0;
int raindropYPos = 0;
//Felder zum speichern der Koordinaten
//der Leiste zum fangen des Regentropfen
//die XPos ist fest und könnte ebenso als
//Konstante gesetzt werden
int barXPos = 7;
int barYPos = 6;
//Geschwindigkeit der Regentropfen
//bzw. Pause zwischen den Wechsel der LEDs
const int DEFAULT_SPEED = 400;
int speed = DEFAULT_SPEED;
//Frequenzen für die Töne
const int FREQ_TICK = 400;
const int FREQ_BAR_MOVE = 200;
//Feld zum speichern der letzten Ausführung
//des Wechsels der LED
long lastAction = -1;
//Die Funktion setup wird beim starten und neustarten ausgeführt.
void setup() {
//beginn mit der Kommunikation mit der LED Matrix
matrix.begin();
//beginn der Kommunikation mit den Modulinos
Modulino.begin();
buzzer.begin();
buttons.begin();
//die kleinen SMD LEDs an den Tastern A & C
//aktivieren
buttons.setLeds(true, false, true);
//eine Zufallszahl generieren und dem Feld zuweisen
raindropYPos = generateRandomNumber();
//aktivieren der Leiste zum fangen des Regentropfens
grid = 1;
}
//Funktion zum bewegen eines Regentropfens
void moveRaindrop() {
//am Buzzer einen Ton für 75ms. ausgeben
buzzer.tone(FREQ_TICK, 75);
//Wenn die X-Koordinate größer 0 ist dann den
//letzten tropfen löschen
if (raindropXPos > 0) {
grid = 0;
}
//aktivieren der LED an der neuen Koordinate
grid = 1;
//absenden des Arrays und anzeigen der LEDs
matrix.renderBitmap(grid, 8, 12);
//Wenn die X-Koordinate gleich sieben ist,
//dann ist die Runde zuende
if (raindropXPos == 7) {
//prüfen ob die Y-Position der Leiste mit
//der Y-Position des Regentropfens übereinstimmt
if (raindropYPos == barYPos) {
//anzeigen eines glücklichen Smileys
matrix.loadFrame(happy);
//Geschwindigkeit erhöhen
speed -= 25;
} else {
//Wenn die Koordinaten nicht übereinstimmen, dann...
//anzeigen eines traurigen Smileys
matrix.loadFrame(sad);
//zurücksetzen der Geschwindigkeit
speed = DEFAULT_SPEED;
}
//eine Pause von 600ms.
delay(600);
//Zurücksetzen der Felder
grid = 0;
grid = 1;
raindropXPos = 0;
//erzeugen einer neuen Zufallszahl
raindropYPos = generateRandomNumber();
//anzeigen der LEDs
matrix.renderBitmap(grid, 8, 12);
}
}
//Funktion zum erzeugen einer Zufallszahl
//zwischen 0 und 7
int generateRandomNumber() {
randomSeed(analogRead(0));
return random(8);
}
//Die Funktion loop wird dauerhaft ausgeführt, bis
//der Mikrocontroller keine Strom mehr hat, oder
//auf einen Fehler trifft.
void loop() {
//auslesen der vergangenen Millisekunden seit dem Starten
//des Mikrocontrollers
long currentMillis = millis();
//prüfen ob eine Ausführung erfolgen soll
if (currentMillis > (lastAction + speed)) {
//speichern des Zeitpunkts der neuen Ausführung
lastAction = currentMillis;
//die X-Koordinate des Regentropfens um eins erhöhen
raindropXPos += 1;
//Funktion zum bewegen des Regentropfens ausführen
moveRaindrop();
}
//Aktualisieren des Buttons Objektes
if (buttons.update()) {
//Feld zum speichern ob eine Taste betätigt wurde
bool btnPress = false;
//Wenn der Taster A gedrückt wurde, dann...
if (buttons.isPressed(BUTTON_A)) {
//die letzt Koordinate löschen / zurücksetzen
grid = 0;
//Wenn die Y-Position größer 0 ist, dann..
if (barYPos > 0) {
//den Wert um eins verringern
barYPos -= 1;
}
//Feld auf Wahr / True setzen
btnPress = true;
} else if (buttons.isPressed(BUTTON_C)) {
//Wenn der Taster C gedrückt wurde, dann...
//die letzt Koordinate löschen / zurücksetzen
grid = 0;
//Wenn die Y-Position kleiner als 11 ist, dann...
if (barYPos < 11) {
//die Y-Position um eins erhöhen
barYPos += 1;
}
//Feld auf Wahr / True setzen
btnPress = true;
}
//Wenn ein Taster betätigt wurde, dann...
if (btnPress) {
//ausgeben eines Tones wenn die Taste betätigt wurde
buzzer.tone(FREQ_BAR_MOVE, 75);
//aktivieren der neuen Position im Array
grid = 1;
//absenden der Daten und anzeigen der LEDs
matrix.renderBitmap(grid, 8, 12);
}
}
}
Die beiden Smileys habe ich in die Datei animations.h ausgelagert, dieses wirkt lediglich das der eigentliche Quellcode nicht unnötig länger wird.
const uint32_t happy = {
0x31831,
0x80000404,
0x42081f0,
66
};
const uint32_t sad = {
0x31831,
0x80000001,
0xf0208404,
66
};
Alternativer Aufbau & Programmierung mit Taster am Arduino
Wenn du das Arduino Plug and Make Kit nicht hast, aber trotzdem das kleine Spiel nachbauen möchtest, dann zeige ich dir hier nun den Aufbau und die Programmierung mit einfachen Komponenten.
Aufbau der Schaltung
Die Schaltung am Arduino UNO R4 WiFi ist mit den beiden Tastern auch recht schnell erledigt. Du kannst diese entweder mit einem PullUp oder PullDown Widerstand anschließen, oder du lässt diesen ganz weg und schaltest den Taster via Code über den internen 10kOhm Widerstand von der MCU.
Schaltung - Arduino mit Taster & Buzzer
Der Piezo Buzzer muss an einen PWM Pin des Arduinos angeschlossen werden, diese sind am Board mit einer kleinen Welle / Tilde gekennzeichnet.
Prüfen der Schaltung mit einem kleinen Programm
Bevor wir in die Programmierung einsteigen, sollten wir prüfen, ob die Schaltung funktioniert und wir die Signale der Taster erfolgreich auswerten können. Dazu schreiben wir ein kleines Programm, welches die Status der Taster prüft und wenn einer betätigt ist, dieses auf der seriellen Schnittstelle ausgibt.
//Taster Links am digitalen Pin D3 angeschlossen
#define buttonLeft 3
//Taster Rechts am digitalen Pin D2 angeschlossen
#define buttonRight 2
//Buzzer am digitalen PWM Pin D5 angeschlossen
#define buzzer 5
void setup() {
//beginn der seriellen Kommunikation mit 9600 baud
Serial.begin(9600);
//definieren das die Pins der Taster als Eingang dienen
pinMode(buttonLeft, INPUT);
pinMode(buttonRight, INPUT);
//definieren das der Pin des Buzzers als Ausgang dient
pinMode(buzzer, OUTPUT);
}
void loop() {
//Wenn einer der Taster betätigt wird, dann
//ist das Signal am digitalen Pin auf HIGH.
//Wenn der Linke Taster betätigt wird, dann...
if (digitalRead(buttonLeft) == HIGH) {
Serial.println("Taster Links betätigt!");
//ausgeben eines hellen Tones für 100ms.
tone(buzzer, 600, 100);
} else if (digitalRead(buttonRight) == HIGH) {
//Wenn der Rechte Taster betätigt wird, dann...
Serial.println("Taster Rechts betätigt!");
//ausgeben eines tiefen Tones für 100ms.
tone(buzzer, 300, 100);
}
}
Im seriellen Monitor der Arduino IDE siehst du, dass mehrere Signale verarbeitet werden, obwohl wir nur einmal auf den Taster gedrückt haben, dieses nennt man prellen und kann recht einfach unterbunden werden.
Wie man einen Taster am Arduino entprellt habe ich dir im Beitrag Arduino Lektion 87: Taster entprellen ausführlich erläutert.
Programmieren in der Arduino IDE
Für die Programmierung in der Arduino IDE benötigen wir neben dem Boardtreiber für den UNO R4 WiFi und Bibliothek für die LED Matrix noch Bounce2. Über Bounce2 können wir recht einfach die verbundenen Taster entprellen.
Wie man einen Taster entprellt habe ich dir bereits im Beitrag Arduino Lektion 87: Taster entprellen ausführlich erläutert.
Nachfolgend der Link zum Download des fertiges Programmes als ZIP-Datei.
Programm - Arduino UNO R4 WiFi - Fang den RegentropfenHerunterladen
//Bibliothek zum steuern der LED Matrix
#include "Arduino_LED_Matrix.h"
//Bibliothek zum entprellen eines Tasters
#include
//einbinden der externen Datei animation.h
//diese Datei enthält die Smileys für die
//LED Matrix
#include "animation.h"
//Taster Links am digitalen Pin D3 angeschlossen
#define buttonLeftPin 3
//Taster Rechts am digitalen Pin D2 angeschlossen
#define buttonRightPin 2
//Buzzer am digitalen PWM Pin D5 angeschlossen
#define buzzer 5
//Mehrdimensionales Array welches die LED Matrix
//wiederspiegelt.
uint8_t grid = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
};
//Objektinstanz erstellen
ArduinoLEDMatrix matrix;
Bounce btnLeft = Bounce();
Bounce btnRight = Bounce();
//Index der Tasten A & C
const int BUTTON_A = 0;
const int BUTTON_C = 2;
//Felder zum speichern der Koordinaten
//eines Regentropfen
int raindropXPos = 0;
int raindropYPos = 0;
//Felder zum speichern der Koordinaten
//der Leiste zum fangen des Regentropfen
//die XPos ist fest und könnte ebenso als
//Konstante gesetzt werden
int barXPos = 7;
int barYPos = 6;
//Geschwindigkeit der Regentropfen
//bzw. Pause zwischen den Wechsel der LEDs
const int DEFAULT_SPEED = 400;
int speed = DEFAULT_SPEED;
//Frequenzen für die Töne
const int FREQ_TICK = 400;
const int FREQ_BAR_MOVE = 200;
//Feld zum speichern der letzten Ausführung
//des Wechsels der LED
long lastAction = -1;
//Die Funktion setup wird beim starten und neustarten ausgeführt.
void setup() {
//beginn mit der Kommunikation mit der LED Matrix
matrix.begin();
//definieren das die Pins der Taster als Eingang dienen
//und verbinden mit den Tasterobjekten
btnLeft.attach(buttonLeftPin, INPUT);
//Interval zum entprellen auf 5ms. setzen
btnLeft.interval(5);
btnRight.attach(buttonRightPin, INPUT);
btnRight.interval(5);
//definieren das der Pin des Buzzers als Ausgang dient
pinMode(buzzer, OUTPUT);
//eine Zufallszahl generieren und dem Feld zuweisen
raindropYPos = generateRandomNumber();
//aktivieren der Leiste zum fangen des Regentropfens
grid = 1;
}
//Funktion zum bewegen eines Regentropfens
void moveRaindrop() {
//am Buzzer einen Ton für 75ms. ausgeben
tone(buzzer, FREQ_TICK, 75);
//Wenn die X-Koordinate größer 0 ist dann den
//letzten tropfen löschen
if (raindropXPos > 0) {
grid = 0;
}
//aktivieren der LED an der neuen Koordinate
grid = 1;
//absenden des Arrays und anzeigen der LEDs
matrix.renderBitmap(grid, 8, 12);
//Wenn die X-Koordinate gleich sieben ist,
//dann ist die Runde zuende
if (raindropXPos == 7) {
//prüfen ob die Y-Position der Leiste mit
//der Y-Position des Regentropfens übereinstimmt
if (raindropYPos == barYPos) {
//anzeigen eines glücklichen Smileys
matrix.loadFrame(happy);
//Geschwindigkeit erhöhen
speed -= 25;
} else {
//Wenn die Koordinaten nicht übereinstimmen, dann...
//anzeigen eines traurigen Smileys
matrix.loadFrame(sad);
//zurücksetzen der Geschwindigkeit
speed = DEFAULT_SPEED;
}
//eine Pause von 600ms.
delay(600);
//Zurücksetzen der Felder
grid = 0;
grid = 1;
raindropXPos = 0;
//erzeugen einer neuen Zufallszahl
raindropYPos = generateRandomNumber();
//anzeigen der LEDs
matrix.renderBitmap(grid, 8, 12);
}
}
//Funktion zum erzeugen einer Zufallszahl
//zwischen 0 und 7
int generateRandomNumber() {
randomSeed(
Read the full article
0 notes