Serial

Omschrijving
Serial verwijst niet naar een enkele functie, maar naar een verzameling functies die communicatie tussen een computer en een microcontrollerbord mogelijk maken. Over het algemeen is er ten minste één poort beschikbaar voor deze communicatie. Bovendien kan een microcontrollerbord ook met andere apparaten communiceren via deze poorten.

Hieronder bespreek ik enkele basis functies die het mogelijk maken om waarden vanaf het microcontrollerbord weer te geven in de seriële monitor van de Arduino IDE, en om gegevens vanuit de Arduino IDE (via de seriële monitor) naar het microcontrollerbord te sturen. Deze functionaliteit wordt vaak gebruikt voor het debuggen van een programma.

Seriële monitor in Arduino IDE gebruiken

Hoe maak je de seriële monitor zichtbaar in de Arduino IDE?
Dit kan op drie manieren, door:

  • in het menu te kiezen voor de opties ‘Hulpmiddelen’ en vervolgens ‘Seriële monitor’.
  • de toetsen combinatie Ctrl+Shift+M.
  • op het vergrootglas icoontje, rechtsboven te klikken

Zie de drie oranje pijlen in afb. 1

Afb. 1

Overzicht seriële monitor
In afbeelding 2 zie je het volledige venster van de seriële monitor. Linksboven wordt de poort getoond die door de seriële monitor wordt gebruikt, welke overeenkomt met de poort van het microcontrollerbord (in afb.2 is dit ‘COM4’). Direct daaronder bevindt zich het invoerveld (dit gebruik je voor de communicatie van de computer naar het microcontrollerbord), met rechts de ‘Verzenden’ knop. Onder het invoerveld vind je het uitvoergedeelte van het venster, waar de gegevens die van het microcontrollerbord naar de computer worden gestuurd, worden weergegeven.

Op de onderste regel staan de opties:

  • Autoscroll
    Als het vinkje is ingeschakeld, wordt de laatste uitvoer op het scherm weergegeven en worden oudere regels naar boven geschoven, waardoor na verloop van tijd de bovenste regels niet meer zichtbaar zijn. Telkens wanneer er een nieuwe regel wordt toegevoegd, herhaalt dit proces zich. Aan de rechterkant verschijnt een scrollbalk waarmee je de bovenste regels weer zichtbaar kunt maken.
  • Toon tijdstempel
    Als deze optie is aangevinkt, wordt bij elke regel een tijdstempel weergegeven in de vorm van ’17:02:11.787 ->’, wat staat voor ‘uur : minuut : seconden . milliseconden ->’. Na de pijl wordt de data weergegeven.
  • Einde regel (afb. 3)
    Zet deze optie op ‘Geen regeleinde’. Ik heb alle mogelijkheden geprobeerd, maar de uitvoer verandert niet. Dit is waarschijnlijk gerelateerd aan specifieke microcontrollerborden van Arduino.
  • Snelheid seriële poort (afb. 4)
    Dit is de snelheid waarmee gecommuniceerd wordt over de seriële poort. Deze snelheid hoort overeen te komen met wat in het programma is gedefinieerd (bijvoorbeeld: ‘Serial.begin(115200)’). Daarom moet je in de lijst ook voor deze waarde kiezen, zoals in afbeelding 4 is gedaan. Mocht er onleesbare tekst verschijnen in het uitvoergedeelte van de seriële monitor, dan betekent dit dat de waarden niet overeenkomen.
  • Knop ‘Uitvoer wissen’ (afb. 4)
    Als je op deze knop klikt, wordt alle uitvoer van het uitvoer venster verwijderd.

Afb. 2

Afb. 3

Afb. 4

Serial

Een microcontrollerboard kan meerdere seriële poorten hebben. De ESP32 die in deze workshop wordt gebruikt, heeft drie seriële poorten, ook wel UART’s genoemd. UART staat voor Universal Asynchronous Receiver/Transmitter. In je programma worden deze aangeduid als Serial, Serial1 en Serial2. Serial is verbonden met de USB-poort, waardoor het mogelijk is om te communiceren met de seriële monitor van de Arduino IDE. In deze ga ik allen in uitleg licht ik alleen Serial toe.

Serial.begin()

Omschrijving
De Serial.begin() functie start de communicatie tussen je Arduino en de computer via de seriële monitor. Bij het gebruik van deze functie geef je aan hoe snel de gegevens verstuurd moeten worden. Deze snelheid moet hetzelfde zijn als de snelheid die je instelt in de seriële monitor op je computer. Normaal gesproken zet je deze functie één keer in het begin van je code, meestal in het blokje dat setup() heet, zodat je Arduino weet dat hij klaar is om te beginnen met het verzenden en ontvangen van informatie.

Syntax
Serial.begin(snelheid);

Parameters
Serial: seriële poort object. Mogelijke waarden voor de ESP32 zijn: Serial, Serial1 en Serial2.
snelheid: Dit is de snelheid waarmee de seriële poort van de computer en de microcontroller met elkaar communiceren. Mogelijke waardes zijn: 300, 1200, 2400, 4800, 9600, 192000, 38400, 57600, 74880, 115200, 230400, 250000, 500000, 1000000 en 2000000 baud. De vetgedrukte zijn de meest gebruikelijke. Hiervan wordt 115200 in de workshops gebruikt.

Geeft terug
Niets

Voorbeeld

void setup() {
  Serial.begin(115200); // opent seriële poort en zet de snelheid op 115200 baud
}

void loop() {
  Serial.print("Hallo!");
}

Toelichting voorbeeld

void setup()
Serial.begin(115200);
Start de communicatie met de seriële poort op een snelheid van 115200 baud. Dit betekent dat je deze snelheid ook moet kiezen in het venster van de seriële monitor op je computer.

void loop()
Serial.print(“Hallo!”);
Stuurt informatie van het microcontrollerbord naar de computer.

Notities en waarschuwingen
Zorg ervoor dat de snelheid die je in je programma instelt hetzelfde is als de snelheid die je kiest in de seriële monitor. Als deze niet hetzelfde zijn, werkt het niet goed en zie je misschien gekke tekens op je scherm.

Let op dat je ‘Serial.begin()’ met een hoofdletter ‘S’ schrijft.

Serial.print() / Serial.println()

Omschrijving
Met de functies Serial.print() en Serial.println() kun je gegevens van je microcontrollerbord naar de seriële monitor op je computer sturen. Als je Serial.println() gebruikt, stuurt het de gegevens en gaat daarna automatisch naar de volgende regel. Als je Serial.print() gebruikt, blijft de cursor op dezelfde regel staan, en wat je daarna stuurt, komt direct achter de vorige gegevens te staan.

Syntax
Serial.print(gegevens)
Serial.println(gegevens)

Parameters
Serial: seriële poort object. Mogelijke waarden voor de ESP32 zijn: Serial, Serial1 en Serial2.
gegevens: zijn teksten, getallen of variabelen (bij variabelen de inhoud ervan) die je naar de seriële monitor wil sturen.

Geeft terug
Niets

Voorbeeld

void setup() {
  Serial.begin(115200); // opent seriële poort en zet de snelheid op 115200 bps
}

void loop() {
  Serial.println("Eerste regel.");
  Serial.println("Tweede regel.");
  Serial.print("Begin derde regel ");
  Serial.print("en het vervolg van de derde regel, ");
  Serial.println("het einde van de derde regel.");
  Serial.println("Vierde regel.");
  Serial.println();
  int getal = 10;
  Serial.print("Het getal is: ");
  Serial.println(getal);
  Serial.print("Het tweede getal is: ");
  Serial.println(5);
  delay(300000);
}

Uitvoer van het programma:

Eerste regel.
Tweede regel.
Begin derde regel en het vervolg van de derde regel, het einde van de derde regel.
Vierde regel.

Het getal is: 10
Het tweede getal is: 5

Elk gebruik van println() zorgt ervoor dat je naar een nieuwe regel gaat na het versturen van de tekst, terwijl print() je op dezelfde regel houdt.

Toelichting voorbeeld
In het stukje code hierboven, worden verschillende dingen verstuurd van je microcontroller naar de seriële monitor op je computer. Hier is wat er stap voor stap gebeurt:

void setup()
Serial.begin(115200);
Dit initialiseert de seriële communicatie met een baud rate (snelheid) van 115200 bits per seconde. Het zorgt ervoor dat de Arduino kan communiceren met een computer via de seriële monitor.

void loop()
Serial.println(“Eerste regel.”);
Dit stuurt de tekst “Eerste regel.” naar de seriële monitor en gaat daarna naar de volgende regel.

Serial.println(“Tweede regel.”);
Dit stuurt de tekst “Tweede regel.” en gaat naar de volgende regel.

Serial.print(“Begin derde regel “);
Dit stuurt de tekst “Begin derde regel ” naar de monitor, maar blijft op dezelfde regel.

Serial.print(“en het vervolg van de derde regel, “);
Dit voegt de tekst “en het vervolg van de derde regel, ” direct achter de vorige tekst toe en blijft op dezelfde regel.

Serial.println(“het einde van de derde regel.”);
Dit voegt “het einde van de derde regel.” toe aan het einde van de derde regel en gaat daarna naar de volgende regel.

Serial.println(“Vierde regel.”);
Dit stuurt “Vierde regel.” en gaat naar de volgende regel.

Serial.println();
Deze opdracht verstuurd geen gegevens naar de computer, maar zorgt er wel voor dat de uitvoer naar de volgende regel gaat. Er ontstaat een lege regel. Dit is gemakkelijk om gegevens die je naar de computer stuurt van elkaar te scheiden en houdt het overzichtelijk.

int getal = 10;
Maakt een variabele van het soort integer (int) en geeft deze een waarde van 10.

Serial.print(“Het getal is: “);
Dit stuurt de tekst ‘Het getal is: ‘ naar de monitor en blijft op dezelfde regel.

Serial.println(getal);
Dit stuurt de inhoud van de variabele getal naar de computer, in dit geval ’10’, en gaat naar de volgende regel.

Serial.print(“Het tweede getal is: “);
Dit stuurt de tekst ‘Het tweede getal is: ‘ naar de monitor en blijft op dezelfde regel.

Serial.println(5);
Dit stuurt het getal 5 naar de monitor en gaat naar de volgende regel.

delay(300000);
Het programma wacht 300.000 milliseconden. Dit is 5 minuten en gaat dan verder. Omdat dit de laatste regel in het programma is, gaat het programma verder bij de eerste regel van loop(). Dit is regel 6 in het voorbeeld.

Notities en waarschuwingen
Let op dat je ‘Serial.print()’ en ‘Serial.println’ met een hoofdletter ‘S’ schrijft.

Serial.readString()

Omschrijving
Leest een tekens uit de serial buffer en geeft die inhoud terug aan een variabele. Maar voordat je dit kunt doen, moet je de seriële poort aanzetten met de functie Serial.begin(115200). Zonder dit werkt de seriële poort niet en kun je geen gegevens lezen en schrijven.

Syntax
Serial.readString()

Parameters
Serial: seriële poort object. Mogelijke waarden voor de ESP32 zijn: Serial, Serial1 en Serial2.

Geeft terug
Een string (alle tekens) die uit de buffer van serial gelezen zijn.

Voorbeeld

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

void loop() {
  Serial.println("Geef een kleur in:");
  while (Serial.available() == 0) {}     //wacht totdat er gegevens aanwezig zijn
  String teststr = Serial.readString();  //Lees gegevens uit de serial buffer
  teststr.trim();                        // Verwijder alle '\r', '\n' en spaties aan het einde van de gegevens
if (teststr == "rood") {
    Serial.println("Een primaire kleur");
  } else {
    Serial.println("Andere tekst");
  }
}

Toelichting voorbeeld

void setup()
Serial.begin(115200);
Dit initialiseert de seriële communicatie met een baud rate (snelheid) van 115200 bits per seconde. Het zorgt ervoor dat de Arduino kan communiceren met een computer via de seriële monitor.

void loop()
Serial.println(“Geef een kleur in: “);
Dit stuurt de tekst “Geef een kleur in: ” naar de seriële monitor als een prompt voor de gebruiker om gegevens in te voeren.

while (Serial.available() == 0) {}
Dit is een wachtlus die zich blijft herhalen totdat er gegevens beschikbaar zijn in de seriële buffer. Serial.available() retourneert het aantal bytes dat beschikbaar is om te lezen. Als dit aantal 0 is, wacht de lus totdat er gegevens beschikbaar zijn. Serial.available() geeft dan een aantal dat groter is dan 0.

String teststr = Serial.readString();
Deze regel leest de beschikbare gegevens uit de seriële buffer als een string en slaat deze op in de variabele teststr. In deze regel wordt ook ‘teststr’ gedefinieerd als string.

teststr.trim();
Dit verwijdert eventuele witruimten, inclusief carriage return (\r) en line feed (\n), aan het einde van de string teststr (dit zijn tekens die automatisch meegestuurd worden door de computer). Dit zorgt ervoor dat de string nauwkeurig kan worden vergeleken zonder extra spaties of nieuwe regels.

if (teststr == “rood”) { Serial.println(“Een primaire kleur”); } else { Serial.println(“Andere tekst”); }
Dit is een voorwaardelijke structuur.
Als de string teststr gelijk is aan “rood”, dan print het programma “Een primaire kleur” naar de seriële monitor.
Anders, print het programma “Andere tekst” naar de seriële monitor.

Notities en waarschuwingen
Let op!!!
Dat je Serial.readString() met de letters ‘S’ als hoofdletters schrijft. Doe je dit niet, krijg je een foutmelding.

Serial.read()

Omschrijving
Serial.read() is een functie die je gebruikt om informatie te lezen die naar je Arduino wordt gestuurd via de seriële poort. Maar voordat je dit kunt doen, moet je de seriële poort aanzetten met de functie Serial.begin(115200). Zonder dit werkt de seriële poort niet en kun je geen gegevens lezen en schrijven.

Syntax
Serial.read()

Parameters
Serial: seriële poort object. Mogelijke waarden voor de ESP32 zijn: Serial, Serial1 en Serial2.

Geeft terug
Geeft het eerste teken terug van de seriële buffer. Deze waarde is van type integer.

Voorbeeld

void setup() {
  Serial.begin(115200); // Start de seriële communicatie met 115200 baud
  Serial.println("Type iets en druk op Enter:");
}

void loop() {
  if (Serial.available() > 0) { // kijkt of er data beschikbaar is om te lezen
    int incomingByte = Serial.read(); // Lees het binnenkomende byte (is een teken)
    Serial.print("Ontvangen: ");
    Serial.println(incomingByte, DEC); // Print de ontvangen byte als decimaal getal
  }
}

Toelichting voorbeeld

void setup()
Serial.begin(115200);
Hierin start je de seriële communicatie met Serial.begin(115200);, wat betekent dat de communicatie op een snelheid van 115200 baud plaatsvindt.

Serial.println(“Type iets en druk op Enter:”);
Vervolgens print je een bericht om de gebruiker te laten weten dat ze iets moeten typen.

void loop()
if (Serial.available() > 0) {}
Deze functie kijkt of er een of meerdere tekens in de invoer buffer staan, dit doet het deel ‘Serial.available’. De functie geeft een waarde terug en de if-functie kijkt of die waarde groter is dan 0. Als dat waar is, worden de commando’s die tussen de accoladen ‘{}’ staan uitgevoerd. Als dit niet het geval is gaat het programma verder achter de afsluit accolade ‘}’.

int incomingByte = Serial.read();
Als er data is, wordt deze gelezen met Serial.read(), wat één byte data van de seriële buffer leest en in de variabele ‘incomingByte’ wordt gezet. Als het teken gelezen is, wordt deze uit de buffer gehaald.

Serial.print(“Ontvangen: “);
De tekst ‘Ontvangen: ‘ wordt naar de seriële monitor gestuurd.

Serial.println(incomingByte, DEC);
Deze byte wordt vervolgens geprint als decimaal getal met Serial.println(incomingByte, DEC); en gaat vervolgens naar de volgende lijn.

Notities en waarschuwingen

Serial.available()

Omschrijving
De functie Serial.available() in de Arduino programmeertaal wordt gebruikt om te controleren hoeveel bytes er beschikbaar zijn om te lezen van de seriële buffer. Het wordt gebruikt in een programma om te controleren voorafgaand aan Lezen van de seriële buffer. Het is gebruikelijk om Serial.available() te gebruiken voordat je seriële gegevens leest met functies zoals Serial.read() of Serial.readString(). Dit voorkomt dat je probeert te lezen als er geen gegevens zijn, wat fouten kan voorkomen.

Syntax
Serial.available()

Parameters
Serial: seriële poort object. Mogelijke waarden voor de ESP32 zijn: Serial, Serial1 en Serial2.

Geeft terug
Retourneert een Integer
De functie retourneert een integer die aangeeft hoeveel bytes er beschikbaar zijn in de seriële buffer. Als er geen gegevens beschikbaar zijn, retourneert het 0.

Voorbeeld

void setup() {
  Serial.begin(115200); // Initialiseer seriële communicatie op 115200 bps
}

void loop() {
  if (Serial.available() > 0) {  // Controleer of er gegevens beschikbaar zijn
    int incomingByte = Serial.read();  // Lees de inkomende byte
    Serial.print("Ontvangen: ");
    Serial.println(incomingByte, DEC);  // Print de ontvangen byte als decimaal getal
  }
} 

Toelichting voorbeeld

void setup()
Serial.begin(115200);
Dit initialiseert de seriële communicatie met een baud rate (snelheid) van 115200 bits per seconde. Het zorgt ervoor dat de Arduino kan communiceren met een computer via de seriële monitor.

void loop()
if (Serial.available() > 0)
De if-voorwaarde Serial.available() > 0 controleert of er minstens één byte beschikbaar is in de seriële buffer.
Als er gegevens beschikbaar zijn, wordt de eerste byte gelezen met Serial.read() en opgeslagen in de variabele ‘incomingByte’. Het teken dat gelezen is wordt uit de seriële buffer verwijdert.

Serial.println(incomingByte, DEC);
De ontvangen byte wordt vervolgens geprint naar de seriële monitor.

Notities en waarschuwingen
Geen.