Servoumrichter von SEW


Google-Suche auf MEINE-SCHALTUNG.de :





Online Rechner

Chronik

Dauerkalender


Schlag den Maulwurf für zwei Spieler

Schlag den Maulwurf


In 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.
In unserer Spielausführung werden die Maulwürfe durch farbige Leuchten, die via Zufall in einer unerwarteten und nicht vorhersehbaren Reihenfolge aufleuchten, ersetzt. Zurückgedrängt werden die Maulwürfe durch Betätigen einen dazugehörigen Taster. In unserer Testschaltung werden pro eine Spielrunde die „Maulwürfe“ 20-mal aus den Löchern hervorkommen. Der Spieler, der es schafft, die „Maulwürfe“ schneller zurückzudrängen, ist der Gewinner.
Als Mikrocontroller, der das Aufleuchten der Leuchten und das Betätigen der Taster verwaltet, tritt Arduino Mega auf. Jedem Spieler ist ein Spielbrett mit fünf Taster mit Leuchten zugeordnet.
Wichtige Punkte der Schaltung sind: Startwert für den Zufallsgenerator, gleichzeitige Steuerung von zwei 7-Segmentanzeigen und Taster Prellung.

Drucktaster

Drucktaster


Bei 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.

Drucktaster Anschlüsse


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.
In unserem Beispiel verzichten wir im Programm auf Anwendung von Interrupts. Der Zustand der Taster wir im laufenden Programm abgefragt. Sobald nach dem Betätigen eines Tasters das erste EIN-Signal erkannt wird, wird eine andere Leuchte aktiviert und Abfrage eines anderen Tasters gestartet. Damit sind die weiteren Signale von dem gerade betätigten Taster nicht mehr relevant und werden nicht mehr berücksichtigt.
Wenn wir zulassen, dass nach beliebiger Leuchte X via Zufall wieder die gleiche Leuchte X gewählt wird und damit auch der zugehörige Taster, würde das Prellen des Kontaktes die Punktezählung völlig durcheinanderbringen und ein faires Spiel unmöglich machen.

Anzeige

Anzeige

Die 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.

Mikrocontroller

Mikrocontroller

Lä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.

Schaltplan

Schaltplan


Testschaltung

Testschaltung


Testschaltung (Anzeigen)


Programm (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;
}

// **************************************************************************************

Kurzvideo

Kurzvideo


Weitere Themen:


Google-Suche auf MEINE-SCHALTUNG.de :


Home Impressum Datenschutz