Dies ist eine alte Version des Dokuments!
Die einfachste Art und Weise, einen Befehl vom PC an den Arduino zu übermitteln, ist, ihm einzelne Zeichen über die Serielle Schnittstelle zu schicken, die ein Programm auf dem Arduino auswertet.
Dabei kann z.B. der Buchstabe f
für „fahre los“ und der Buchstabe s
für „stop“ stehen.
Das Arduino Programm muss zum Empfang der Befehle nur:
Serial.available()
)Serial.read()
)if
oder switch case
)if
oder switch case
)
Das Beispiel libraries/Serial/SimpleWrite
in Processing enthält sowohl den Processing, als auch den Arduino Code, um mit der Maus eine LED auf dem Arduino ein- und ausschalten zu können. Hier ein kleiner Ausschnitt mit den wichtigsten Teilen auf Arduinoseite:
... if (Serial.available()) { // Wenn Daten empfangen wurden und zum Lesen bereitstehen int val = Serial.read(); // lese das erste Zeichen in der Warteschlange und speichere es in der Variable 'val' zwischen if (val == 'H') { // Wenn das Zeichen den Wert 'H' hat... digitalWrite(ledPin, HIGH); // schalte eine LED an } else { digitalWrite(ledPin, LOW); // wenn es irgendein anderes Zeichen ist, schalte die LED aus. } } ...
Sollen mehr als zwei unterschiedliche Befehle erkann werden können, so geht das am einfachsten mit dem switch/case
. Die Sendeseite funktioniert ganz genau so wie in libraries/Serial/SimpleWrite
, nur dass eben mehrere unterschiedliche Zeichen gesendet werden können.
Für die Arduino/ Empfängerseite gibt es ein gutes Beispielprogramm ''control/switchCase2'' aus dem Arduino IDE, aus dem ich hier (mit deutschen Kommentaren) zitiere:
if (Serial.available() > 0) { // Wenn Daten angekommen sind... int inByte = Serial.read(); // ...dann lies das erste Byte und speichere es in der Variable inByte switch (inByte) { // und nimm den Wert, der übertragen wurde, genauer unter die Lupe. case 'a': // wenn dieser das Zeichen 'a' ist... digitalWrite(2, HIGH); // ... dann schalte den pin 2 auf 5V break; // Ohne 'break' würde das Programm auch den nächsten Teil ausführen, obwohl kein 'b' kam. (beliebter Fehler) case 'b': // alle anderen Buchstaben funktionieren genauso wie 'a', nur passiert eben als Reaktion etwas anderes. digitalWrite(3, HIGH); break; case 'c': digitalWrite(4, HIGH); break; case 'd': digitalWrite(5, HIGH); break; case 'e': digitalWrite(6, HIGH); break; default: //wenn das Zeichen keinem der oben überprüften entspricht, passiert das Folgende: // Schalte die Spannung an allen Pins aus. for (int thisPin = 2; thisPin < 7; thisPin++) { digitalWrite(thisPin, LOW); } }
In vielen Fällen wollen wir nicht nur ein Kommando übertragen („fahre geradeaus“), sondern auch dazugehörige Zahlenwerte („wie lange?“ , „wie schnell?“, „wie weit?“).
Das geht ganz einfach mit den beiden Befehlen Serial.parseInt()
(für Ganzzahlen) oder Serial.parseFloat()
.
Beide Befehle lesen solange Daten aus der seriellen Schnittstelle, bis entweder längere Zeit nichts mehr gekommen ist („timeout“) oder das nächste Zeichen nicht mehr Teil einer Zahl sein kann (also irgendetwas ausser 0…9 oder '.' ist).
Zum Steuern eines Motors könnten wir z.B. die Kommandos 'f' für vorwärts 'b' für rückwärts verwenden, die jeweils von einer Zahl gefolgt sind, die angibt, wieviel Gas in die entsprechende Richtung gegeben werden soll. Ein kompletter Befehl, der so in den Serial-Monitor eingegeben oder von Processing verschickt werden kann wäre also z.B. 'f100' oder 'b20'.
Der Arduino Code dafür könnte z.B. so aussehen:
if (Serial.available() > 0) { // Wenn Daten da sind... int inByte = Serial.read(); // ...dann lies das erste Byte und speichere es in der Variable inByte switch (inByte) { // und nimm den Wert, der übertragen wurde, genauer unter die Lupe. case 'f': // wenn dieser das Zeichen 'f' für 'vorwärts' ist... { int inValue=Serial.parseInt(); // dann lies erstmal eine Zahl ein (wenn irgendetwas anders kam, ist das Ergebnis 0 ) digitalWrite(directionPin,HIGH); // stelle den Motor auf 'vorwärts' analogWrite(throttlePin, inValue); // ... gib genau so viel Gas, wie gewünscht. break; // höre hier auf. } case 'b': // ..rückwärts genauso: { int inValue=Serial.parseInt(); // dann lies erstmal eine Zahl ein (wenn irgendetwas anders kam, ist das Ergebnis 0 ) digitalWrite(directionPin,LOW); // stelle den Motor auf 'rückwärts' analogWrite(throttlePin, inValue); // ... gib genau so viel Gas, wie gewünscht. break; // höre hier auf. } case default: // bei uns unbekannten Kommandos machen wir einfach garnichts... break; }