/*========================================
Programm-Name: Serial GYR mit Escape Chars und detaillierten Comments
Beschreibung: Das Programm lässt je nach eingegebenem Buchstaben
- "G" für grün, "Y" für gelb und "R" für rot -
eine der 3 LEDs 2x aufleuchten.
Zweck: Übung zur Eingabe über die serielle Schnittstelle
und Demonstration von
- sauber strukturiertem und übersichtlichem Code,
- einzeiligen/mehrzeiligen Kommentaren (div. Beispiele),
- Escape Characters,
- Konstanten-Definition,
- ausgelagerter Funktion
========================================*/
// Variablen-Deklaration für serielle User-Eingabe
String dataRX;
/* Konstanten-Definition für LED Pins
----------------------------------
Info: Konstanten werden groß geschrieben und können
während der Programm-Ausführung nicht verändert werden.
(Die angesprochenen Pins dürfen sich nicht ändern!)
Im Gegensatz dazu kann einer Variable während der Laufzeit
immer wieder ein anderer Wert zugewiesen werden.
*/
#define G 2 // Green LED auf Pin-Anschluss D2
#define Y 3 // Yellow LED auf Pin-Anschluss D3
#define R 4 // Red LED auf Pin-Anschluss D4
void setup() {
// Aktivierung der Seriellen Schnittstelle mit Baudrate 9600 (bit/s)
Serial.begin(9600);
// Konfiguration der konstanten Pins als Output
pinMode(G,OUTPUT);
pinMode(Y,OUTPUT);
pinMode(R,OUTPUT);
/* Ausgabe am Seriellen Monitor mit Erklärung des Programms für
den User. Eine benutzerfreundliche Darstellung erfolgt durch
folgende Escape Characters:
\n für neuen Zeilenumbruch
\t für eine Tabulator-Einrückung
\" für die Darstellung des Anführungszeichens
*/
Serial.println("Hallo!\n\nDieses Programm lässt je nach eingegebenem Buchstaben \neine der 3 LEDs 2x aufleuchten. \nBitte gib \n\t\"g\" für Grün, \n\t\"y\" für Gelb und \n\t\"r\" für Rot\nein, um die entsprechende LED leuchten zu lassen.");
Serial.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nEingabe erwartet..");
}
void loop() {
/* Funktion Serial.available()
Bei Aufruf gibt die Funktion die Byte-Anzahl der User-Eingabe
als Integer/Ganzzahl zurück (="Rückgabewert der Funktion").
Mit der Abfrage auf > 0 kann somit gewährleistet werden, dass der Code innerhalb
der if-Bedingung erst ausgeführt wird, wenn auch etwas eingegeben wurde.
Weitere Erklärung: https://www.arduino.cc/reference/de/language/functions/communication/serial/available/
*/
if(Serial.available() > 0)
{
// Usereingabe und Umwandlung in Großbuchstaben
// --------------------------------------------
// Usereingabe wird in Variable dataRX gespeichert
dataRX = Serial.readString();
// Ausgabe für die Überprüfung der Usereingabe
Serial.print("Eingabe des Users:\t\t");
Serial.print(dataRX);
dataRX.trim(); // Entfernt eventuelle Leerzeichen und Zeilenumbrüche am Anfang/Ende der Eingabe
dataRX.toUpperCase(); // Gewährleistet Großbuchstaben, auch wenn der User Kleinbuchstaben eingibt
// Ausgabe für die Überprüfung der Weiterverwendung
Serial.print("Umwandlung für if-Abfragen:\t");
Serial.println(dataRX);
// Abfrage auf Eingabewert und Blinken der entsprechenden LED
// ----------------------------------------------------------
if(dataRX == "G")
{
// Aufruf der Blink-Funktion für Grün
// Der übergebene Parameter innerhalb der Klammern ist die anzusprechende LED
blink(G);
} else if(dataRX == "Y")
{
// Aufruf der Blink-Funktion für Gelb
blink(Y);
} else if(dataRX == "R")
{
// Aufruf der Blink-Funktion für Rot
blink(R);
} else {
/* Wurde keine der 3 Buchstaben eingegeben,
wird ein Fehler für den User ausgegeben */
Serial.println("Fehler: Bitte gib einen gültigen Wert ein!");
}
Serial.println("----"); // Trennlinie nach jeder Eingabe für benutzerfreundliche Ausgabe
dataRX=""; // Der Wert der Eingabe wird zurück gesetzt
}
}
/* Blink-Funktion
--------------
Die Codezeilen digitalWrite und delay wurden in eine eigene Funktion ausgelagert,
da sie an 3 Stellen im loop auftauchen würden. Da die Funktion immer wieder
aufgerufen werden kann, wird so redundanter Code vermieden.
Der Parameter in der Klammer beinhaltet den jeweils übergebenen Pin-Wert (2, 3 oder 4).
Hier wird eine neue Variable deklariert, somit ist der Datentyp notwendig
(in unserem Fall int).
Da die LED 2x blinken soll und sich der Code somit erneut 2 Mal wiederholen würde,
wurde das Problem mit einer for-Schleife gelöst. Die for-Schleife beinhaltet innerhalb
der Klammer die Anweisungen für den Durchlauf:
"int i = 0" bedeutet: Eine Hilfsvariable wird definiert, die mit dem Wert 0 startet.
"i < 2" bedeutet: Die Schleife soll solange durchlaufen, solange i kleiner 2 ist.
"i++" bedeutet: Bei jedem Durchlauf soll die Variable um 1 erhöht werden.
Der Durchlauf findet somit 2 Mal statt und geht von Durchlauf 0 bis Durchlauf 1.
*/
void blink(int LED) {
for(int i = 0; i < 2; i++) {
digitalWrite(LED,HIGH);
delay(300);
digitalWrite(LED,LOW);
delay(300);
}
}