Taschen­rech­ner Grundrechenarten

Lese­zeit: 13 Minu­ten
Navi­ga­ti­on

Das Tas­ten­feld soll dazu ver­wen­det wer­den um Rechen­ope­ra­tio­nen in den Grund­re­chen­ar­ten durchzuführen.Das Ergeb­nis soll im Seri­el­len Moni­tor und auf einem LCD ange­zeigt werden.

So sieht es aus:

Schlie­ße das LCD an:

LCD

Nor­ma­ler­wei­se wäre eine kom­ple­xe Ver­ka­be­lung zum Betrieb eines LCDs nötig. Der ➨I2C-Bus regelt über einen eige­nen Mikro­pro­zes­sor die Kom­mu­ni­ka­ti­on der Daten­lei­tun­gen unter­ein­an­der. Es wer­den des­halb nur vier Anschlüs­se benötigt.

Die Hel­lig­keit kann mit einem Poten­tio­me­ter auf der Rück­sei­te des LCDs ein­ge­stellt werden.

Bevor du star­ten kannst musst du eine Biblio­thek instal­lie­ren:
Sketch → Biblio­thek ein­bin­den → Biblio­the­ken verwalten

Benö­tig­te Bauteile:

  • LCD 1602
  • Lei­tungs­dräh­te

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

Bin­de die benö­tig­te Biblio­thek ein und defi­nie­re die Variablen.

# include <LiquidCrystal_I2C.h>

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

String Eingabe;
String Rechnung;
long Ergebnis;

// Fehlervariablen für gefundenen Buchstaben oder Division durch 0
bool BuchstabeGefunden = false;
bool DivisionNull = false;

Der setup-Teil. Beach­te die Kommentare.

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

  // LCD einschalten
  lcd.init();
  lcd.backlight();

  // LCD einschalten
  lcd.init();
  lcd.backlight();

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

Der loop-Teil. Beach­te die Kommentare:

void loop()
{
  String GleichZeichen = " = ";

  // Eingabe serieller Monitor
  while (Serial.available() > 0)
  {
    // solange lesen, bis return \n = return eingegeben wurde
    Eingabe = Serial.readStringUntil("\n");

    // das letzte Zeichen ist return = \n → soll entfernt werden (-1)
    Eingabe = Eingabe.substring(0, Eingabe.length() - 1);

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

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

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

      // String Rechnung "zusammenbauen"
      Rechnung = SummandEins + " + " + SummandZwei + GleichZeichen + String(Ergebnis);
      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);

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

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

      // String Rechnung "zusammenbauen"
      Rechnung = Minuend + " - " + Subtrahend + GleichZeichen + String(Ergebnis);

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

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

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

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

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

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

      /* 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
      {
        float Quotient = Dividend.toFloat() / Divisor.toFloat();

        // String Rechnung "zusammenbauen"
        Rechnung = Dividend + " : " + Divisor + GleichZeichen + String(Quotient);
        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;
  }
}

Die Metho­de Rech­nungAus­ga­ben() zeigt die Rech­nung und das Ergeb­nis im Seri­el­len Moni­tor und auf dem LCD an.
Für die Anzei­ge auf dem LCD gibt es noch eine Beson­der­heit:
Wenn die Rech­nung 20 Zei­chen über­schrei­tet, wird sie vor dem =-Zei­chen umgebrochen.

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

Jetzt fehlt nur noch die Funk­ti­on, mit deren Hil­fe geprüft wird, ob in der Rech­nung Buch­sta­ben vor­han­den sind.

bool BuchstabeSuchen(String Pruefen)
{
  bool BuchstabeGefunden = false;
  
  // wenn das Zeichen im zu prüfenden String ein Buchstabe (isAlpha) ist
  // -> BuchstabeGefunden = true
  for (int zaehler = 0; zaehler < Pruefen.length(); zaehler++)
  {
    if (isAlpha(Pruefen.charAt(zaehler)))
    {
      BuchstabeGefunden = true;
      
      // nicht weiter suchen Schleife verlassen
      break;
    }
  }

  return BuchstabeGefunden;
}

Das Pro­gramm soll jetzt um die Rech­nung mit Dezi­mal­zah­len erwei­tert werden.

  • Der Ardui­no kennt lei­der nur den Daten­typ float, der mit ein­fa­cher Genau­ig­keit rech­net. Des­halb wer­den ledig­lich zwei Nach­kom­ma­stel­len berechnet.
  • Ardui­no ver­wen­det die Punkt-Notation für Dezi­mal­zah­len (2.5 statt 2,5). Die Ein­ga­be soll aber mit Kom­ma erfolgen.
  • Wenn das Ergeb­nis eine natür­lich Zahl ist, sol­len die Nach­kom­ma­stel­len abge­schnit­ten werden.

So sieht es aus:

Der Kopf des Programms:

# include <LiquidCrystal_I2C.h>

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

String Eingabe;
String Rechnung;
long Ergebnis;

// Fehlervariablen für gefundenen Buchstaben oder Division durch 0
bool BuchstabeGefunden = false;
bool DivisionNull = false;

Der setup-Teil:

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

  // LCD einschalten
  lcd.init();
  lcd.backlight();

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

Der geän­der­te loop-Teil. Beach­te die Kommentare.

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

    // das letzte Zeichen ist return = \n → soll entfernt werden (-1)
    Eingabe = Eingabe.substring(0, Eingabe.length() - 1);

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

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

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

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

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

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

      // 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);
      Dividend.replace(",", ".");

      // Divisor: von der Position hinter dem Geteiltzeichen
      // bis zum letzten Zeichen
      String Divisor = Eingabe.substring(GeteiltZeichen + 1, Eingabe.length());
      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;
  }
}

Die Metho­de Rech­nungAus­ge­ben() und die Funk­ti­on Buch­sta­be­Su­chen() blei­ben unverändert.

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

Die Funk­ti­on Null­Ent­fer­nen() tes­tet, ob das Ergeb­nis eine natür­li­che Zahl ist – die bei­den Nac­k­om­men­stel­len sind 0 - und schnei­det die Nach­kom­ma­stel­len ab.

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

  // Nachkommastellen > 0
  else TestString = PruefString;

  return TestString;
}


Ver­wand­te Aufgaben:


    Letzte Aktualisierung: 7. Jan 2021 @ 11:02