| Schlag den Maulwurf für zwei SpielerIn dem Spiel sind besonders die Schnelligkeit und Geschicklichkeit gefragt. Eine sehr gute Gelegenheit, um eigene Reflexe und Reaktionszeiten zu testen.
Das Spiel basiert auf dem alten Kinderspiel „Schlag den Maulwurf“ (Whac-A-Mole) indem künstliche Maulwürfe, die aus Löchern hervorkommen, mit einem Hammer zurück in die
Löcher geschlagen werden müssen.
DrucktasterBei den Drucktastern handelt es sich um mechanische Taster mit einer Kontrollleuchte. Die Bezeichnung der Taster lautet YJ-LA16. Ein Taster stellt
einen potenzialfreien Wechsler Kontakt zur Verfügung. Er kann an den drei mittleren Pins abgegriffen werden. In der Schaltung verwenden wir lediglich den Schließer.
Mit zwei äußeren Pins kann die integrierte Kontrollleuchte mit Spannung versorgt werden. Die Leuchte ist für 12V ausgelegt, kann jedoch problemlos mit 5V versorgt
werden. Beim Betrieb mit 5V liegt die Stromaufnahme zwischen 1 und 2 mA. Wie bei allen mechanischen Schaltern und Tastern haben wir auch hier mit dem Problem des Prellens zu tun. Beim Betätigen jeden Tasters kann der
Mikrocontroller mehrere Ein/Aus-Signale wahrnehmen. Ohne Gegenmaßnahmen ist eine einwandfreie Funktionalität einer Schaltung nicht möglich.
AnzeigeDie Schaltung verfügt über zwei 7-Segmentanzeigen, die aus vier Digits bestehen. Jede Anzeige bildet zusammen mit dem Anzeigetreiber TM1637 ein Modul, das
vier Anschlüsse hat. Zwei Leitungen werden benötigt für die Spannungsversorgung, mit zwei weiteren wird der Treiber mit Daten versorgt. Um den Treiber problemlos
ansteuern zu können benutzen wir im Programm die Bibliothek „TM1637Display.h“. Die Bibliothek ermöglicht auch zwei Anzeigen gleichzeitig in einem
Programm zu steuern. MikrocontrollerLämpchen ein- und ausschalten, Taster überwachen und Gewinner ermitteln erledigt für uns Arduino Mega. Unter anderem arbeitet der Mikrocontroller mit
Zufallszahlen, was notwendig ist, um jeden Spieler jeweils mit einer unvorhersehbaren Aufgabe zu konfrontieren. Das Problem bei Zufallszahlen besteht darin, dass
ein Mikrocontroller beim Start seines Zufallsgenerators immer mit der gleichen Zahl beginnt. Es gibt zahlreiche Methoden, um das Problem umzugehen. In unserem
Beispiel wird mit „randomSeed(analogRead(0))“ der aktuelle Wert am analog Eingang A0 ausgelesen und als Startwert in den Zufallsgenerator geladen. Hier machen wir
uns die Tatsache nützlich, dass ein nicht verdrahteter analoger Eingang beim Auslesen stets unterschiedliche
Werte liefert. SchaltplanTestschaltungProgramm (Sketch)// **************************************************************************************// Schlag den Maulwurf für zwei Spieler // Eine Schaltung mit Arduino Mega und zwei 7-Segmentanzeigen // Arduino IDE 2.3.3 // ************************************************************************************** #include <TM1637Display.h> // Bibliothek für den Treiber TM1637 #define CLK1 43 // Anschlußpins für Display Spieler 1 #define DIO1 45 #define CLK2 47 // Anschlußpins für Display Spieler 2 #define DIO2 49 TM1637Display display1(CLK1, DIO1); // Objekt Display Spieler 1 TM1637Display display2(CLK2, DIO2); // Objekt Display Spieler 2 String Ausgabe; int Taster [2][5] = { { 22, 24, 26, 28, 30 }, // Pins Taster Spieler 1 { 32, 34, 36, 38, 40 } };// Pins Taster Spieler 2 int Leuchte [2][5] = { { 23, 25, 27, 29, 31 }, // Pins Leuchten Spieler 1 { 33, 35, 37, 39, 41 } };// Pins Leuchten Spieler 2 // Bei folgenden Variablen: // 0 - Spieler 1 / 1 - Spieler 2 bool Taster_betaetigt [2]; int Zufall_Leuchte [2]; bool Leuchte_EA [2]; int Punkte [2]; // Aktuelle Punktezahl bool Spiel_laeuft = false; // Spiel Status int Punkte_Maximal = 20; // Spielgrenze kann eingestellt werden // Zeitmessung für "Keine Aktion" unsigned long MillisAktuell; unsigned long MillisAlt; // ************************************************************************************** void setup() { display1.setBrightness(10); // Anzeige Helligkeit display2.setBrightness(10); display1.clear(); // Anzeige löschen display2.clear(); for (int i=0; i<5; i++) { // Pins Deklaration pinMode(Taster [0][i], INPUT_PULLUP); pinMode(Taster [1][i], INPUT_PULLUP); pinMode(Leuchte [0][i], OUTPUT); pinMode(Leuchte [1][i], OUTPUT); } MillisAlt = millis(); randomSeed(analogRead(0)); // Stratwert für Zufallsgenerator } // ************************************************************************************** void loop () { // Hauptprogramm MillisAktuell = millis(); // Keine Aktion in 3s = Abbruch if (MillisAktuell - MillisAlt > 3000) { Spiel_laeuft = false; } if (not Spiel_laeuft) { // Leuchteffekte vor dem Spiel Leuchten_EIN_AUS (); // Blinkende lampen Leuchten_AUS (); // Alle Leuchten aus Spiel_laeuft = true; // Möglichkeit für Spielanfang for (int i=0; i<2; i++) { Taster_betaetigt [i] = true; Punkte [i] = 0; } Punkte_Anzeigen (); // Punke-Anzeige aktualisieren } // Spiel läuft: // 1. Neue Leuchte via Zufall EIN // dabei alle anderen Leuchten AUS // 2. Richtiger Taster betätigt? // 3. Wenn ja = Punkte addieren for (int i=0; i<2; i++) { if (Spiel_laeuft && Taster_betaetigt [i]) { ZUFALL: int Zufallszahl = random (5); if (Zufallszahl == Zufall_Leuchte [i]) { goto ZUFALL; } Zufall_Leuchte [i] = Zufallszahl; // Spieler 1 Zufall digitalWrite (Leuchte [i][Zufall_Leuchte [i]], HIGH); // Leuchte EIN for (int j=0; j<5; j++) { if (j != Zufall_Leuchte [i]) { digitalWrite(Leuchte [i][j], LOW); // andere Leuchten AUS } } Taster_betaetigt [i] = false; } if (digitalRead(Taster [i][Zufall_Leuchte [i]]) == LOW) { // Taster betätigt? Taster_betaetigt [i]= true; Punkte [i]++; Punkte_Anzeigen (); MillisAlt = millis(); } } // Punktgrenze erreicht = Spiel Ende for (int i=0; i<2; i++) { if (Punkte [i] == Punkte_Maximal) { Gewonnen (i); } } } // ************************************************************************************** void Punkte_Anzeigen () { // Punkte Anzeige aktualisieren display2.showNumberDec(Punkte [0], false, 4,4); // Ausgabe Display 1 display2.showNumberDec(Punkte [0], false, 4,4); // Ausgabe Display 2 } // ************************************************************************************** void Leuchten_EIN_AUS () { // Lichteffekte for (int i=0; i<100; i++) { int Zufall_Leuchte = random (5); bool OUT_Zustand = digitalRead(Leuchte [0][Zufall_Leuchte]); digitalWrite (Leuchte [0][Zufall_Leuchte], not OUT_Zustand); OUT_Zustand = digitalRead(Leuchte [1][Zufall_Leuchte]); digitalWrite (Leuchte [1][Zufall_Leuchte], not OUT_Zustand); delay (50); } } // ************************************************************************************** void Leuchten_AUS () { // Alle Leuchten AUS for (int i=0; i<5; i++) { digitalWrite (Leuchte [0][i], LOW); digitalWrite (Leuchte [1][i], LOW); } delay (2000); MillisAlt = millis(); } // ************************************************************************************** void Gewonnen (int Spieler) { // Runde abgeschlossen // Leuchten Gewinnerseite blinken lassen for (int i=0; i<10; i++) { for (int j=0; j<5; j++) { digitalWrite (Leuchte [Spieler][j], HIGH); } delay (200); for (int j=0; j<5; j++) { digitalWrite (Leuchte [Spieler][j], LOW); } delay (200); } MillisAlt = millis(); Spiel_laeuft = false; } // ************************************************************************************** KurzvideoKurzvideo Weitere Themen:
|