Hydraulik-Lüfter


Google-Suche auf MEINE-SCHALTUNG.de :





Online Rechner

Chronik

Dauerkalender


Musterspiel mit LED-Matrix


LED-Matrix Musterspiel


Ein Mikrocontroller, in dem Fall Arduino Nano, generiert in dem Spiel pro Versuch eine Reihe aus acht Mustern, die einzeln auf je einer 8x8-LED-Matrix angezeigt werden. Der Spieler hat ca. fünf Sekunden Zeit, um sich eine solche Musterreihe anzuschauen. Grundsätzlich sind alle Muster verschieden. In bestimmten Versuchen, die im Programm per Zufall dazu bestimmt werden, werden jedoch zwei identische Muster angezeigt. Die Aufgabe des Spielers ist es, die gleiche Muster, falls sie vorkommen, zu erkennen und dies mit der Betätigung eines Tasters zu bestätigen. Die Gesamtanzahl der Versuche pro Spiel ist unbekannt. Auch dies wird per Zufall entschieden. Insgesamt werden pro Spiel jedoch immer nur acht Aufgaben mit doppelt vorkommenden Mustern gestellt. D.h. maximal acht Mal pro Spiel tauchen in den Musterreihen zwei identische Muster auf. Für jeden erfolgreichen Versuch, in dem der Spieler die gleichen Muster erkennt, wird seine Punktezahl erhöht. Pro Spiel kann der Spieler demnach maximal acht Punkte ansammeln. Nach dem letzten achten Versuch mit zwei gleichen Mustern wird das Spiel beendet. Die Punktezahl wird in Form von Kreuzen, die aus acht LEDs gebildet werden, eingeblendet. Für jeden Punkt ein Kreuz auf einer 8x8-Matrix.

LED-Matrix

Matrix-Modul vierfach

4fach-Modul Frontansicht

Matrix-Modul vierfach (Rückseite)

4fach-Modul Rückansicht

Matrix-Modul vierfach (Anschluss)

LED-Matrix-Modul Anschlüsse (IN Seite)

Das gesamte Anzeige-Feld besteht aus acht 8x8-Matrixmodulen, die in Reihe verschaltet sind. Jedes Modul besteht aus einer rechteckigen Platine, auf der der MAX7219 – Treiber eingelötet ist. Der Treiber stellt die Schnittstelle zwischen dem Mikrocontroller und der LED-Matrix dar. Er ist für die Ansteuerung der einzelnen LEDs verantwortlich. In zwei Steckleisten, die auf der Platine montiert sind, wird das LED-Modul 1088AS, das aus 64 roten Leuchtdioden besteht, gesteckt. Die LEDs sind jeweils in acht Reihen und acht Spalten angeordnet. Zwei Schnittstellen für IN- und OUT-Signale ermöglichen die Reihenschaltung der Module. Dank der SPI-Schnittstelle, über die der Treiber MAX7219 verfügt und über die er mit dem Mikrocontroller kommuniziert, werden zur Ansteuerung eines Moduls nur drei Leitungen gebraucht.
Die Matrix-Module sind in verschiedenen Formaten erhältlich. Sie können einzeln oder als Gruppe eingekauft werden. In unserem Fall wurden zwei Module 8x32 zusammenverbunden.

Max-Treiber

MAXIM-Treiber

LED-Matrix

LED-Matrix

Mikrocontroller

Mikrocontroller

Die Aufgabe, das Spiel zu verwalten, erledigt für uns der Mikrocontroller Arduino Nano. Das ist möglich, da dank der SPI-Schnittstelle zu den Matrix-Modulen nur drei Leitungen benötigt werden. Bei deutlich mehr Anschlüssen müsste man unter Umständen auf andere Alternativen ausweichen. Neben den drei SPI-Anschlüssen wird noch ein digitaler und analoger Eingang in der Schaltung in Anspruch genommen. Damit stehen noch weitere freie I/Os für eventuelle Erweiterungen des Spiels zur Verfügung.

Schaltplan

Schaltplan


Programm (Sketch)

// **************************************************************************************
// MUSTERSPIEL mit LED-Matrix
// Arduino Nano
// Arduino IDE 2.3.2
// **************************************************************************************
#include "LedControl.h"                               // Matrix Bibliothek einbinden

LedControl lc=LedControl(11,12,10,8);                 

         // -------------------------------------------------
         // LedControl (DIN, CLK, CS, Anzahl) / Anschlüsse
         // lc.shutdown (Adresse, Status) / Modus
         // lc.setIntensity (Adresse, Wert) / Helligkeit
         // lc.clearDisplay (Adresse) / Löschen
         // lc.setRow (Adresse, Reihe, Byte) / Led-Reihe
         // lc.setColumn (Adresse, Reihe, Byte) / Led-Spalte
         // lc.setLed(Segment,Reihe,Spalte,Wert) / LED e/a
         // -------------------------------------------------

int Segment;                                          // Segment aktuell     
int Segment_Figur [8];                                // Nr. des Segmentmusters
int Muster;                                           // Muster aktuell
int Muster_gesperrt [12];                             // Muster markieren
int Segment_gesperrt [12];                            // Segmente markieren
int Zaehler;                                          // Zählvariable bei Anzeige
int Aufgabe;                                          // "Aufgabe"=0: Aufgabe stellen
int Aufgaben_gestellt;                                // Anzahl gestellten Aufgaben
int Aufgaben_geloest;                                 // Anzahl gelösten Ausgaben
int Taster = 2;                                       // Externer Taster
bool Spielstart;                                      // Spiel läuft
bool Aufgabe_Aktuell;                                 // Aufgabe wurde gestellt

// **************************************************************************************
void setup() {
  
    for (Segment=0; Segment<8; Segment++) {           // Anzeigen vobereiten
        lc.shutdown(Segment,false);
        lc.setIntensity(Segment,8);
    }    
    pinMode(Taster, INPUT_PULLUP);                    // Taster als PullUp
    randomSeed(analogRead(A0));                       // Zufallsgenerator Startwert
}

// **************************************************************************************
void loop() {

    while (not Spielstart) {                          // Warten auf Start
      if (digitalRead(Taster) == LOW) {
          Spielstart = true;
      }
    }

    for (int i=0; i<8; i++) {
        lc.clearDisplay (i);                          // Alle Segmente löschen
        Segment_Figur [i] = -1;                       // Segment_Figur [] vorbelegen
        Segment_gesperrt [i] = -1;                    // Segment_gesperrt [] vorbelegen
    }                     
    for (int i=1; i<12; i++) {                        // Alle Muster stehen zur Verfügung
        Muster_gesperrt [i] = -1;                     // Alle Muster freigeben
    }    
                                                      // Alle Felder mit Muster belegen
    for (Segment=0; Segment<8; Segment++) {
        NEUES_MUSTER:
            Muster = random(12);                      // Muster per Zufall auswählen
            if (Muster_gesperrt [Muster] > -1) {      // Bereits verwendet
                goto NEUES_MUSTER;                    // Noch ein Versuch
            }
            Muster_gesperrt [Muster] = 1;             // Muster sperren
            Segment_Figur [Segment] = Muster;         // Muster zuordnen
    }

    Aufgabe = random (3);                             // Soll Aufgabe gestellt werden?
    if (Aufgabe == 0) {                               // JA bei 0
        Segment = random (8);
        int Muster_Halten = Segment_Figur [Segment];
        Segment = random (8);
        Segment_Figur [Segment] = Muster_Halten;
        Aufgaben_gestellt++;
        Aufgabe_Aktuell = true;
    }

    Zaehler = 0;
    ANZEIGEN:                                         // Felder per Zufall anzeigen
        Segment = random(8);                          // Feld wählen
        if (Segment_gesperrt [Segment] > -1) {        // Bereits vorbelegt
            goto ANZEIGEN;
        }
        Segment_gesperrt [Segment] = 1;               // Feld sperren
        Muster = Segment_Figur [Segment];             // Muster Variable aktualisieren
        Zaehler++;                                    // Laufzähler (8 Felder)
        Muster_anzeigen ();                           // Anzeige aktualisieren
        if (Zaehler < 8) {                            // solange, bis alle Felder fertig
          goto ANZEIGEN;
        }

    for (int i=1; i<5000; i++) {                      // Zeit für die Antwort
        delay (1);
        if (digitalRead(Taster) == LOW) {
            if (Aufgabe_Aktuell) {
                Aufgaben_geloest++;                   // Punkt bei richtiger Antwort
            }
            goto WEITER_MACHEN;
        }
    }
    WEITER_MACHEN:
        Aufgabe_Aktuell = false;
        if (Aufgaben_gestellt == 8) {                 // Bei 8 Aufgaben Spielende
            for (int i=0; i<8; i++) {
                lc.clearDisplay (i);                  // Alle Segmente löschen
            }
            for (int i=0; i<Aufgaben_geloest; i++) {  // Anzahl Antworten anzeigen
                Segment = i;
                Muster = 13;
                Muster_anzeigen ();
            }
            Spielstart = false;                       // Variablen zurücksetzen
            Aufgaben_geloest = 0;
            Aufgaben_gestellt = 0;
        }    
}  

// **************************************************************************************
void Muster_anzeigen () {

    switch (Muster) {
        case 1: { Muster_01 ();
                break; }
        case 2: { Muster_02 ();
                break; }        
        case 3: { Muster_03 ();
                break; }        
        case 4: { Muster_04 ();
                break; }        
        case 5: { Muster_05 ();
                break; }        
        case 6: { Muster_06 ();
                break; }        
        case 7: { Muster_07 ();
                break; }        
        case 8: { Muster_08 ();
                break; }        
        case 9: { Muster_09 ();
                break; }        
        case 10: { Muster_10 ();
                break; }        
        case 11: { Muster_11 ();
                break; }        
        case 12: { Muster_12 ();
                break; }  
        case 13: { Muster_13 ();
                break; }                      
    }
}

// **************************************************************************************
void Muster_01 () {

    Rechteck (3,3);                    // x
}

// **************************************************************************************
void Muster_02 () {

    Rechteck (3,1);                    // x   x
    Rechteck (3,5);
}

// **************************************************************************************
void Muster_03 () {
                                       //  x
    Rechteck (1,3);                    //
    Rechteck (5,3);                    //  x
}

// **************************************************************************************
void Muster_04 () {

    Rechteck (1,3);                    //  x
    Rechteck (3,3);                    //  x
    Rechteck (5,3);                    //  x
}

// **************************************************************************************
void Muster_05 () {

    Rechteck (3,1); 
    Rechteck (3,3);                    // x x x
    Rechteck (3,5);
}

// **************************************************************************************
void Muster_06 () {

    Rechteck (1,5);                    //     x
    Rechteck (3,3);                    //   x
    Rechteck (5,1);                    // x
}

// **************************************************************************************
void Muster_07 () {

    Rechteck (1,1);                    // x
    Rechteck (3,3);                    //   x
    Rechteck (5,5);                    //     x
}

// **************************************************************************************
void Muster_08 () {

    Rechteck (1,1);                    // x   x
    Rechteck (1,5);                    // 
    Rechteck (5,1);                    // x   x
    Rechteck (5,5);                    
}

// **************************************************************************************
void Muster_09 () {

    Rechteck (1,1);                    
    Rechteck (1,5);                    // x   x
    Rechteck (5,1);                    //   x
    Rechteck (5,5);                    // x   x
    Rechteck (3,3);                    
}

// **************************************************************************************
void Muster_10 () {

    Rechteck (1,3);  
    Rechteck (3,1);                    //    x
    Rechteck (3,3);                    // x  x  x
    Rechteck (3,5);                    //    x
    Rechteck (5,3);
}

// **************************************************************************************
void Muster_11 () {

    Rechteck (1,1);                 
    Rechteck (1,3);                    //    x
    Rechteck (1,5);                    //    x
    Rechteck (3,3);                    // x  x  x
    Rechteck (5,3);               
}

// **************************************************************************************
void Muster_12 () {

    Rechteck (1,3);                 
    Rechteck (3,3);                    // x  x  x
    Rechteck (5,3);                    //    x
    Rechteck (5,5);                    //    x
    Rechteck (5,1);                    
}

// **************************************************************************************
void Muster_13 () {

    Rechteck (3,3);                    // x    x
    lc.setLed(Segment,2,2,true);       //   x x
    lc.setLed(Segment,2,5,true);       //   x x
    lc.setLed(Segment,5,2,true);       // x     x
    lc.setLed(Segment,5,5,true);
}

// **************************************************************************************
void Rechteck (byte Reihe, byte Spalte) {         // Grundelement aller Figuren ist
                                                  // ein Rechteck bestehend aus 4 Pixel
    lc.setLed(Segment,Reihe,Spalte,true); 
    lc.setLed(Segment,Reihe+1,Spalte,true);
    lc.setLed(Segment,Reihe,Spalte+1,true);
    lc.setLed(Segment,Reihe+1,Spalte+1,true);
}

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


Das Spiel wird mit einem Taster bedient. Wenn das Spiel noch nicht gestartet ist, dient der Taster als Starttaster. Wenn das Spiel bereits läuft, wird mit dem Taster die „hoffentlich“ richtige Antwort quittiert.
Vieles hängt in dem Spiel vom Zufall ab. Damit das „Zufällige“ auch wirklich sichergestellt wird, wird in dem Setup-Bereich mit „randomSeed(analogRead(A0))“ in das Zufallsgenerator eine zufällige Startzahl geladen. Der analoge Eingang A0 bleibt unverdrahtet und verändert ständig seinen Wert.
Nachdem der Taster betätigt wird, startet das Spiel. Alle Matrix-Module werden gelöscht. Alle Segmente und Figuren (Muster) zur Auswahl freigegeben.
Im ersten Schritt wird jedem der acht Segmente ein Muster zugeordnet. Mit einer Zusatzabfrage wird sichergestellt, dass alle Muster verschieden sind.
Im zweiten Schritt entscheidet der Zufall (Aufgabe = random (3)), ob dem Spieler eine Aufgabe gestellt werden soll. In diesem Fall (Aufgabe = 0) erscheinen in der Musterreihe zwei identische Figuren.
Anschließend werden die Figuren eingeblendet.
Der Spieler hat ab jetzt fünf Sekunden Zeit, um die Figuren zu betrachten und ggf. die zwei identische zu identifizieren. Sobald ihm das gelingt, sollte er den Taster betätigen, um die Gesamtzahl seiner Trefferpunkte zu aktualisieren.
Der Ablauf wiederholt sich so oft, bis die Anzahl der gestellten Aufgaben gleich acht ist. Die Anzeigeelemente werden gelöscht und die Anzahl der gesammelten Punkte in Form von Kreuz-Figuren eingeblendet.
Die Spielrunde ist damit beendet. Bei erneutem Betätigen des Tasters wird das Spiel wieder gestartet und der Ablauf wiederholt.

Testschaltung

Testschaltung



Kurzvideo

Kurzvideo


Weitere Themen:


Google-Suche auf MEINE-SCHALTUNG.de :


Home Impressum Datenschutz