Lot­to­zah­len mit Zeit­stem­pel anzei­gen und auf einer SD-Kar­te speichern

Lese­zeit: 9 Minu­ten

Lösung
Seite als PDF

Der Ardui­no „spielt“ für dich 6 Zah­len. Anschlie­ßend wer­den die Lot­to­zah­len gezo­gen, auf­stei­gend sor­tiert und auf die Anzahl der rich­ti­gen Zah­len unter­sucht. Zu Beginn des Pro­gramms wird gefragt, ob die bestehen­de Datei „Lottozahlen.txt“ gelöscht wer­den soll.

Der Tas­ter erfüllt meh­re­re Funktionen:

  • ein Druck auf den Tas­ter: die Lot­to­zah­len wer­den mit Datum und Uhr­zeit im Seri­el­len Moni­tor angezeigt
  • Dop­pel­klick auf den Tas­ter: die Lot­to­zah­len wer­den mit Datum und Uhr­zeit auf der SD-Kar­te gespeichert
  • lan­ger Druck auf den Tas­ter: die auf der SD-Kar­te gespei­cher­ten Zah­len wer­den im Seri­el­len Moni­tor angezeigt

Die Lot­to­zah­len sol­len auf eine SD-Kar­te gespei­chert wer­den, das RTC-Modul ermit­telt das aktu­el­le Datum und die aktu­el­le Zeit.

Benö­tig­te Bauteile:

  • Tas­ter
  • SD-Kar­ten-Modul
  • RTC-Modul
  • Lei­tungs­dräh­te

Ach­te auf die Pin-Bele­gung des SD-Kar­ten-Moduls!
Die SD-Kar­te muss mit FAT32 for­ma­tiert sein!

SD-Kar­ten-Modul

So sieht es aus:

Baue die Schal­tung auf.
(Fah­re mit der Maus über das Bild, um die Bezeich­nun­gen der Bau­tei­le zu sehen)

Benö­tig­te Bibliotheken:

Bin­de die benö­tig­ten Biblio­the­ken ein und defi­nie­re die Variablen:

# include "SdFat.h"
# include "RTClib.h"
# include "OneButton.h"

// Bezeichnung der SD-Karte
SdFat SD;

// Bezeichnung des RTC-Moduls
RTC_DS3231 rtc;

// Bezeichnung der Textdatei
File ZiehungLotto;

// Datenpin für das SD-Kartenmodul
int DatenPin = 4;

// Daten-Logger-Shield
// int DatenPin = 10;

int TASTER = 7;

// Name des Tasters
OneButton NameTaster(TASTER, true);

// Array für die gezogenen Zahlen
int LottoZahl[6];

// Array für die angekreuzten Zahlen
int SpielZahl[6];

// Minimum/Maximum der Zufallszahlen
int Minimum = 1;
int Maximum = 49;

// Anzahl der zu ziehenden Zahlen
int Anzahl = 6;

Im set­up-Teil müs­sen das SD-Kar­ten-Modul und das RTC-Modul gestar­tet wer­den und die Abfra­ge vor­be­rei­tet werden:

void setup() 
{
  /*
    wenn Datum und Zeit nicht korrekt -> Datum/Zeit setzen
    Jahr, Monat, Tag, Stunde, Minute, Sekunde
    rtc.adjust(DateTime(2022, 8, 7, 11, 55, 30));
  */
  // RTC-Modul starten
  rtc.begin();
    
  // Zufallsgenerator starten
  randomSeed(analogRead(0));
  
  // Aktionen dem Modus des Tasters zuordnen
  NameTaster.attachClick(einKlick);
  NameTaster.attachDoubleClick(DoppelKlick);
  NameTaster.attachLongPressStop(langerDruckStopp);
  
  /*
    Anzahl der Millisekunden festlegen
    Standardwerte gesetzt:
    PressTicks: 1000
    ClickTicks: 600
    DebounceTicks: 50
    wenn die Standardwerte gesetzt werden sollen
    können die nächsten Zeilen auskommentiert werden
  */
  NameTaster.setPressTicks(1000);
  NameTaster.setClickTicks(500);
  NameTaster.setDebounceTicks(50);
  pinMode(TASTER, INPUT_PULLUP);
  Serial.begin(9600);
  
  // auf serielle Verbindung warten
  while (!Serial) {;}
  delay(500);
  
  /*
    SD-Karte mit Angabe des Datenpins starten
    wenn die Intialisierung fehlschlägt
    - keine SD-Karte vorhanden
    - falsche Pinbelegung
    → es wird eine Fehlermeldung angezeigt
  */
  if (!SD.begin(DatenPin)) 
  {
    Serial.println(F("Initialisierung fehlgeschlagen!"));
  } 
  else Serial.println(F("Initialisierung abgeschlossen"));
  
  // Menü
  Serial.print(F("kurzer Druck auf den Taster "));
  Serial.println(F("-> Lottozahlen im Seriellen Monitor anzeigen"));
  Serial.print(F("Doppelklick auf den Taster"));
  Serial.println(F("-> Lottozahlen speichern"));
  Serial.print(F("langer Druck auf den Taster "));
  Serial.println(F("-> Datei lesen und Lottozahlen im Seriellen Monitor anzeigen"));
  Serial.println(F("Datei Lottozahlen.txt l\u00f6schen (j/n)?"));
}
Download

Ver­wen­de für Bestim­mung der Spiel­zah­len und die ➨Zie­hung der Lot­to­zah­len die ➨Funk­ti­on Ziehung.

int Ziehung() 
{
  for (int i = 0; i < Anzahl; i++) 
  {
    /*
      die Lottozahl gilt solange als bereits gezogen
      bis in der for-Schleife nachgewiesen wird, dass sie neu ist
      und BereitsGezogen den Wert false hat
    */
    bool BereitsGezogen = true;
    while (BereitsGezogen) 
    {
      // Zahl ziehen
      LottoZahl[i] = random(Minimum, Maximum);
      BereitsGezogen = false;
      /*
        Zufallszahl mit den bereits gezogenen Zahlen vergleichen
        i wird in der ersten for-Schleife hochgezählt
        alle bisherigen Zahlen (ii) werden mit den bisher gezogenen
        (außer der gerade gezogenen) verglichen (ii < i)
        ist sie identisch, erhält BereitsGezogen den Wert true
        es wird erneut eine Zufallszahl bestimmt
        wenn die Zahl neu ist, (BereitsGezogen hat noch den Wert false)
        wird die while-Schleife verlassen und die nächste Zahl gezogen
      */
      for (int ii = 0; ii < i; ii++) 
      {
        if (LottoZahl[i] == LottoZahl[ii]) BereitsGezogen = true;
      }
    }
  }
  /*
    das Array mit den Zahlen wird an das Hauptprogramm zurückgegeben
    beim ersten Aufruf sind es die gespielten Zahlen
    beim zweiten Aufruf die gezogenen Lottozahlen
  */
  return LottoZahl[Anzahl];
}

Im loop-Teil wird die Ein­ga­be ver­ar­bei­tet und der Tas­ter abgefragt.

void loop() 
{
   // Serielle Eingabe "Datei löschen" lesen
  while (Serial.available() > 0) 
  {
    while (Serial.available() > 0)
    {
      char Eingabe = Serial.read();
      /*
        prüfen, ob die Datei existiert
        wenn ja → Datei Lottozahlen.txt löschen
      */
      if (Eingabe == 'j')
      {
        if (SD.exists("Lottozahlen.txt"))
        {
          // Datei entfernen
          SD.remove("Lottozahlen.txt");
          Serial.println(F("Datei Lottozahlen.txt entfernt!"));
        }
        else
        {
          Serial.println(F("Datei Lottozahlen.txt existiert nicht!"));
        }
      }
      
      else if (Eingabe == 'n')
      {
        Serial.println(F("Lottozahlen werden der Datei Lottozahlen.txt hinzugefügt!"));
      }
    }
  }

  // Taster alle 10 Millisekunden abfragen
  NameTaster.tick();
  delay(10);
}

Die Funk­tio­nen:

  • ein­Klick() → Seri­el­le Aus­ga­be der Lottozahlen
  • Dop­pel­klick() → Lot­to­zah­len auf der SD-Kar­te speichern
  • lan­ger­Druck­Stopp() - Datei lesen und im Seri­el­len Moni­tor anzeigen
  • Zah­len­Sor­tie­ren() → Lot­to­zah­len sortieren
void einKlick()
{
  String AnzahlTreffer = "";
  String GespielteZahlen = "";
  String GezogeneZahlen = "";
  int Treffer = 0;

  // aktuelle Zeit holen
  DateTime aktuell = rtc.now();

  char Datum[] = "DD.MM.YYYY";
  Serial.print(aktuell.toString(Datum));

  // Zeit schreiben
  char Zeit[] = " Uhrzeit: hh:mm:ss";
  Serial.println(aktuell.toString(Zeit));

  // Ziehung der "angekreuzten" Zahlen
  Ziehung();
  ZahlenSortieren(LottoZahl, 6);

  for (int i = 0; i < Anzahl; i ++)
  {
    // String GespielteZahlen aus den Elementen des Arrays
    // LottoZahl zusammensetzen
    GespielteZahlen = GespielteZahlen + LottoZahl[i] + " ";
    /*
      dem Array SpielZahl (die „gespielten“ Zahlen)
      wird das identische Element des Arrays LottoZahl zugewiesen
      Dieser Schritt darf für die Ziehung der Lottozahlen
      nicht wiederholt werden.
    */
    SpielZahl[i] = LottoZahl[i];
  }

  // Ziehung der Lottozahlen
  Ziehung();

  // Zahlen sortieren
  ZahlenSortieren(LottoZahl, 6);

  // Vergleichen der Elemente der Arrays SpielZahl und LottoZahl
  for (int i = 0; i < Anzahl; i++)
  {
    for (int ii = 0; ii < Anzahl; ii++)
    {
      // Übereinstimmung gefunden -> Treffer um 1 erhöhen
      // AnzahlTreffer: String für übereinstimmende Zahlen erzeugen
      if (SpielZahl[i] == LottoZahl[ii])
      {
        AnzahlTreffer = AnzahlTreffer + SpielZahl[i] + " ";
        Treffer ++;
      }
    }
  }

  // String GezogeneZahlen aus den Elementen des Arrays LottoZahl
  // zusammensetzen
  for (int i = 0; i < Anzahl; i++)
  {
    GezogeneZahlen = GezogeneZahlen + LottoZahl[i] + " ";
  }
  // Daten im Seriellen Monitor anzeigen
  Serial.println("Gespielte Zahlen");
  Serial.println(GespielteZahlen);
  Serial.println("-----------------------------");
  Serial.println("Gezogene Zahlen");
  Serial.println(GezogeneZahlen);
  Serial.println("-----------------------------");

  // keine Treffer
  if (Treffer == 0) Serial.println("keine Treffer!");

  // getroffene Zahlen anzeigen
  else Serial.println("Treffer: " + AnzahlTreffer);
  Serial.println("-----------------------------");
}
void DoppelKlick()
{
  String AnzahlTreffer = "";
  String GespielteZahlen = "";
  String GezogeneZahlen = "";
  int Treffer = 0;

  // aktuelle Zeit holen
  DateTime aktuell = rtc.now();

  char Datum[] = "DD.MM.YYYY";
  Serial.print(aktuell.toString(Datum));

  // Zeit schreiben
  char Zeit[] = " Uhrzeit: hh:mm:ss";
  Serial.println(aktuell.toString(Zeit));

  // Ziehung der "angekreuzten" Zahlen
  Ziehung();
 
  ZahlenSortieren(LottoZahl, 6);

  // String GespielteZahlen aus den Elementen des Arrays LottoZahl
  // zusammensetzen
  for (int i = 0; i < Anzahl; i++)
  {
    GespielteZahlen = GespielteZahlen + LottoZahl[i] + " ";
    SpielZahl[i] = LottoZahl[i];
  }

  // Ziehung der Lottozahlen
  Ziehung();

  // Zahlen sortieren
  ZahlenSortieren(LottoZahl, 6);
  
  // Vergleichen der Elemente der Arrays SpielZahl und LottoZahl
  for (int i = 0; i < Anzahl; i++)
  {
    for (int ii = 0; ii < Anzahl; ii++)
    {
      // Übereinstimmung gefunden -> Treffer um 1 erhöhen
      // AnzahlTreffer: String für übereinstimmende Zahlen erzeugen
      if (SpielZahl[i] == LottoZahl[ii])
      {
        AnzahlTreffer = AnzahlTreffer + SpielZahl[i] + " ";
        Treffer ++;
      }
    }
  }

  // String GezogeneZahlen aus den Elementen des Arrays LottoZahl
  // zusammensetzen
  for (int i = 0; i < Anzahl; i++)
  {
    GezogeneZahlen = GezogeneZahlen + LottoZahl[i] + " ";
  }

  /*
    O_CREAT -> Datei erstellen, wenn sie nicht existiert
    O_WRITE -> in die Date schreiben
    O_AT_END -> Startposition zum Schreiben an das Ende der Datei setzen
  */
  ZiehungLotto = SD.open("Lottozahlen.txt", O_CREAT | O_WRITE | O_AT_END);

  if (ZiehungLotto)
  {

    Serial.println(F("Schreibe Zahlen in Lottozahlen.txt ... "));
    Serial.println(F("-----------------------------"));

    char Datum[] = "DD.MM.YYYY";
    ZiehungLotto.print(aktuell.toString(Datum));

    // Zeit schreiben
    char Zeit[] = " Uhrzeit: hh:mm:ss";
    ZiehungLotto.println(aktuell.toString(Zeit));

    // Daten in die Datei schreiben
    ZiehungLotto.println("Gespielte Zahlen");
    ZiehungLotto.println(GespielteZahlen);
    ZiehungLotto.println("-----------------------------");
    ZiehungLotto.println("Gezogene Zahlen");
    ZiehungLotto.println(GezogeneZahlen);
    ZiehungLotto.println("-----------------------------");

    // keine Treffer
    if (Treffer == 0) ZiehungLotto.println("keine Treffer!");

    // getroffene Zahlen anzeigen
    else ZiehungLotto.println("Treffer: " + AnzahlTreffer);
    ZiehungLotto.println("-----------------------------");

    // Datei schließen
    ZiehungLotto.close();
    Serial.println(F("Abgeschlossen."));
    Serial.println();
  }

  else
  {
    Serial.println(F("Datei Lottozahlen.txt konnte nicht gelesen werden"));
  }
}
void langerDruckStopp()
{
  // Datei öffnen und Zahlen anzeigen
  ZiehungLotto = SD.open("Lottozahlen.txt");
  if (ZiehungLotto)
  {
    Serial.println(F("Lese Lottozahlen.txt ..."));

    // solange sich Zeilen in der Datei befinden ...
    while (ZiehungLotto.available())
    {
      // ... werden sie gelesen und im Seriellen Monitor ausgegeben
      Serial.write(ZiehungLotto.read());
    }
    // Datei schließen
    ZiehungLotto.close();
  }
  else
  {
    Serial.println(F("Lottozahlen konnte nicht ge\u00f6ffnet werden"));
  }
}
void ZahlenSortieren(int Zahlen[], int Groesse)
{
  // unsortierten Bereich des Arrays durchlaufen
  for (int i = 0; i < (Groesse - 1); i++)
  {
    // bei jedem Durchlauf wird das jeweils letzte Element weggelassen
    for (int ii = 0; ii < (Groesse - (i + 1)); ii++)
    {
      /*
        wenn die aktuelle Zahl größer als die nachfolgende Zahl ist
        -> aktuelle Zahl temporär speichern
        -> Zahlen vertauschen
        -> temporäre Zahl der nachfolgenden Zahl zuweisen
      */
      if (Zahlen[ii] > Zahlen[ii + 1])
      {
        int zwischengespeicherteZahl = Zahlen[ii];
        Zahlen[ii] = Zahlen[ii + 1];
        Zahlen[ii + 1] = zwischengespeicherteZahl;
      }
    }
  }
}

Startseite
Aufgaben A-Z
Suchen
Downloads
Fehlermeldungen
Seite als PDF

Ver­wand­te Aufgaben:


Letzte Aktualisierung: 6. Okt 2023 @ 11:02