Serieller Monitor

Wie oft benötigt man zum Testen eines Programms die Eingabe von Zahlen über den Seriellen Monitor und muss dann jedes Mal neu einen Zusatzcode schreiben, der die empfangenen Zeichenketten auf Gültigkeit der einzelnen Zeichen überprüft, in Integer- oder Float-Zahlen umwandelt und eventuelle Bereichsüberschreitungen erkennt. Mit Hilfe der Arduino-Funktionen "Serial.parseInt" und "Serial.parseFloat" kann man zwar aus seriellen Zeichenfolgen Integer- oder Float-Zahlen extrahieren, aber bei Eingabefehlern (z.B. irrtümlich Buchstabe zwischen Zahlen oder Bereichsüberschreitung) werden dann falsche Werte übernommen. Aus diesem Grund habe ich eine kleine Library geschrieben, die die empfangenen Zeichenketten nur bei fehlerfreier Eingabe als Integer- oder Float-Zahl zurückgibt.


Achtung: Die Library ist im Zusammenhang mit der Verwendung des Seriellen Monitor der Arduino-IDE geschrieben. Bei Verwendung von anderen Monitorprogrammen, wie z.B. Realterm, ist die Verwendung der Library nur bedingt geeignet. Der Unterschied besteht darin, dass andere Monitorprogramme standardmäßig bei jedem Tastendruck sofort die einzelnen Zeichen senden. Im Gegensatz dazu sendet der Serielle Monitor der  Arduino-IDE ein oder mehrere Zeichen erst nach Betätigung der "Enter"-Taste oder des "Senden"-Symbols, sozusagen blockweise. Eine eingegebene Zahl wird also in einem Block vom Monitor zum Arduino gesendet und von der Library ausgewertet. Das Senden von Einzelzeichen, wie bei Realterm, wird von der Library derzeit nicht berücksichtigt. Es gibt aber auch bei Realterm die Möglichkeit, ebenfalls Zeichen und/oder Zahlen blockweise zu senden.

 

Library MySerialRead:

Folgende Funktionen stehen derzeit zur Verfügung:


  • Einlesen einer Float-Zahl
  • Einlesen eines Bytes (0 bis 255)
  • Einlesen einer 8-Bit Integer-Zahl (-128 bis 127)
  • Einlesen einer 16-Bit Integer-Zahl (-32768 bis 32767)
  • Einlesen einer 16-Bit Unsigned-Integer-Zahl (0 bis 65535)
  • Neu: Einlesen einer 32-Bit Integer-Zahl (-2147483648 bis 2147483647)


Die Library kann hier heruntergeladen werden:

Version 2.1

Änderungen gegenüber Version 1.0: Erweiterung um 2 neue Funktionen und Umbenennung von 2 alten Funktionen

Änderungen gegenüber Version 2.0: Erweiterung um 1 Funktion und Fehlerbehebung

MySerialRead.cpp.txt

MySerialRead.h.txt

keywords.txt

Leider kann ich hier keine "cpp"- oder "h"-Files hochladen, daher zum Verwenden der Library ".txt" aus den Dateinamen entfernen und in einem neuen Verzeichnis mit dem Namen "MySerialRead" dort speichern, wo eure anderen Libraries gespeichert sind.


Zur Auflistung der Funktionen der Library geht es hier: Funktionen


Programmbeispiel 1 MySerialRead:

Das Programmbeispiel 1 zeigt das Einlesen einer Float-Zahl und einer Unsigned Int-Zahl vom Seriellen Monitor.

Aber Achtung: Durch die Angabe von "SERIAL_WAIT" beim Aufruf der Funktionen "readFloat" und "readUInt" wartet das Programm auf eine Eingabe und alle anderen (im Programmbeispiel nicht vorhandenen) Programmfunktionen werden während des Wartens gestoppt. Vorteil: Es können so mehrere Variablen von unterschiedlichem Datentyp eingelesen werden.


#include <MySerialRead.h>

MySerialRead SerialRead;

float f_zahl;
unsigned int ui_zahl;


void setup() {
  Serial.begin(115200);
}


void loop() {
  Serial.println("Warte auf Float-Zahl!");
  if (SerialRead.readFloat(&f_zahl, SERIAL_WAIT))
  {
    Serial.print("Float-Zahl = ");
    Serial.println(f_zahl);
  }
  else Serial.println("Eingabefehler!");
  Serial.println();
  Serial.println("Warte auf Unsigned Int-Zahl!");
  if (SerialRead.readUInt16(&ui_zahl, SERIAL_WAIT))
  {
    Serial.print("Unsigned Int-Zahl = ");
    Serial.println(ui_zahl);
  }
  else Serial.println("Eingabefehler!");
  Serial.println();
}


Programmbeispiel 2 MySerialRead:

Bei Programmbeispiel 2 wird eine Integer-Zahl eingelesen. Gegenüber Programmbeispiel 1 wartet aber das Programm durch die Angabe von "SERIAL_CONT" nicht auf die Eingabe und die Funktion "readInt" muss daher zyklisch aufgerufen werden. Der Vorteil ist, dass andere Programmfunktionen, im Beispiel das Blinken der LED auf Pin 13, nicht unterbrochen werden. Der Nachteil aber ist, dass nur genau eine Zahl mit einem Datentyp eingelesen werden kann, da ja die vom Seriellen Monitor empfangene Zahl kein "Mascherl" hat, zu welcher Variablen die Zahl gehört.


#include <MySerialRead.h>

MySerialRead SerialRead;

#define ledPin 13
int i_zahl;
unsigned long start = 0;


void setup() {
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
}


void loop() {
  if (millis() - start >= 500)
  {
    digitalWrite(ledPin, !digitalRead(ledPin));
    start = millis();
  }
  //Serial.println("Warte auf Zahl!");
  if (SerialRead.readInt16(&i_zahl, SERIAL_CONT))
  {
    Serial.print("Zahl = ");
    Serial.println(i_zahl);
  }
}


Nachfolgend das Programmbeispiel 2 noch einmal mit der Funktio "serialEvent". Diese ist eine Standard-Arduino-Funktion, die bei jedem Durchlauf der "loop"-Funktion einmal aufgerufen wird, sofern serielle Daten verfügbar sind.


#include <MySerialRead.h>

MySerialRead SerialRead;

#define ledPin 13
int i_zahl;
unsigned long start = 0;


void setup() {
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
}


void loop() {
  if (millis() - start >= 500)
  {
    digitalWrite(ledPin, !digitalRead(ledPin));
    start = millis();
  }
}


void serialEvent()
{
  if (SerialRead.readInt16(&i_zahl, SERIAL_CONT))
  {
    Serial.print("Zahl = ");
    Serial.println(i_zahl);
  }
}