Ent­fer­nun­gen LCD

#include "LCDIC2.h"

// 4-zeiliges Display
LCDIC2 lcd(0x27, 20, 4);

// 2-zeiliges Display
// LCDIC2 lcd(0x3f, 16, 2);

// Pins für Senden/Empfangen definieren
#define SENDEN 9
#define ECHO 8

// Variable für Zeit und Entfernung initialisieren 
long Zeit;
long Entfernung;

void setup() 
{ 
  pinMode(SENDEN, OUTPUT); 
  pinMode(ECHO, INPUT); 

  // LCD starten
  lcd.begin();

  // Cursor "verstecken"
  lcd.setCursor(false);
}

void loop() 
{  
  // Sender kurz ausschalten um Störungen des Signals zu vermeiden   
  digitalWrite(SENDEN, LOW);
  delay(10); 

  // Signal für 10 Mikrosekunden senden 
  digitalWrite(SENDEN, HIGH); 
  delayMicroseconds(10);

  // Sender ausschalten
  digitalWrite(SENDEN, LOW); 

  // pulseIn ⇒ Zeit messen, bis das Signal zurückkommt 
  Zeit = pulseIn(ECHO, HIGH);

  /*
    Entfernung in cm berechnen   
    Zeit/2 ⇒ nur eine Strecke soll berechnet werden      
    Umrechnung in cm  
  */ 
  Entfernung = (Zeit / 2) * 0.03432;   

  // 200 cm ist die maximal messbare Entfernung 
  if (Entfernung < 200) 
  {  
    /*
      2-zeiliges LCD
      lcd.setCursor(0, 0);
      lcd.print("Entfernung: ");
      lcd.print(String(Entfernung));
      lcd.print(" cm    ");
    */

    // 4-zeiliges LCD
    lcd.setCursor(0, 0);
    lcd.print("Entfernung messen");
    lcd.setCursor(0, 1);
    lcd.print("--------------------");
    lcd.setCursor(0, 2);
    lcd.print("Entfernung: ");
    lcd.print(String(Entfernung));
    lcd.print(" cm    ");
    delay(1000);
  }
}

Letzte Aktualisierung:

Lot­to­zah­len mit Zeit­stem­pel SD-Karte

#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 = 8;

// 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;

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(A0));
  
  // 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)?"));
}

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);
}

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 "bauen"
  for (int i = 0; i < Anzahl; i++)
  {
    GezogeneZahlen = GezogeneZahlen + LottoZahl[i] + " ";
  }

  // Daten zeigen
  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 "bauen"
  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 "bauen"
  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;
      }
    }
  }
}

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];
}

Letzte Aktualisierung:

Spiel RGB-Matrix

#include "Adafruit_NeoMatrix.h"

#define RGBMatrixPin 7

// Anzahl der LEDs für das Pixelmuster ⇒ kann angepasst werden
#define AnzahlLED 40

// RGBMatrix -> Name der Matrix
Adafruit_NeoMatrix RGBMatrix = Adafruit_NeoMatrix(8, 8, RGBMatrixPin,
                               NEO_MATRIX_TOP + NEO_MATRIX_RIGHT +
                               NEO_MATRIX_COLUMNS + NEO_MATRIX_PROGRESSIVE,
                               NEO_GRB + NEO_KHZ800);
                               
// Farben definieren
#define Schwarz      RGBMatrix.Color(0,0,0)
#define Rot          RGBMatrix.Color(255,0,0)
#define Gruen        RGBMatrix.Color(0,255,0)
#define Blau         RGBMatrix.Color(0,0,255)
#define Magenta      RGBMatrix.Color(139,0,139)
#define Pink         RGBMatrix.Color(255,20,147)
#define Weiss        RGBMatrix.Color(255,255,255)
#define Gelb         RGBMatrix.Color(255,255,0)
#define MarineBlau   RGBMatrix.Color(0,0,128)
#define DunkelGruen  RGBMatrix.Color(0,100,0)
#define Golden       RGBMatrix.Color(205,149,12)
#define ZufallsFarbe RGBMatrix.Color(random(1, 255), random(1, 255), random(1, 255))

// PixelFarbe  -> Farbe der zufällig leuchtenden Pixel
// PixelCursor -> Farbe des sich bewegenden Pixels
#define PixelFarbe Blau
#define PixelCursor Gelb

// Variablen der Zeit
float StartZeit;
float VerstricheneZeit;
float Sekunden;

// entscheidet über den Neustart
bool Start = true;

int AnzahlKlicks = 1;

// Startposition der LED
int Zeile = 4;
int Spalte = 4;
int Taster;
int Analogwert;

void setup()
{
  // setBrightness(0..255)
  RGBMatrix.setBrightness(10);

  // NeoPixel Bibliothek initialisieren
  RGBMatrix.begin();

  // Zufallsgenerator starten
  randomSeed(analogRead(A0));
  Serial.begin(9600);
}

int Tasterabfrage()
{
  Analogwert = analogRead(A0);

  // kurzes delay() -> doppelten Tastendruck so weit wie möglich verhindern
  delay(200);
  /* 
     A0 gibt je nach Taster einen Wert aus
     über den Seriellen Monitor kann dieser Wert angezeigt
     und kann dann eventuell angepasst werden
  */
  // Serial.println(Analogwert);  
  switch (Analogwert)
  {
    case 0 ... 20:
      Taster = 1;
      break;
    case 30 ... 60:
      Taster = 2;
      break;
    case  70 ... 120:
      Taster = 3;
      break;
    case 150 ... 200:
      Taster = 4;
      break;
    case 300 ... 400:
      Taster = 5;
      break;
    default:
      return 0;
  }

  // gedrückten Taster zurückgeben
  return Taster;
}

void ParcoursBauen()
{
  int Minimum = 0;
  int Maximum = 8;
  RGBMatrix.clear();

  for (int i = 0; i < AnzahlLED; i++)
  {
    // Zufallsposition der Pixel
    Spalte =  random(Minimum, Maximum);
    Zeile =  random(Minimum, Maximum);

    RGBMatrix.drawPixel(Zeile, Spalte, PixelFarbe);
  }
  Zeile = 4;
  Spalte = 4;
  RGBMatrix.drawPixel(Zeile, Spalte, PixelCursor);
  RGBMatrix.show();
}

void loop()
{
  // wenn Start = true -> Parcour erstellen
  if (Start)
  {
    RGBMatrix.clear();
    ParcoursBauen();
    Start = false;
    StartZeit = millis();
    int Zeile = 4;
    int Spalte = 4;
  }

  Taster = Tasterabfrage();

  // Ergebnisse anzeigen und Neustart
  if (Taster == 5)
  {
    Start = true;

    // Zeit berechnen
    float Sekunden;
    VerstricheneZeit = millis() - StartZeit;
    Sekunden = VerstricheneZeit / 1000;
    String GesamtSekunden = String(Sekunden);

    // . durch , ersetzen
    GesamtSekunden.replace(".", ",");

    // Ausgabe im Seriellen Monitor
    Serial.println("Sekunden insgesamt: " + GesamtSekunden + " Sekunden");

    // Minuten berechnen
    int Minute  = int(Sekunden) / 60;

    // nur Ausgabe der Minuten wenn Minute > 0
    if (Minute > 0)
    {
      // Ausgabe verschönern, wenn Minute > 1 -> Ausgabe "Minuten"
      // "Minute"
      if (Minute > 1)
      {
        Serial.print(String(Minute) + " Minuten ");
      }
      else
      {
        Serial.print(String(Minute) + " Minute ");
      }
    }
    // von Sekunden Anzahl der Minuten abziehen
    Sekunden = Sekunden - Minute * 60;

    // Sekunden in String umwandeln
    // damit . durch , ersetzt werden kann
    String AnzahlSekunden = String(Sekunden);

    // . durch , ersetzen
    AnzahlSekunden.replace(".", ",");
    Serial.println(AnzahlSekunden + " Sekunden");
    Serial.println(String(AnzahlKlicks) + " Klicks!");
    AnzahlKlicks = 1;
  }

  /*
    bei der Matrix gibt es kein oben oder unten
    links oder rechts
    die Funktion der Tasten muss durch Drehen der Matrix
    entsprechend angepasst werden
  */

  // links
  if (Taster == 1)
  {
    RGBMatrix.drawPixel(Zeile, Spalte, Schwarz);
    if (Zeile < 7) Zeile++;
    RGBMatrix.drawPixel(Zeile, Spalte, PixelCursor);
    RGBMatrix.show();
    AnzahlKlicks ++;
  }

  // oben
  if (Taster == 2)
  {
    RGBMatrix.drawPixel(Zeile, Spalte, Schwarz);
    if (Spalte < 7) Spalte++;
    RGBMatrix.drawPixel(Zeile, Spalte, PixelCursor);
    RGBMatrix.show();
    AnzahlKlicks ++;
  }

  // unten
  if (Taster == 3)
  {
    RGBMatrix.drawPixel(Zeile, Spalte, Schwarz);
    if (Spalte > 0) Spalte--;
    RGBMatrix.drawPixel(Zeile, Spalte, PixelCursor);
    RGBMatrix.show();
    AnzahlKlicks ++;
  }

  // rechts
  if (Taster == 4)
  {
    RGBMatrix.drawPixel(Zeile, Spalte, Schwarz);
    if (Zeile > 0) Zeile--;
    RGBMatrix.drawPixel(Zeile, Spalte, PixelCursor);
    RGBMatrix.show();
    AnzahlKlicks ++;
  }
}

Letzte Aktualisierung:

Taschen­rech­ner Grund­re­chen­ar­ten auf LCD

#include "LCDIC2.h"

// LCD Adresse/Namen festlegen
LCDIC2 lcd(0x27, 20, 4);

String Eingabe;
String Rechnung;
float Ergebnis;
bool BuchstabeGefunden = false;
bool DivisionNull = false;

void setup()
{
  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial);
  delay(1000);

  // LCD einschalten
  lcd.begin();

  // Cursor "verstecken"
  lcd.setCursor(false);

  // Erklärung anzeigen Serieller Monitor
  Serial.println("Taschenrechner");
  Serial.println("_______________________");
  Serial.println("+\tAddition");
  Serial.println("-\tSubtraktion");
  Serial.println("*\tMultiplikation");
  Serial.println(":\tDivision");
  Serial.println("_______________________");

  // LCD
  lcd.setCursor(0, 0);
  lcd.print("+ Addition");
  lcd.setCursor(0, 1);
  lcd.print("- Subtraktion");
  lcd.setCursor(0, 2);
  lcd.print("* Multiplikation");
  lcd.setCursor(0, 3);
  lcd.print(": Division");
}

void loop()
{
  String GleichZeichen = " = ";
  lcd.setCursor(0, 0);
  while (Serial.available() > 0)
  {
    // solange lesen, bis return \n = return eingegeben wurde
    Eingabe = Serial.readStringUntil('\n');

    lcd.clear();

    // Addition
    // "+" Zeichen suchen
    if (Eingabe.indexOf('+') > 0)
    {
      int PlusZeichen = Eingabe.indexOf('+');

      // erster Summand: von 0 bis zur Position des Pluszeichens
      String SummandEins = Eingabe.substring(0, PlusZeichen);

      // Leerzeichen entfernen
      SummandEins.trim();
      
      // für die Rechnung , durch . ersetzen
      SummandEins.replace(",", ".");

      // zweiter Summand: von der Position hinter dem Pluszeichen
      // bis zum letzten Zeichen
      String SummandZwei = Eingabe.substring(PlusZeichen + 1, Eingabe.length());

      // Leerzeichen entfernen
      SummandZwei.trim();

      // für die Rechnung , durch . ersetzen
      SummandZwei.replace(",", ".");

      // rechnen
      Ergebnis = SummandEins.toFloat() + SummandZwei.toFloat();

      // prüfen, ob Ergebnis eine natürliche Zahl
      String StringPruefen = NullEntfernen(String(Ergebnis));

      // String Rechnung "zusammenbauen"
      Rechnung = SummandEins + " + " + SummandZwei + GleichZeichen + String(StringPruefen);

      Rechnung.replace(".", ",");

      BuchstabeGefunden = BuchstabeSuchen(SummandEins + SummandZwei);
    }

    // Subtraktion
    // "-" Zeichen suchen
    if (Eingabe.indexOf('-') > 0)
    {
      int MinusZeichen = Eingabe.indexOf('-');

      // Minuend: von 0 bis zur Position des Minuszeichens
      String Minuend = Eingabe.substring(0, MinusZeichen);

      // Leerzeichen entfernen
      Minuend.trim();

      // für die Rechnung , durch . ersetzen
      Minuend.replace(",", ".");

      // Subtrahend: von der Position hinter dem Minuszeichen
      // bis zum letzten Zeichen
      String Subtrahend = Eingabe.substring(MinusZeichen + 1, Eingabe.length());

      // Leerzeichen entfernen
      Subtrahend.trim();

      // für die Rechnung , durch . ersetzen
      Subtrahend.replace(",", ".");

      // rechnen
      Ergebnis = Minuend.toFloat() - Subtrahend.toFloat();

      // prüfen, ob Ergebnis eine natürliche Zahl
      String StringPruefen = NullEntfernen(String(Ergebnis));

      // String Rechnung "zusammenbauen"
      Rechnung = Minuend + " - " + Subtrahend + GleichZeichen + String(StringPruefen);
      Rechnung.replace(".", ",");

      // nach Buchstaben suchen
      BuchstabeGefunden = BuchstabeSuchen(Subtrahend + Minuend);
    }

    // Multiplikation
    // "*" Zeichen suchen
    if (Eingabe.indexOf('*') > 0)
    {
      int MalZeichen = Eingabe.indexOf('*');

      // erster Faktor: von 0 bis zur Position des Malzeichens
      String FaktorEins = Eingabe.substring(0, MalZeichen);

      // Leerzeichen entfernen
      FaktorEins.trim();

      // für die Rechnung , durch . ersetzen
      FaktorEins.replace(",", ".");

      // zweiter Faktor: von der Position hinter dem Malzeichen
      // bis zum letzten Zeichen
      String FaktorZwei = Eingabe.substring(MalZeichen + 1, Eingabe.length());

      // Leerzeichen entfernen
      FaktorZwei.trim();

      // für die Rechnung , durch . ersetzen
      FaktorZwei.replace(",", ".");

      // rechnen
      Ergebnis = FaktorEins.toFloat() * FaktorZwei.toFloat();

      // prüfen, ob Ergebnis eine natürliche Zahl
      String StringPruefen = NullEntfernen(String(Ergebnis));

      // String Rechnung "zusammenbauen"
      Rechnung = FaktorEins + " * " + FaktorZwei + GleichZeichen + String(StringPruefen);
      Rechnung.replace(".", ",");
    }

    // Division
    // ":" Zeichen suchen
    if (Eingabe.indexOf(':') > 0)
    {
      int GeteiltZeichen = Eingabe.indexOf(':');
      // Dividend: von 0 bis zur Position des Geteiltzeichens
      String Dividend = Eingabe.substring(0, GeteiltZeichen);

      // Leerzeichen entfernen
      Dividend.trim();

      Dividend.replace(",", ".");

      // Divisor: von der Position hinter dem Geteiltzeichen
      // bis zum letzten Zeichen
      String Divisor = Eingabe.substring(GeteiltZeichen + 1, Eingabe.length());

      // Leerzeichen entfernen
      Divisor.trim();
      Divisor.replace(",", ".");

      /* String Rechnung "zusammenbauen"
         Besonderheit: das Ergebnis einer Division kann eine Kommazahl sein
         -> Datentyp float -> Kommazahlen
         Ergebnis zeigt nur 2 Nachkommastellen
      */

      // Division durch 0 nicht möglich
      if (Divisor == "0")
      {
        DivisionNull = true;

        // String Rechnung ohne Ergebnis "zusammenbauen"
        Rechnung = Dividend + " : " + Divisor + GleichZeichen;
      }

      // Divisor != 0 -> rechnen
      else
      {
        Ergebnis = Dividend.toFloat() / Divisor.toFloat();
        String StringPruefen = NullEntfernen(String(Ergebnis));

        // String Rechnung "zusammenbauen"
        Rechnung = Dividend + " : " + Divisor + GleichZeichen + String(StringPruefen);
        BuchstabeGefunden = BuchstabeSuchen(Dividend + Divisor);

        // . durch , ersetzen
        Rechnung.replace(".", ",");
      }
    }

    // wenn kein Buchstabe gefunden wurde oder Divisor != 0 -> Rechnung ausgeben
    if (!BuchstabeGefunden && !DivisionNull) RechnungAusgeben();

    // Division durch 0 -> Meldung anzeigen
    if (DivisionNull)
    {
      Serial.println(Rechnung);
      Serial.println("Division durch 0 ist verboten ;-)");
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(Rechnung);
      lcd.setCursor(0, 1);
      lcd.print("Divison durch 0");
      lcd.setCursor(0, 2);
      lcd.print("ist verboten ;-)");
    }

    // Buchstabe eingegeben -> Meldung anzeigen
    if (BuchstabeGefunden)
    {
      Rechnung = Rechnung.substring(0, Rechnung.indexOf('='));
      Serial.println(Rechnung);
      Serial.println("Buchstaben sind nicht erlaubt ;-)");
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(Rechnung);
      lcd.setCursor(0, 1);
      lcd.print("Buchstaben sind ");
      lcd.setCursor(0, 2);
      lcd.print("nicht erlaubt ;-)");
    }

    // Eingaben löschen, Fehlervariablen auf false setzen
    Rechnung = "";
    Eingabe = "";
    DivisionNull = false;
    BuchstabeGefunden = false;
  }
}

void RechnungAusgeben()
{
  // Ausgabe Serieller Monitor
  Serial.println(Rechnung);

  // Ausgabe LCD
  lcd.clear();

  // Ergebnis zu String umwandeln, damit die Länge bestimmt werden kann
  String LaengeErgebnis = String(Ergebnis);

  lcd.setCursor(0, 0);
  int laenge = Rechnung.length();

  // wenn die Länge der Rechnung > 20
  if (laenge > 20)
  {
    // Position des =-Zeichen bestimmen
    int GleichZeichen = Rechnung.indexOf('=');

    // Rechnung bis =-Zeichen anzeigen
    lcd.print(Rechnung.substring(0, GleichZeichen + 1 ));

    // Ergebnis anzeigen
    lcd.setCursor(0, 1);
    lcd.print(Rechnung.substring(GleichZeichen + 2, Rechnung.length()));
  }

  // Rechnung passt in eine Zeile
  else lcd.print(Rechnung);
}

bool BuchstabeSuchen(String Pruefen)
{
  bool BuchstabeGefunden = false;

  // wenn das Zeichen im zu prüfenden String ein Buchstabe (isAlpha) ist
  // -> BuchstabeGefunden = true
  for (int i = 0; i < Pruefen.length(); i++)
  {
    if (isAlpha(Pruefen.charAt(i)))
    {
      BuchstabeGefunden = true;

      // nicht weiter suchen Schleife verlassen
      break;
    }
  }

  return BuchstabeGefunden;
}

String NullEntfernen(String PruefString)
{
  String TestString;
  PruefString.replace(" ", "");

  // wenn die letzten Ziffern 00 sind -> Ergebnis ist natürliche Zahl
  if (PruefString.indexOf(".00") > 0)
  {
    TestString = PruefString.substring(0, PruefString.indexOf(".00"));
  }
  else TestString = PruefString;

  return TestString;
}

Letzte Aktualisierung:

Töne erzeu­gen Tastenfeld

#include "Adafruit_Keypad.h"

int LAUTSPRECHER = 13;

// Größe des Tastenfeldes
// 3 Spalten
const byte SPALTEN = 3;

// 4 Zeilen
const byte REIHEN = 4;

// die Ziffern/Zeichen:
// Array 3 x 4
char Tasten[REIHEN][SPALTEN] =
{
  { '#', '0', '*' },
  { '9', '8', '7' },
  { '6', '5', '4' },
  { '3', '2', '1' }
};

// die Pins für die 3 Spalten
byte SpaltenPins[SPALTEN] = { 3, 4, 5 };

// die Pins für die 4 Zeilen
byte ReihenPins[REIHEN] = { 6, 7, 8, 9 };

// TastenFeld ⇒ Name des Keypads
// -> Zuordnung der Pins zu den REIHEN und SPALTEN des Arrays
Adafruit_Keypad Tastenfeld = Adafruit_Keypad(makeKeymap(Tasten), ReihenPins, SpaltenPins, REIHEN, SPALTEN);

/*
  C-Dur Tonleiter Frequenzen
  c'  -> 264
  d'  -> 297
  e'  -> 330
  f'  -> 352
  g'  -> 396
  a'  -> 440
  h'  -> 495
  c'' -> 528
*/

void setup()
{
  // Tastenfeld starten
  Tastenfeld.begin();

  pinMode(LAUTSPRECHER, OUTPUT);
  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial) { ; }
}

void loop()
{
  // gedrückte Taste lesen
  Tastenfeld.tick();

  while (Tastenfeld.available())
  {
    keypadEvent Taste = Tastenfeld.read();

    // wenn die Taste losgelassen wurde -> Lautsprecher ausschalten
    if (Taste.bit.EVENT == KEY_JUST_RELEASED) noTone(LAUTSPRECHER);

    // solange die Taste gedrückt wird -> Ton abspielen
    if (Taste.bit.EVENT == KEY_JUST_PRESSED)
    {
      // ASCII-Code der gedrückten Taste anzeigen
      Serial.println(Taste.bit.KEY);

      /*
         Tastencode entspricht dem ASCII-Code:
         49 = 1
         50 = 2
         . . . 
         56 = 8
       */
      switch (Taste.bit.KEY)
      {
        case 49:
          tone(LAUTSPRECHER, 264);
          break;

        case 50:
          tone(LAUTSPRECHER, 297);
          break;

        case 51:
          tone(LAUTSPRECHER, 330);
          break;

        case 52:
          tone(LAUTSPRECHER, 352);
          break;

        case 53:
          tone(LAUTSPRECHER, 396);
          break;

        case 54:
          tone(LAUTSPRECHER, 440);
          break;

        case 55:
          tone(LAUTSPRECHER, 495);
          break;
          
        case 56:
          tone(LAUTSPRECHER, 520);
          break;
      }
    }
  }
}

Letzte Aktualisierung:

Leucht­stär­ke von LEDs mit Joy­stick ändern

// PWM-Pins 
int GRUEN = 5; 
int ROT = 6; 

// Button/Knopf 
int JoystickButton = 7; 

// analoge Pins 
int XAchse = A0; 
int YAchse = A1; 

// Variablen für die Auswertung der Bewegung des Joysticks 
int PositionX; 
int PositionY; 

// Leuchstärke der LEDs (0-255) 
int LeuchtStaerkeRot; 
int LeuchtStaerkeGruen; 

// Zustand des Buttons 
int ButtonLesen;

void setup() 
{ 
  Serial.begin(9600);
  pinMode(ROT, OUTPUT); 
  pinMode(GRUEN, OUTPUT); 
  pinMode(JoystickButton, INPUT_PULLUP); 
}

void loop() 
{ 
  // Bewegung der X-Achse lesen 
  PositionX = analogRead(XAchse); 

  // Bewegung X-Achse nach oben 
  if (PositionX > 600) 
  { 
    // bei der PWM darf die Leuchstärke 255 nicht übersteigen 
    if (LeuchtStaerkeRot < 255) 
    { 
      // Helligkeit um 1 erhöhen 
      LeuchtStaerkeRot = LeuchtStaerkeRot + 1; 
      
      // rote LED einschalten 
      analogWrite(ROT, LeuchtStaerkeRot); 
      delay(20); 
    }     
    Serial.println("Helligkeit rote LED: " + String(LeuchtStaerkeRot));
    Serial.println("Helligkeit grüne LED: " + String(LeuchtStaerkeGruen));
  } 

  // Bewegung X-Achse nach unten 
  if (PositionX < 300) 
  { 
    // solange die Helligkeit > 0 
    // -> Helligkeit um 1 verringern 
    if (LeuchtStaerkeRot > 0) 
    { 
      LeuchtStaerkeRot = LeuchtStaerkeRot - 1; 
      analogWrite(ROT, LeuchtStaerkeRot); 
      delay(20); 
    } 
    Serial.println("Helligkeit rote LED: " + String(LeuchtStaerkeRot));
    Serial.println("Helligkeit grüne LED: " + String(LeuchtStaerkeGruen));
  } 

  // Bewegung der Y-Achse lesen 
  PositionY = analogRead(YAchse); 

  // Bewegung Y-Achse nach rechts 
  if (PositionY > 600) 
  { 
    if (LeuchtStaerkeGruen > 0) 
    { 
      LeuchtStaerkeGruen = LeuchtStaerkeGruen - 1; 
      analogWrite (GRUEN, LeuchtStaerkeGruen); 
      delay(20); 
    } 
    Serial.println("Helligkeit rote LED: " + String(LeuchtStaerkeRot));
    Serial.println("Helligkeit grüne LED: " + String(LeuchtStaerkeGruen));
  } 

  // Bewegung Y-Achse nach links 
  if (PositionY < 300) 
  { 
    if (LeuchtStaerkeGruen < 255) 
    { 
      LeuchtStaerkeGruen = LeuchtStaerkeGruen + 1; 
      analogWrite(GRUEN, LeuchtStaerkeGruen); 
      delay(20); 
    } 
    Serial.println("Helligkeit rote LED: " + String(LeuchtStaerkeRot));
    Serial.println("Helligkeit grüne LED: " + String(LeuchtStaerkeGruen));
  } 

  // Button/Knopf auswerten 
  ButtonLesen = digitalRead(JoystickButton); 
  if (ButtonLesen == LOW) 
  { 
    // Helligkeit der LEDs auf 0 setzen und LEDs ausschalten 
    LeuchtStaerkeGruen = 0; 
    LeuchtStaerkeRot = 0; 
    analogWrite(ROT, 0); 
    analogWrite(GRUEN, 0); 
  }
}

Letzte Aktualisierung:

Laby­rinth­spiel TFT

/*
  GND      (1) - GND
  VCC      (2) - 5V
  RESET    (3) - D9
  D/C      (4) - D8
  CARD-CS  (5) -
  TFT-CS   (6) - D10
  MOSI     (7) - D11
  SCK      (8) - D13
  MISO     (9) -
  LITE    (10) - 5V
*/

#include "Adafruit_GFX.h"
#include "Adafruit_ST7735.h"
#include "SPI.h"
#define TFT_CS        10
#define TFT_RST        9
#define TFT_DC         8

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

/*
  Farben als hexadezimal definiert
  alternativ:
  int SCHWARZ = 0;
  int BLAU = 15;
  . . .
*/
#define SCHWARZ    0x0000 // dezimal 0
#define BLAU       0x000F // dezimal 15
#define ROT        0xF800 // dezimal 63488
#define GRUEN      0x0E81 // dezimal 3713
#define CYAN       0x07FF // dezimal 2047
#define MAGENTA    0xF81F // dezimal 63519
#define GELB       0xAFE5 // dezimal 65504
#define WEISS      0xFFFF // dezimal 65535
#define BRAUN      0xFC00 // dezimal 64512
#define GRAU       0xF7F0 // dezimal 63472
#define GRUENGELB  0xAFE5 // dezimal 45029

#define DUNKELCYAN 0x03EF // dezimal 1007
#define ORANGE     0xFD20 // dezimal 64800
#define PINK       0xFC18 // dezimal 64536

// Farbe der Blöcke
#define FARBE GRUEN

// Farbe des Kreises
#define KREISFARBE GELB

// Farbe der Schrift
#define SCHRIFTFARBE WEISS

// Joystick analoge Pins
int XAchse = A0;
int YAchse = A1;

// Button/Knopf
int JoystickButton = 7;

// Zustand des Buttons
int ButtonLesen;

// Spiel starten wenn * gedrückt wurde
bool SpielStart = false;

// Radius des kreises
const int Radius = 10;

// Abstand zu den Rändern
const int Abstand = Radius * 2;

// je höher, dest langsamer
const int Geschwindigkeit = 100;

// Bewegung des Kreises in Pixeln
const int Bewegung = 5;

// Startposition des Kreises
int CursorX = Radius;
int CursorY = tft.height() / 2 - Abstand;

// Variablen für die Auswertung der Bewegung des Joysticks
int PositionX;
int PositionY;

// Variable für die Zeitmessung
long Start;

void setup()
{
  // Startbildschirm
  // schwarzes Farbschema vertikale Ausrichtung (nicht drehen)
  // Cursor setzen, Schriftgröße und -farbe definieren
  tft.initR(INITR_BLACKTAB);
  tft.setRotation(0);
  tft.fillScreen(SCHWARZ);

  // Startbildschirm
  tft.setTextSize(2);
  tft.setCursor(1, 10);
  tft.setTextColor(SCHRIFTFARBE);

  tft.println("Start:");
  tft.print("-> Button");
  pinMode(JoystickButton, INPUT_PULLUP);
}

void loop()
{
  // Button/Knopf auswerten
  ButtonLesen = digitalRead(JoystickButton);
  if (ButtonLesen == LOW)
  {
    // Spiel wird gestartet
    SpielStart = true;

    // Parcours bauen
    ParcoursBauen();

    // Zeitmessung starten
    Start = millis();
  }

  // wenn der Button gedrückt wurde -> SpielStart -> true
  if (SpielStart)
  {
    // Bewegung der X-Achse lesen
    PositionX = analogRead(XAchse);

    // Bewegung X-Achse nach oben
    if (PositionX > 600)
    {
      // Kreis an der aktuellen Position "löschen"
      tft.fillCircle(CursorX, CursorY, Radius, SCHWARZ);

      // wenn der Bildschirmrand oben noch nicht erreicht wurde
      // rückwärts -> Richtung x = 1 bewegen
      if (CursorY > Radius) CursorY -= Bewegung;

      // Kreis an der neuen Position zeichnen
      tft.fillCircle(CursorX, CursorY, Radius, KREISFARBE);
      delay(Geschwindigkeit);
    }

    // Bewegung X-Achse nach unten
    if (PositionX < 300)
    {
      // Kreis an der aktuellen Position "löschen"
      tft.fillCircle(CursorX, CursorY, Radius, SCHWARZ);

      // wenn der Bildschirmrand rechts noch nicht erreicht wurde
      // vorwärts -> Richtung tft.height() bewegen
      if (CursorY < tft.height() - Radius) CursorY += Bewegung;

      // Kreis an der neuen Position zeichnen
      tft.fillCircle(CursorX, CursorY, Radius, KREISFARBE);
      delay(Geschwindigkeit);
    }

    // Bewegung Y-Achse nach links
    if (PositionY < 300)
    {
      // Kreis an der aktuellen Position "löschen"
      tft.fillCircle(CursorX, CursorY, Radius, SCHWARZ);

      // wenn der Bildschirmrand links noch nicht erreicht wurde
      // rückwärts -> Richtung linken Bildschirmrand bewegen
      if (CursorX > Radius) CursorX -= Bewegung;

      // Kreis an der neuen Position zeichnen
      tft.fillCircle(CursorX, CursorY, Radius, KREISFARBE);
      delay(Geschwindigkeit);
    }

    // Bewegung Y-Achse nach rechts
    PositionY = analogRead(YAchse);

    if (PositionY > 600)
    {
      // Kreis an der aktuellen Position "löschen"
      tft.fillCircle(CursorX, CursorY, Radius, SCHWARZ);

      // Abfrage, ob der rechte Rand erreicht wurde, nicht nötig
      // wird in der nächsten Bedingung abgefragt
      CursorX += Bewegung;

      // Kreis an der neuen Position zeichnen
      tft.fillCircle(CursorX, CursorY, Radius, KREISFARBE);
      delay(Geschwindigkeit);
    }

    // rechter Bildschirmrand erreicht -> Spielende
    if (CursorX > tft.height() - Radius)
    {
      ErgebnisZeigen();
    }
  }
}

void ErgebnisZeigen()
{
  // Zeit berechnen
  int Sekunden;
  long VerstricheneZeit = millis() - Start;
  Sekunden = int(VerstricheneZeit / 1000);

  // Zeit anzeigen
  tft.fillScreen(SCHWARZ);
  tft.setTextColor(SCHRIFTFARBE);

  tft.setTextSize(2);
  tft.setCursor(1, 10);
  tft.println("Zeit:");
  tft.println(String(Sekunden) + " s");

  tft.setCursor(1, 40);
  tft.println();
  tft.println("Neustart:");
  tft.println("-> Taste");
  SpielStart = false;
}

void ParcoursBauen()
{
  CursorX = Radius;
  CursorY = tft.height() / 2 - Abstand;
  tft.fillScreen(SCHWARZ);

  // Kreis anzeigen
  tft.fillCircle(CursorX, CursorY, Radius, KREISFARBE);

  // Parcours "bauen"
  tft.fillRect(65, 35, 5, 45, FARBE);
  tft.fillRect(1, 1, 35, 35, FARBE);
  tft.fillRect(1, 80, 70, 80, FARBE);
  tft.fillRect(110, 1, 70, 95, FARBE);
  tft.fillRect(110, 130, 140, 160, FARBE);
}

Letzte Aktualisierung:

Pin-Ein­ga­be im Seri­el­ler Monitor

#include "Adafruit_Keypad.h"

int LAUTSPRECHER = 13;

// Größe des Tastenfeldes
// 3 Spalten
const byte SPALTEN = 3;

// 4 Zeilen
const byte REIHEN = 4;

// die Ziffern/Zeichen:
// Array 3 x 4
char Tasten[REIHEN][SPALTEN] =
{
  { '#', '0', '*' },
  { '9', '8', '7' },
  { '6', '5', '4' },
  { '3', '2', '1' }
};

// die Pins für die 3 Spalten
byte SpaltenPins[SPALTEN] = { 3, 4, 5 };

// die Pins für die 4 Zeilen
byte ReihenPins[REIHEN] = { 6, 7, 8, 9 };

// TastenFeld ⇒ Name des Keypads
// -> Zuordnung der Pins zu den REIHEN und SPALTEN des Arrays
Adafruit_Keypad Tastenfeld = Adafruit_Keypad(makeKeymap(Tasten), ReihenPins, SpaltenPins, REIHEN, SPALTEN);

String Vergleich;
String Pin;

// char-Array für die eingegebenen Zeichen
char Zeichen[5];

int Position = 0;

void setup()
{
  // Tastenfeld starten
  Tastenfeld.begin();

  pinMode(LAUTSPRECHER, OUTPUT);
  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial) {;}
  delay(500);

  // nur beim Start anzeigen
  Serial.println("Bitte 4-stelligen Pin eingeben:");
  Serial.println("Pin-Eingabe mit # abschlie\u00dfen");
  Serial.println("Korrektur mit * ");

  // Zufallsgenerator starten
  randomSeed(analogRead(A0));

  // neuen Pin erstellen
  neuerPin();
}

void loop()
{
  // gedrückte Taste lesen
  Tastenfeld.tick();

  while (Tastenfeld.available())
  {
    keypadEvent Taste = Tastenfeld.read();

    // wenn die Taste losgelassen wurde
    if (Taste.bit.EVENT == KEY_JUST_RELEASED)
    {
      tone(LAUTSPRECHER, 1000);
      delay(50);
      noTone(LAUTSPRECHER);

      // eingegebenes Zeichen an der aktuellen Position speichern
      Zeichen[Position] = (char)Taste.bit.KEY;

      // Zeichen anzeigen
      Serial.print(Zeichen[Position]);

      // nächstes Zeichen -> Position erhöhen
      Position ++;

      // Korrektur ASCII-Wert 42 = *
      if (Taste.bit.KEY == 42)
      {
        // char-Array Zeichen leeren
        for (int i = 0; i < sizeof(Zeichen); i++)
        {
          Zeichen[i] = NULL;
        }

        Position = 0;
        Serial.println("\tKorrektur: ");

      }

      // Zeichen ASCII-Wert 35 = #
      if (Taste.bit.KEY == 35)
      {
        // char-Array in String umwandeln
        Vergleich = String(Zeichen);

        // letzte Zeichen des Strings sind 0 und # -> müssen entfernt werden
        Vergleich = Vergleich.substring(0, Vergleich.length() - 2);

        Serial.println();
        Serial.print(Vergleich);

        // Eingabe mit Pin vergleichen
        if (Vergleich == Pin)
        {
          Serial.println("\tPin ist korrekt - Zugriff");
        }
        else Serial.println("\tFalscher Pin - kein Zugriff");

        // Variable zurücksetzen
        Position = 0;

        // neuen Pin erstellen
        neuerPin();
      }
    }
  }
}

String neuerPin()
{
  // zufälligen PIN bestimmen
  Pin = "";
  Serial.println("---------------------------------------");

  for (int i = 0; i < sizeof(Zeichen) - 1; i++)
  {
    int Zahl = random(0, 10);
    Pin = Pin + String(Zahl);
  }

  // Pin anzeigen
  Serial.println("neuer Pin: " + Pin);
  return Pin;
}

Letzte Aktualisierung:

Taschen­rech­ner Mul­ti­pli­ka­ti­on auf LCD

#include "Adafruit_Keypad.h"
#include "LiquidCrystal_I2C.h"

int LAUTSPRECHER = 13;

// Größe des Tastenfeldes
// 3 Spalten
const byte SPALTEN = 3;

// 4 Zeilen
const byte REIHEN = 4;

// die Ziffern/Zeichen:
// Array 3 x 4
char Tasten[REIHEN][SPALTEN] =
{
  { '#', '0', '*' },
  { '9', '8', '7' },
  { '6', '5', '4' },
  { '3', '2', '1' }
};

// die Pins für die 3 Spalten
byte SpaltenPins[SPALTEN] = { 3, 4, 5 };

// die Pins für die 4 Zeilen
byte ReihenPins[REIHEN] = { 6, 7, 8, 9 };

// TastenFeld ⇒ Name des Keypads
// -> Zuordnung der Pins zu den REIHEN und SPALTEN des Arrays
Adafruit_Keypad Tastenfeld = Adafruit_Keypad(makeKeymap(Tasten), ReihenPins, SpaltenPins, REIHEN, SPALTEN);

// LCD initialisieren
LiquidCrystal_I2C lcd(0x27, 20, 4);

// char-Array für die eingegebenen Zeichen
char Zeichen[50];

// Position des eingegebenen Zeichens im char-Array
int Position = 0;

// beinhaltet die vollständige Rechnung
String Rechnung;

void setup()
{
  Serial.begin(9600);

  // Tastenfeld starten
  Tastenfeld.begin();

  // LCD einschalten, Startbildschirm zeigen
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Mal-Rechner");
  lcd.setCursor(0, 1);
  lcd.print("--------------------");
  lcd.setCursor(0, 2);
}

void loop()
{
  String GleichZeichen = " = ";
  lcd.setCursor(Position, 2);

  // Tastenfeld abfragen
  Tastenfeld.tick();

  while (Tastenfeld.available())
  {
    /*
      wenn eine Aufgabe ausgegeben wurde
      LCD löschen, Anzeige neu aufbauen
    */
    if (Rechnung != "")
    {
      Rechnung = "";
      lcd.clear();
      Position = 0;
      lcd.setCursor(0, 0);
      lcd.print("Mal-Rechner");
      lcd.setCursor(0, 1);
      lcd.print("--------------------");
      lcd.setCursor(0, 2);

      // char-Array Zeichen leeren
      for (int i = 0; i < sizeof(Zeichen); i++)
      {
        Zeichen[i] = NULL;
      }

      Position = 0;
    }

    // gedrückte Taste lesen
    keypadEvent Taste = Tastenfeld.read();

    // wenn die Taste losgelassen wurde
    // Wert abgefragter Taste zu char umwandeln
    if (Taste.bit.EVENT == KEY_JUST_RELEASED)
    {
      // eingegebenes Zeichen an der aktuellen Position speichern
      Zeichen[Position] = (char)Taste.bit.KEY;

      // Ton ausgeben
      tone(LAUTSPRECHER, 1000);
      delay(50);
      noTone(LAUTSPRECHER);

      // Zeichen anzeigen
      // # soll nicht angezeigt werden
      if (Taste.bit.KEY != 35)
      {
        Serial.print(Zeichen[Position]);
        lcd.print(Zeichen[Position]);
      }

      // nächstes Zeichen -> Position erhöhen
      Position ++;

      // # (ASCII-Code = 35) gedrückt ⇒ Rechnung ausführen
      if (Taste.bit.KEY == 35)
      {
        // char-Array in String umwandeln
        Rechnung = String(Zeichen);

        // letztes Zeichen ist # ⇒ muss entfernt werden
        Rechnung = Rechnung.substring(0, Position - 1);

        // Position des Malzeichens bestimmen
        // Zählung beginnt mit 0
        int MalZeichen = Rechnung.indexOf('*');

        // erster Faktor: von 0 bis zur Position des Malzeichens
        String FaktorEins = Rechnung.substring(0, MalZeichen);

        /*
          zweiter Faktor: von der Position hinter dem Malzeichen
          bis zum vorletzten Zeichen
          das letzte Zeichen ist # ⇒ soll entfernt werden
        */
        String FaktorZwei = Rechnung.substring(MalZeichen + 1, Rechnung.length());

        /*
           Produkt berechnen
           damit dürfen die beiden Faktoren nicht größer als
           32768 sein
           long Produkt = FaktorEins.toInt() * FaktorZwei.toInt();
           Zahlen nach long umwandeln
        */
        long ErsterFaktor = FaktorEins.toInt();
        long ZweiterFaktor = FaktorZwei.toInt();
        long Produkt =  ErsterFaktor * ZweiterFaktor;

        // String Rechnung "zusammenbauen"
        Rechnung = FaktorEins + " * " + FaktorZwei + GleichZeichen + String(Produkt);

        // Rechnung anzeigen
        RechnungAusgeben();
      }
    }
  }
}

void RechnungAusgeben()
{
  // Ausgabe Serieller Monitor
  Serial.println("\n" + Rechnung);

  // Ausgabe LCD
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.noCursor();
  lcd.print("Mal-Rechner");
  lcd.setCursor(0, 1);

  lcd.print("--------------------");
  lcd.setCursor(0, 2);

  /* Länge der Rechnung bestimmen
     das LCD hat nur 20 Zeichen
     wenn es mehr als 20 sind ⇒ Zeilenumbruch beim =-Zeichen
  */
  int Laenge = Rechnung.length();

  if (Laenge > 20)
  {
    // Position des =-Zeichen bestimmen
    int GleichZeichen = Rechnung.indexOf('=');

    // Rechnung bis =-Zeichen anzeigen
    lcd.print(Rechnung.substring(0, GleichZeichen + 1));

    // Zeilenumbruch
    lcd.setCursor(0, 3);
    lcd.print(Rechnung.substring(GleichZeichen + 2, Rechnung.length()));
  }

  // wenn < 20 Zeichen
  else lcd.print(Rechnung);
}

Letzte Aktualisierung:

Mor­se­ge­rät

int LAUTSPRECHER = 5;
int LED = 6;
int SENSOR = 7;

// der auszulesende Zustand des Sensors
// wird als Variable definiert
int SensorLesen;

void setup()
{
  pinMode(SENSOR, INPUT);
  pinMode(LED, OUTPUT);
}

void loop()
{
  SensorLesen = digitalRead(SENSOR);
  if (SensorLesen == HIGH)
  {
    // Lautsprecher einschalten
    tone(LAUTSPRECHER, 1000);

    // LED einschalten
    digitalWrite(LED, HIGH);
  }

  else
  {
    // Lautsprecher ausschalten
    noTone(LAUTSPRECHER);

    // LED ausschalten
    digitalWrite(LED, LOW);
  }
}

Letzte Aktualisierung: