HowTo: Ardunio – Gebruik de seriële poort

Normaal wordt elk Arduino-bord geprogrammeerd via de seriële interface.
Maar niet alleen de programmacode kan worden overgebracht naar de Arduino. Er kunnen ook besturingscommando's naar de Arduino worden gestuurd of waarden van de Arduino worden ontvangen.

In het volgende artikel beschrijf ik hoe je dit kunt doen en welke opties je hebt.


Veiligheidsinstructies

Ik weet dat de volgende opmerkingen altijd een beetje vervelend zijn en onnodig lijken. Helaas hebben veel mensen die "beter" wisten door onvoorzichtigheid ogen, vingers of andere dingen verloren of zichzelf verwond. Gegevensverlies is in vergelijking bijna te verwaarlozen, maar zelfs dit kan erg vervelend zijn. Neem daarom vijf minuten de tijd om de veiligheidsinstructies te lezen. Omdat zelfs het coolste project geen blessure of andere problemen waard is.
https://www.nerdiy.de/sicherheitshinweise/

Affiliate links / reclame links

De hier vermelde links naar online winkels zijn zogenaamde affiliate-links. Als u op zo'n affiliate-link klikt en via deze link een aankoop doet, ontvangt Nerdiy.de een commissie van de betreffende onlineshop of aanbieder. De prijs verandert voor jou niet. Als u via deze links uw aankopen doet, steunt u Nerdiy.de om in de toekomst andere nuttige projecten aan te kunnen bieden. 🙂 


Bereid seriële interface voor

Om de seriële interface in uw programma te gebruiken, moet u deze initialiseren.
Dies geschieht indem Ihr in der “setup()”-Funktion die Funktion

Serieel.begin(115200);

aufruft. Die Zahl “115200” steht dabei für die Baudrate – also die Geschwindigkeit – mit der die Symbole Nicht Bits oder Bytes) über die serielle Schnittstelle übertragen werden. Diese Geschwindigkeit solltet ihr von der “Qualität” der Verbindungsleitung abhängig machen.

Als je bijvoorbeeld een afgeschermde en erg korte kabel hebt, kan de snelheid erg hoog worden ingesteld.
Voor onafgeschermde en/of erg lange kabels moet deze snelheid niet zo hoog worden ingesteld.

Gangbare baudrates zijn bijvoorbeeld de volgende waarden:

50
110
150
300
1200
2400
4800
9600
19200
38400
57600
115200
230400
460800
500000

Egal welche Geschwindigkeit Ihr einstellt, dieser Wert muss auch im “Seriellen Monitor” – also dem anderen Kommunikationspartner der seriellen Kommunikation – eingestellt werden. Nur dann werden die Zeichen korrekt empfangen und gesendet. Mehr dazu erfahrt Ihr im Laufe des Textes.

Als je niet zeker weet welke baudrate je moet gebruiken, raad ik waarden aan tussen 9600 baud en 115200 baud. Deze en de tussenliggende waarden zijn ook de gebruikelijke waarden voor veel eindproducten zoals sensoren en actuatoren.


Stuur gegevens van het Arduino-bord naar de aangesloten computer

Om gegevens van je Arduino-bord naar de aangesloten computer te sturen, moet je de volgende functie oproepen.

Diese sendet den Text “Hallo Welt!” inklusive Zeilenumbruch an den Computer.

Serial.println ("Hallo wereld!");

Als voorbeeld kun je de volgende code proberen.

ongeldige setup() { Serial.begin(115200); } void loop() { Serial.println("Hallo wereld!"); vertraging(1000); }
Dadurch erhaltet Ihr die abgebildete Ausgabe. Nach jedem “Hallo Welt!” wird automatisch ein Wechsel in die nächste Zeile vorgenommen.

In der folgenden Kombination sendet die Funktion den Text “Hallo Welt!” ohne Zeilenumbruch an den Computer.

Serial.print ("Hallo wereld!");

Hier is nog een voorbeeld van.

ongeldige setup() { Serial.begin(115200); } void loop() { Serial.print("Hallo wereld!"); vertraging(1000); }
Da nun nach dem “Hallo Welt!” kein Zeilenumbruch vorgenommen wird entsteht eine Lange Zeile aus mehreren “Hallo Welt!”-Abschnitten.

Wollt Ihr Variabel-Werte – in diesem Fall den Wert der Variable “lustige_variable” –  senden könnt Ihr dies wie folgt tun:

uint8_t grappige_variabele=5; Serial.println(String(grappige_variabele));

Als voorbeeld ziet het geheel er weer zo uit.

ongeldige setup() { Serial.begin(115200); } lege lus() { uint8_t grappige_variabele=5; Serial.println(String(grappige_variabele)); vertraging(1000); }
De waarde (5) van de variabele wordt uitgevoerd inclusief een regeleinde.

Een regeleinde verzenden betekent dat er naast de eigenlijke berichtinhoud ook een controleteken wordt verzonden dat de ontvanger het signaal geeft om naar de volgende regel te gaan.


Gebruik een seriële monitor

De seriële monitor is de tegenhanger van het Arduino-bord. Het is het programma dat de gegevens van de computer ontvangt en voor jou leesbaar maakt.
Ihr findet es als Teil der Arduino-IDE unter dem Menüpunkt “Werkzeuge/Serieller Monitor”. Tools wie dieser “Serielle Monitor” werden auch Terminalprogramme genannt. Eine gute Alternative zu dem “Seriellen Monitor” der Arduino-IDE ist auch das Programm HTERM.

Im Fenster des Seriellen Monitors lassen sich das Zeilenabschlusszeichen und die Baudrate einstellen. Durch einen Klick auf “Ausgabe löschen” lässt sich außerdem der Inhalt des Ausgabefensters löschen.

De baudrate kan worden ingesteld in het venster van de seriële monitor. Hier moet je dezelfde waarde instellen die je eerder in de programmacode hebt ingesteld.
Hebben jullie met het commando

Serieel.begin(115200);

Als u een baudrate van 115200 baud hebt ingesteld, moet u ook een baudrate van 115200 baud instellen in de seriële monitor.

Naast de baudrate kun je ook het line termination karakter instellen. Je hebt deze instelling alleen nodig als je gegevens van de computer naar de Arduino wilt sturen.

Hier kun je het teken instellen dat automatisch wordt toegevoegd en verzonden telkens wanneer een waarde wordt verzonden.

Je kunt dit heel goed gebruiken in je code, bijvoorbeeld om op de Arduino te herkennen of de verzending van een commando of waarde is voltooid.

Im Bereich “Befehle und Parameter an den Arduino senden” wird dies ausführlich erklärt.


Gebruik seriële plotter

De seriële plotter is een hulpmiddel waarmee je numerieke waarden (bijvoorbeeld meetwaarden) rechtstreeks op de computer kunt weergeven als een chronologische volgorde. Hiervoor moet je de Arduino zo programmeren dat hij de numerieke waarden naar de computer stuurt.
Dit kan bijvoorbeeld met het commando:

Serial.println(VariableWithAReading);

Die Variable “VariableMitEinemMesswert” sollte natürlich euren Messwert als Zahl enthalten.
Auf dem Computer müsst ihr dann den Seriellen Plotter starten. Diesen findet ihr unter “Werkzeuge/Serieller Plotter”.

Ein simples Beispiel das auf dem seriellen Plotter eine Sinus-Kurve ausgibt ist das folgende. Probiert den Code einfach aus. Er sollte sich auf jedem Arduino ausführen lassen. Denkt daran Euren “Seriellen Plotter” auf 115200 baud einzustellen.

/* _ _ _ _ _
                                 | | | | |(_) | |
  __ ____ ____ __ | | | ___ _ __ __| | _ _ _ __| | ___
    / / / / / / / / / | . ` | / _ | '__|/ _` || || | | | / _` | / _
    V V / V V / V /_ | | | __/| | (_| | | |_| | _| (_| | __/
    \_/\_/ \_/\_/ \_/\_/(_)|_| \_| \___||_| \__,_||_| \__, |(_)\__,_| \___|
                                                               __/ |
                                                              |___/
     sinusTest door Fabian Steppat
     Info op https://www.nerdiy.de/ardunio-die-serielle-schnittstelle/

     Dit programma is vrije software: je mag het verspreiden en/of wijzigen
     onder de voorwaarden van de GNU General Public License zoals gepubliceerd door
     de Free Software Foundation, ofwel versie 3 van de Licentie, of
     (naar keuze) een latere versie.

     Dit programma wordt verspreid in de hoop dat het nuttig zal zijn,
     maar ZONDER ENIGE GARANTIE; zelfs zonder de impliciete garantie van
     VERKOOPBAARHEID of GESCHIKTHEID VOOR EEN BEPAALD DOEL.  Zie de
     GNU General Public License voor meer details.

     Je zou een kopie van de GNU Algemene Gebruikerslicentie moeten hebben ontvangen
     samen met dit programma ontvangen.  Zo niet, zie .

     Aanvullende informatie over dit project vind je op het volgende adres:
     
HowTo: Ardunio – Gebruik de seriële poort
Deze codesnippet print een sinusgolf via seriële console of seriële plotter */ //variabelen en constanten float degreeAngle = 0; float sinusWaarde = 0; const vlotter pi = 3,1415; zweef radiaalhoek = 0; const uint8_t sinusFactor = 50; ongeldige setup() { Serial.begin(115200); } lege lus() { radiantAngle = gradenHoek * pi / 180; //graden maken in radialen sinusValue = sin(radiantAngle); // bereken sinus vanuit stralingshoek degreeAngle += 1.0; // verhoog de hoekvertraging (5); // maak de uitvoer een beetje langzamer als (degreeAngle> 360) // als de graadgrens is bereikt, reset deze dan naar nul { degreeAngle = 0; } Serieel.println(sinusFactor * sinusWaarde); // uitvoer naar seriële monitor/plotter}
Het bovenstaande voorbeeld zou de sinusgolf moeten weergeven die wordt weergegeven op de seriële plotter.

Natuurlijk werkt de plotter niet alleen met sinuswaarden, maar ook met alle andere numerieke waarden.


Stuur commando's en parameters naar de Arduino

Je weet nu dus hoe je verschillende statusmeldingen of waarden van de Arduino naar de computer kunt sturen.
Maar het werkt ook andersom. Dit is vooral handig of praktisch als je de Arduino van buitenaf wilt bedienen en geen invoerapparaten zoals knoppen en dergelijke op de Arduino wilt aansluiten (of niet kunt door het ontbreken van GPIO's).

Je kunt bijvoorbeeld de helderheid of kleur van een LED of de motorsnelheid van een aangesloten motor alleen via de seriële interface instellen.

De Arduino IDE biedt een aantal handige functies voor communicatie via de seriële interface. (Je kunt de documentatie met meer details hier vinden: https://www.arduino.cc/reference/en/language/functions/communication/serial/)

Er moeten nu drie taken worden opgelost om ervoor te zorgen dat de ontvangst en evaluatie van commando's werkt:
1. Hoe herkent de Arduino ontvangen karakters?
2. Hoe zijn complete commando's samengesteld uit de ontvangen karakters?
3. hoe kunnen deze ontvangen commando's worden geëvalueerd?

1. Hoe herkent de Arduino ontvangen karakters

Om te reageren op inkomende karakters is er de functie

Serieel.beschikbaar()

Diese prüft ob neue Zeichen im Empfangspuffer des Arduino enthalten sind. Der Empfangspuffer ist dabei eine Art zwischenspeicher in dem empfangene Zeichen solange gespeichert werden bis der Mikrocontroller des Arduinos Zeit hat sich um die empfangegenen Zeichen zu “kümmern”.

In dem Fall, dass neue Zeichen empfangen, aber noch nicht aus dem Empfangspuffer gelesen wurden gibt die Funktion “Serial.available()” “true” zurück ansonsten “false”.

Deze functie is perfect om te controleren of er tekens zijn ontvangen die nu moeten worden geëvalueerd. Het commando vertelt ons niet hoeveel karakters er zijn ontvangen. Het zegt alleen dat er minstens één karakter in de ontvangstbuffer zit.

2. Hoe de ontvangen karakters om te zetten in volledige commando's

Goed, nu hebben we dankzij de vorige functie herkend dat er ten minste één karakter beschikbaar is in de ontvangstbuffer. Maar hoe krijgen we nu de ontvangen tekens?

Met het commando kunnen tekens uit de ontvangstbuffer worden gelezen

Serieel.lezen()

uitlezen. De functie voert het eerste teken in de ontvangstbuffer uit en verwijdert het automatisch uit de ontvangstbuffer.
Om nu alle tekens uit te lezen en in een variabele te schrijven, lezen we nu uit de ontvangstbuffer tot deze leeg is en noteren we elk uitgelezen teken.
U kunt dit doen met een lus, bijvoorbeeld:

void check_serial_receipt()
{
   String serialBuffer;
   while (Serial.available())
   {
      char currentchar = (char)Serial.read();
      if (currentcharacter == 13) //controleer of het gelezen teken het regeleinde teken is
      {
         receive_char_evaluate(serialBuffer);
      } anders
      {
         serialBuffer += huidig teken;
      }
   }
}

Zoals je kunt zien, bestaat de code uit een while-lus die loopt totdat de ontvangstbuffer leeg is (dan is Serial.available()==false).
Innerhalb der while-Schleife werden währenddessen zeichenweise die auf dem Emfpangspuffer enthaltenen Zeichen ausgelesen (Serial.read()), der Variable “aktuellesZeichen” zugewiesen und an den String “seriellerPuffer” angehängt.

Hier kommt nun auch das im Abschnitt “Serieller Monitor” erwähnte Zeilenabschlusszeichen ins Spiel. In diesem (und jedem anderen Terminalprogramm) lässt sich nämlich ein Zeichen einstellen, welches nach jedem Absenden eines Zeichens oder einer Zeichenkette automatisch angehängt und mitgesendet wird.

Deze regeleinden kunnen nu worden gebruikt om te herkennen of de eerder gelezen string compleet is en dus kan worden geëvalueerd.
Dit betekent dat elk ontvangen karakter gecontroleerd moet worden om te zien of het de regeleinde is. In de bovenstaande code wordt dit gedaan door

als (currentChar == 13)...

Lasst euch von der 13 nicht verwirren. Das Problem bei Zeilenabschlusszeichen ist nämlich, dass diese auf einer Tastatur nicht aufgeführt sind. Man kann sie also nicht als Vergleichszeichen in den Code “eintippen”.
Om het ontvangen teken toch te controleren op de tekenafsluiting, gebruiken we hier een truc.

dankzij de ASCII-tabel weten we dat elk teken in de computer overeenkomt met een bytewaarde (d.w.z. een numerieke waarde tussen 0 en 255).
Wenn ihr im Arduino also zum Beispiel ein “A” speichert, so speichert dieser eigentlich den Zahlenwert “65”.
Würde man nun prüfen wollen ob ein empfangenes Zeichen einem “A” entspricht könnte man entweder

als (huidigekarakter == "A")

of ook

als (huidigeteken == 65)

schrijven. Beide vergelijkingen zouden tot hetzelfde resultaat leiden.

We zullen nu gebruik maken van deze truc. Om te controleren of het huidige ontvangen teken een regeleinde is, zoals de CR (=CarriageReturn), controleren we niet het teken zelf, maar de waarde van het teken in de ascii-tabel: dus 13.

Zodra dit teken is ontvangen, weten we dat alle eerder verzonden tekens een commando moeten voorstellen en nu moeten worden geëvalueerd.

3. hoe deze ontvangen commando's kunnen worden geëvalueerd

Wir bzw. der Arduino hat nun also einen Befehl empfangen. Dieser ist in der String-Variable “seriellerPuffer” gespeichert und wird als Funktionsparameter an die Funktion “empfangene_zeichen_auswerten()” übergeben.

Deze functie zou er bijvoorbeeld zo uit kunnen zien:

void received_characters_evaluate(String serialBuffer)
{
   Serial.println("" + String(serialBuffer) + "" ontvangen."); //uitvoer van de zojuist ontvangen opdracht.
   
   if (serialBuffer == "simpleCommandDerWasTut")
   {
      simpler_command_the_what_does();
   } anders als (serialBuffer.indexOf('=') != -1)
   {
      uint16_t receivedValue = serialBuffer.substring(serialBuffer.indexOf('=') + 1).toInt();
      String ontvangenParameter = serialBuffer.substring(0, serialBuffer.indexOf('='));
      
      if (receivedParameter == "commandSetOneValue")
      {
         als (receivedValue = 0)
         {
            command_the_one_value_sets(receivedvalue );
         } anders
         {
            Serial.println(F("Waarde buiten het toegestane waardenbereik.");
         }
      } anders
      {
         Serial.print(F("De opdracht ""));
         Serial.print(serialBuffer);
         Serial.print(F("" werd niet herkend.");
      }
   } anders
   {
      Serial.print(F("Het commando "");
      Serial.print(serialBuffer);
      Serial.print(F("" werd niet herkend.");
   }
}

Nadat een commando is ontvangen, wordt het opnieuw uitgevoerd, wat erg praktisch is voor debugging-doeleinden. Op deze manier kun je controleren welke tekenreeks uiteindelijk in de Arduino is aangekomen.

Danach kann mit einer einfachen IF-Abfrage geprüft werden welcher Zeichenkette der empfangene Befehl entspricht. Hier wird zum Beispiel geprüft ob der Befehl der Zeichenkette “simplerBefehlDerWasTut” entspricht.
Ist dies der Fall wird die Funktion “simpler_befehl_der_was_tut();” ausgeführt.

Mithilfe dieser “absoluten” Befehle könntet ihr nun einfache Befehle absetzen. Zum Beispiel um ein Licht ein- oder auszuschalten.

Um nun aber auch Werte übergeben zu können müssen auch Befehle der Form “helligkeitSetzenAuf=20” ausgewertet werden können.
Es muss also der Befehlsname (in diesem Fall “helligkeitSetzenAuf”) und der Wert (in diesem Fall “20”) erkannt werden.

Dit wordt gedaan in het verdere deel van de hierboven getoonde code.
Sollte nämlich keiner der “absoluten” Befehle zu der empfangenen Zeichenkette passen wird geprüft ob in der empfangenen Zeichenkette ein “=”-Zeichen Vorhanden ist.

Solltet Ihr also zum Beispiel den Befehl “setzeHelligkeit=100” an den Arduino gesendet haben wird er die gesamte Zeichenkette “setzeHelligkeit=100” keinem “absoluten” Befehl zuordnen können.

In dit geval wordt de ontvangen tekenreeks gecontroleerd op een gelijkteken en deze wordt ook gevonden.

De ontvangen tekenreeks wordt vervolgens opgesplitst in het gedeelte voor en na het gelijkteken met de volgende opdrachten.

uint16_t ontvangenWaarde = seriëlebuffer.substring(seriëlebuffer.indexOf('=') + 1).toInt(); String van ontvangen parameters = serialbuffer.substring(0, serialbuffer.indexOf('='));

Nun ist in der Variable “empfangenerWert” die “100” und in der Variable “empfangenerParameter” der Befehl “setzeHelligkeit” gespeichert.

Nadat de twee waarden uit de ontvangen string zijn gehaald, kunnen ze verder worden verwerkt en gebruikt.

Probeer het gewoon 🙂
Je kunt de volledige code om het opnieuw te proberen hier vinden:

/* _ _ _ _ _
                                 | | | | |(_) | |
  __ ____ ____ __ | | | ___ _ __ __| | _ _ _ __| | ___
    / / / / / / / / / | . ` | / _ | '__|/ _` || || | | | / _` | / _
    V V / V V / V /_ | | | __/| | (_| | | |_| | _| (_| | __/
    \_/\_/ \_/\_/ \_/\_/(_)|_| \_| \___||_| \__,_||_| \__, |(_)\__,_| \___|
                                                               __/ |
                                                              |___/
     serialTest door Fabian Steppat
     Info op https://www.nerdiy.de/ardunio-die-serielle-schnittstelle/

     Dit programma is vrije software: u mag het verspreiden en/of wijzigen
     onder de voorwaarden van de GNU General Public License zoals gepubliceerd door
     de Free Software Foundation, ofwel versie 3 van de Licentie, of
     (naar keuze) een latere versie.

     Dit programma wordt verspreid in de hoop dat het nuttig zal zijn,
     maar ZONDER ENIGE GARANTIE; zelfs zonder de impliciete garantie van
     VERKOOPBAARHEID of GESCHIKTHEID VOOR EEN BEPAALD DOEL.  Zie de
     GNU General Public License voor meer details.

     Je zou een kopie van de GNU Algemene Gebruikerslicentie moeten hebben ontvangen
     samen met dit programma ontvangen.  Zo niet, zie .

     Aanvullende informatie over dit project vind je op het volgende adres:
     
HowTo: Ardunio – Gebruik de seriële poort
Deze codesnippet is een basisconcept van seriële communicatie om een arduino te besturen via seriële commando's */ { Serial.begin(115200); } void loop() { check_serial_receive(); } void check_serial_receive() { String serialBuffer; while (Serial.available()) { char currentcharacter = (char)Serial.read(); if (currentcharacter == 13) { receive_char_evaluate(serialBuffer); } anders { serialBuffer += huidig teken; } } } void received_character_evaluate(String serialBuffer) { Serial.println("" + String(serialBuffer) + "" ontvangen."); Als (serialBuffer == "simplerCommandTheWhatDoes") { simpler_command_the_what_does(); } anders als (serialBuffer.indexOf('=') != -1) { uint16_t receivedValue = serialBuffer.substring(serialBuffer.indexOf('=') + 1).toInt(); String ontvangenParameter = serialBuffer.substring(0, serialBuffer.indexOf('=')); if (receivedParameter == "commandSetOneValue") { if (receivedValue & lt; = 23 & amp; & receivedValue & gt; = 0) { command_the_one_value_sets(receivedvalue ); } anders { Serial.println(F("Waarde buiten het toegestane waardenbereik."); } } anders { Serial.print(F("De opdracht "")); Serial.print(serialBuffer); Serial.print(F("" werd niet herkend."); } } anders { Serial.print(F("Het commando ""); Serial.print(serialBuffer); Serial.print(F("" werd niet herkend."); } }

Veel plezier met het project

Ik hoop dat alles werkte zoals beschreven. Zo niet, of als je vragen of suggesties hebt, laat het me weten in de commentaren. Ik zal dit dan zo nodig aan het artikel toevoegen.
Ideeën voor nieuwe projecten zijn altijd welkom. 🙂

PS Veel van deze projecten - vooral de hardwareprojecten - kosten veel tijd en geld. Natuurlijk doe ik dit omdat ik het leuk vind, maar als je het cool vindt dat ik de informatie met je deel, dan zou ik blij zijn met een kleine donatie aan het koffiefonds. 🙂

Koop Me a Coffee op ko-fi.com       

Kommentar hinterlassen

Het e-mailadres wordt niet gepubliceerd. Erforderliche Felder sind mit * markiert

Deze site gebruikt Akismet om spam te verminderen. Bekijk hoe je reactie-gegevens worden verwerkt.