Suche

Arduino Memory​

Einleitung

Ein Memory-Spiel, ist ein beliebtes Kartenspiel, das oft von Kindern, aber auch von Erwachsenen, gespielt wird, um das Gedächtnis, die Konzentration und die Aufmerksamkeit zu fördern. Das Ziel des Spiels besteht darin, identische Kartenpaare zu finden, die zuvor verdeckt auf einem Tisch angeordnet wurden. Das Wichtigste ist dabei, dass man sich merkt, welche Karte an welcher Stelle zu finden ist, obwohl diese wieder verdeckt wurden. Das Spiel endet, wenn alle Kartenpaare gefunden wurden. Der Spieler, der am Ende die meisten Paare gesammelt hat, gewinnt.

Dieses Spiel möchten wir in diesem Projekt mit Arduino umsetzen. Man kann dabei einen Arduino-Mikrocontroller, aber auch Mikrocontroller auf ESP oder Raspberry-Basis verwenden. In unserem Beispiel verwenden wir einen Arduino UNO „clone“ von Funduino. Unser Spiel ist ein bisschen anders als das klassische Memorie-Spiel, aber eines haben beide gemeinsam – das Gehirn muss Höchstleistung erbringen, wenn man gewinnen möchte.

Benötigtes Material

Das verwendete Material ist vollständig in den Lernsets von Funduino enthalten:

  • Arduino Microcontroller

  • Breadboard

  • LEDs: 1x Rot, 1x Gelb, 1x Grün, 1x Blau, 3x Weiß

  • Widerstände: 2x 200 Ohm, 5x 100 Ohm, 5x 1000 Ohm

  • 21 Breadboardkabel: In unserem Fall 2x Rot, 1x Orange2x Blau4x Weiß2x Grau, 4x Schwarz, 2x Lila, 2x Grün, 2x Gelb

Aufgabe

Erstelle ein auf LEDs basierendes Memoriespiel. Vier farbige LEDs leuchten in einer zufälligen Reihenfolge auf und der Spieler muss diese Reihenfolge wiederholen. Mit jedem Durchlauf wird die Farbfolge um eine Farbe länger.

 

 

Hilfe zur Umsetzung

Ein Taster startet das Spiel, woraufhin weiße LEDs aufleuchten. 

Die LEDs blinken in einer zufällig generierten Farbfolge auf und die weißen LEDs erleuchten erneut, als Zeichen für den Spieler zu beginnen. 

Der Spieler verwendet die zu den LEDs gehörigen Taster, um die Farbfolge zu wiederholen. 

Hat er genügend Tasten gedrückt, erleuchten die weißen LEDs erneut und der Arduino-Mikrocontroller vergleicht die vorgegebene Farbfolge mit der vom Spieler eingetippten Reihenfolge. Hat der Spieler alles richtig gemacht, so wird das Level, und somit die Anzahl der Farben pro Runde, um einen erhöht. Die weißen LEDs leuchten auf und die nächste Runde beginnt.

Schafft der Spieler es bis zum 10. Level, so erleuchten alle LEDs und das Spiel beginnt von vorn. Macht der Spieler jedoch einen Fehler, so erleuchten die weißen LEDs fünfmal und das Spiel startet ebenfalls von vorn.

Aufbau und Pinbelegung

  • Pin2 = Weiße LEDs

  • Pin3 = Blaue LED

  • Pin4 = Blauer Taster

  • Pin5 = Grüne LED

  • Pin6 = Grüner Taster

  • Pin7 = Gelbe LED

  • Pin8 = Gelber Taster

  • Pin9 = Rote LED

  • Pin10 = Roter TasterPin

  • 11 = Start Taster

Code mit Erklärungen


//Teilt den Namen der LEDs jeweils eine Zahl/Pin zu.
int LEDweis = 2;
int LEDblau = 3;
int LEDgruen = 5;
int LEDgelb = 7;
int LEDrot = 9;

//Teilt den Namen der Taster jeweils eine Zahl/Pin zu.
int TASTERblau = 4;
int TASTERgruen = 6;
int TASTERgelb = 8;
int TASTERrot = 10;
int TASTERstart = 11;

//Speichert ob ein Taster ein- oder ausgeschaltet ist.
int STATUSblau = 0;
int STATUSgruen = 0;
int STATUSgelb = 0;           
int STATUSrot = 0;
int STATUSstart = 0;

int iNumber = 0;  //Platzhaltter für eine Zahl.
int iLevel = 3;   //Speichert welches Level abgespielt werden soll.     
int iLEDs[] = {3, 5, 7, 9};   //Speichert die von LEDs belegten Pins.
/*
 int iLEDs[] erstellt ein Regal in dem Daten vom Typ int(Zahlen) gespeichet werden können.
 Die leehre Klammer [] gibt dabei an, dass die größe des Regals noch nicht festgelegt ist.
 Der Teil {3, 5, 7, 9} erstellt jetzt jeweils ein Fach für die Nummer 3, 5, 7 und 9.
 Die Fächer werden in der Reihenfolge ihrer erstellung nummeriert beginnent mit der Ziffer 0.
 Im Fach0 wäre also die Nummer 3, im Fach1 die Nummer 5, im Fach2 die Nummer 7 und so weiter.
*/
int iRandom[10];    //Speichert die zufällig generierte Farbfolge.   
int iPlayer[10];    //Speichert die vom Spieler eingegebene Farbfolge.
/*
 int iRandom[10] erstellt ein Regal in dem Daten vom Typ int(Zahlen) gespeichert werden können.
 Die [10] gibt an, dass das Regal 10 Fächer hat, die mit den Ziffern von 0 bis 9 markiert sind.
 Da keine weiteren Daten angegeben sind bleiben diese Fächer zunächst leehr.
*/

void setup() {
  //Gibt die LED Pins als ausgabe Pins an. Hier müssen Signale ausgegeben werden.
  pinMode(LEDweis, OUTPUT);
  pinMode(LEDblau, OUTPUT);
  pinMode(LEDgruen, OUTPUT);
  pinMode(LEDgelb, OUTPUT);
  pinMode(LEDrot, OUTPUT);

  //Gibt die Taster Pins als eingabe Pins an. Hier müssen Siegnale emfangen werden.
  pinMode(TASTERblau, INPUT);
  pinMode(TASTERgruen, INPUT);
  pinMode(TASTERgelb, INPUT);
  pinMode(TASTERrot, INPUT);
  pinMode(TASTERstart, INPUT);
  
  RandomArray();    //Springt in die Methode RandomArray(), zur Erstellung der Farbfolge, und kehrt nach dessen Durchlauf hierhin zurück.
}


void loop()   //Diese Methode wiederholt den Code bis eine andere Methode aufgerufen wird.
{
  STATUSstart = digitalRead(TASTERstart);   //Überprüft ob die Starttaste ein- oder ausgeschaltet ist.
  
  if (STATUSstart == HIGH)    //Der Code wird nur ausgeführt wenn die Starttaste gedrückt wird.
  {
    digitalWrite(LEDweis, HIGH);    //Schaltet die weißen LEDs ein.
    delay(500);   //Wartet 500ms.
    digitalWrite(LEDweis, LOW);   //Schalted die weißen LEDs aus.
    delay(500);   //Wartet 500ms.
    
    Random();   //Springt in die Methode Random(),um die Farfolge ab zu spielen, und kehrt nach dessen Durchlauf hierhin zurück.
  }
  
}


void RandomArray()    //Generiert eine zufällige Reienfolge der von LEDs belegten Pins die dann von anderen Methoden verwendet werden kann.
{
  randomSeed(analogRead(0));    //Versucht einen Wert von einem nicht belegten Pin auszulesen um eine zufällige Startposition für die random Funktion zu generieren.
  
  for (int i = 0; i < 10; i++)    //Wiederholt den Code bis i = 10 ist und erhöt i um 1 nach jedem Durchlauf.
  {
    iNumber = random(4);    //Generiert eine 'zufällige' Zahl von 0 bis 3.
    
    iRandom[i] = iLEDs[iNumber];    //Benutzt die Zufallszahl um ein Fach aus dem iLEDs Array zu wählen und packt dessen Inhalt in das i-te Fach im iRandom Array.
  }
  
}


void Random()   //Spielt die zufällig generierte LED Farbfolge ab.
{
  for (int i = 0; i < iLevel; i++)    //Wiederholt den Code bis i = iLevel ist und erhöt i um 1 nach jedem Durchlauf.
  {    
    digitalWrite(iRandom[i], HIGH);   //Schaltet die im i-ten Fach des iRandom Array gespeicherte LED ein.
    delay(500);   //Wartet 500ms.
    digitalWrite(iRandom[i], LOW);    //Schalted die im i-ten Fach des iRandom Array gespeicherte LED aus.
    delay(500);   //Wartet 500ms.
  }
  
  delay(500);   //Wartet 500ms.
  digitalWrite(LEDweis, HIGH);    //Schaltet die weiße LED ein.
  delay(300);   //Wartet 300ms.
  digitalWrite(LEDweis, LOW);   //Schaltet die weiße LED aus.
  delay(500);   //Wartet 500ms.

  PlayerInput();    
  /*
   Startet die Methode PlayerInput(), und verhindert zugleich den volständigen durlauf der Random() Methode.
   Erst nach Durchlauf der PlayerInput() Methode kehrt das Programm zu diesem Punkt zurück und erreicht das Ende von Random().
   Nach vollendung von Random() springt das Programm zurück in die Metode loop().
  */
}


void PlayerInput()    //Speichert die vom Spieler eingegebene Farbfolge.
{
  for (int i = 0; i < iLevel;)    //Wiederholt den Code bis i = iLevel ist.
  {
    while(digitalRead(4) != HIGH && digitalRead(6) != HIGH && digitalRead(8) != HIGH && digitalRead(10) != HIGH)    //Wartet so lange wie keine Tasten gedrückt werden.
    {
      //do Nothing;
    }

    //Überprüft ob die Taster ein- oder ausgeschaltet sind.
    STATUSblau = digitalRead(TASTERblau);
    STATUSgruen = digitalRead(TASTERgruen);
    STATUSgelb = digitalRead(TASTERgelb);
    STATUSrot = digitalRead(TASTERrot);
    
    if (STATUSblau == HIGH)   //Der Code wir nur nach druck des blauen Tasters ausgeführt.
    {
      digitalWrite(LEDblau, HIGH);    //Schaltet die blaue LED ein.
      delay(500);   //Wartet 500ms.
      digitalWrite(LEDblau, LOW);   //Schalted die blaue LED aus.
    
      iPlayer[i] = 3;   //Speichert die Gewählte LED im, mit der Zahl i markierten, Fach des iPlayer[10] Regals ab.
      i++;    //Erhöt i um 1.
    }
    
    
    if (STATUSgruen == HIGH)    //Der Code wir nur nach druck des grünen Tasters ausgeführt.
    {
      digitalWrite(LEDgruen, HIGH);   //Schaltet die grüne LED ein.
      delay(500);   //Wartet 500ms.
      digitalWrite(LEDgruen, LOW);    //Schalted die grüne LED aus.
      
      iPlayer[i] = 5;   //Speichert die Gewählte LED im, mit der Zahl i markierten, Fach des iPlayer[10] Regals ab.
      i++;    //Erhöt i um 1.
    }
    
    
    if (STATUSgelb == HIGH)   //Der Code wir nur nach druck des gelben Tasters ausgeführt.
    {
      digitalWrite(LEDgelb, HIGH);    //Schaltet die gelbe LED ein.
      delay(500);   //Wartet 500ms.
      digitalWrite(LEDgelb, LOW);   //Schalted die gelbe LED aus.
      
      iPlayer[i] = 7;   //Speichert die Gewählte LED im, mit der Zahl i markierten, Fach des iPlayer[10] Regals ab.
      i++;    //Erhöt i um 1.
    }
    
    
    if (STATUSrot == HIGH)    //Der Code wir nur nach druck des roten Tasters ausgeführt.
    {
      digitalWrite(LEDrot, HIGH);   //Schaltet die rote LED ein.
      delay(500);   //Wartet 500ms.
      digitalWrite(LEDrot, LOW);    //Schalted die rote LED aus.
      
      iPlayer[i] = 9;   //Speichert die Gewählte LED im, mit der Zahl i markierten, Fach des iPlayer[10] Regals ab.
      i++;    //Erhöt i um 1.
    }
        
  }
  
  delay(500);   //Wartet 500ms.
  digitalWrite(LEDweis, HIGH);    //Schaltet die weiße LED ein.
  delay(500);   //Wartet 500ms.
  digitalWrite(LEDweis, LOW);   //Schaltet die weiße LED aus.
  delay(500);   //Wartet 500ms.
  
  WinCondition();
  /*
   Startet die Methode WinCondition(), und verhindert zugleich den volständigen durlauf der PlayerInput() Methode.
   Erst nach Durchlauf der WinCondition() Methode kehrt das Programm zu diesem Punkt zurück und erreicht das Ende von PlayerInput().
   Nach vollendung von PlayerInput() springt das Programm zurück in die Metode Random().
  */
  
}


void WinCondition()   //Überprüft ob der spieler die richtige Farbfolge eingegeben hat und zum nächsten Level übergeht.
{ 
  for (int i = 0; i < iLevel; i++)    // Wiederholt den Code bis i = iLevel und erhöt i um 1 nach jedem Durchlauf.
  {
    if (iRandom[i] == iPlayer[i])   //Der Code wird nur ausgeführt wenn, das mit i makierte Fach im iRandom[10] Regal und das mit i makierte Fach im iPlayer[10] Regal, den gleichen Inhalt haben.
    {
      //do nothing
    }
    else    //Der Code wird nur ausgeführt wenn die vorherige if-Bedingung nicht zutraf.
    {
      for (int j = 0; j < 5; j++)   //Wiederholt den Code bis j = 5 und erhöt j um 1 nach jedem Durchlauf.
      {
        delay(500);   //Wartet 500ms.
        digitalWrite(LEDweis, HIGH);    //Schaltet die Weißen LEDs ein.
        delay(500);   //Wartet 500ms.
        digitalWrite(LEDweis, LOW);   //Schaltet die weißen LEDs aus.
      }
      
      RandomArray();    //Startet die Methode RandomArray().
      iLevel = 3;   //Sezt das Level auf 3 zurück.
      return;   //Verlässt die WinCondition() Methode und kehrt zur PlayerInput() Methode zurück.
    }
    
  }
  
  if (iLevel < 10)    //Der Code wird nur ausgeführt wenn iLevel kleiner als 10 ist.
  {
    iLevel++;   //Erhöt iLevel um 1.
  }
  else if (iLevel == 10)    //Der Code wird nur ausgeführt wenn die forherige if-Bedingung nicht zutraf und iLevel = 10 ist.
  {
    digitalWrite(LEDweis, HIGH);    //Schaltet die weißen LEDs ein.
    
    for(int n = 0; n < 5; n++)  //Widerholt den Code bis n = 5 ist und erhöt n um 1 nach jedem Durchlauf.
    {
      digitalWrite(LEDgruen, LOW);    //Schaltet die grüne LED aus.
      digitalWrite(LEDrot, HIGH);   //Schaltet die rote LED ein.
      delay(300);   //Wartet 300ms.
      digitalWrite(LEDblau, LOW);   //Schaltet die blaue LED aus.
      digitalWrite(LEDgelb, HIGH);    //Schaltet die gelbe LED ein.
      delay(300);   //Wartet 300ms.
      digitalWrite(LEDrot, LOW);    //Schaltet die rote LED aus.
      digitalWrite(LEDgruen, HIGH);   //Schaltet die grüne LED ein.
      delay(300);   //Wartet 300ms.
      digitalWrite(LEDgelb, LOW);   //Schaltet die gelbe LED aus.
      digitalWrite(LEDblau, HIGH);    //Schaltet die blaue LED ein.
      delay(300);   //Wartet 300ms.
    }
    
    digitalWrite(LEDgruen, LOW);    //Schaltet die grüne LED aus.
    delay(300);   //Wartet 300ms.
    digitalWrite(LEDblau, LOW);   //Schaltet die blaur LED aus.
    digitalWrite(LEDweis, LOW);   //Schaltet die weißen LEDs aus.
    
    iLevel = 3;   //Sezt das Level auf 3 zurück.
    RandomArray();    //Startet die Methode RandomArray() und kehrt nach dessen Durchlauf hierhin zurück.
    return;   //Verlässt die WinCondition() Methode und kehrt zur PlayerInput() Methode zurück.
  }

  Random();
  /*
   Startet die Methode Random(), und verhindert zugleich den volständigen durlauf der WinCondition() Methode.
   Erst nach Durchlauf der Random() Methode kehrt das Programm zu diesem Punkt zurück und erreicht das Ende von WinCondition().
   Nach vollendung von Wincondition() springt das Programm zurück in die Metode PlayerInput().
  */
}