Skip to content
ICT Fusion Knowledgebase

P5js WebSerial

Om te communiceren met een microcontroller is een bekabelde verbinding waar je serieel data verstuurt en ontvangt de makkelijkste manier om data uit te wisselen tussen een computer en een microcontroller. De data die jouw microcontroller verstuurt kan je in jouw webbrowser lezen als je gebruik maakt van de WebSerial API.

Dit wordt ondersteund door een aantal browsers, waaronder Chrome en Edge, maar niet allemaal. Deze pagina gaat in op hoe je deze WebSerial API kunt gebruiken in jouw p5.js project.

Plugin

Om gebruik te kunnen maken van de WebSerial API in jouw p5.js project heb je een plugin nodig welke je aan je p5.js project kunt toevoegen.

  1. Download de plugin van p5.webserial (Code > Download ZIP).
  2. Op je computer pak je het ZIP bestand uit en navigeer je naar de map libraries.
  3. Kopieer het bestand p5.webserial.js naar de plek waar jouw p5.min.js bestand zich bevindt, dit is meestal in de map libraries van jouw p5.js project.
  4. Voeg nu aan jouw HTML, na het importeren van p5.js, de volgende regel toe:
    <script src="libraries/p5.webserial.js"></script>
    
  5. Nu kan je de WebSerial API gebruiken in jouw p5.js project.

Seriële poort openen

De eerste stap die je moet zetten om data uit te kunnen wisselen met een microcontroller is de seriële poort openen. Vanwege veiligheidsredenen kan een webbrowser geen seriële poort openen zonder dat de gebruiker dit eerst goedkeurt.

In P5js kan je een knop maken die de gebruiker kan indrukken om de seriële poort te openen. In de setup functie van je p5.js project kan je deze knop maken:

let serialOpenButton;

function setup() {
    createCanvas(400, 400);
    serialOpenButton = createButton('Open seriële poort');
}

En met deze knop kan je de seriële poort openen:

let serialOpenButton;
let serialPort;

function setup() {
    createCanvas(400, 400);
    serialOpenButton = createButton('Open seriële poort');

    serialOpenButton.mousePressed(() => {
        console.log('Open seriële poort');
        serialPort = createSerial();
        serialPort.open(115200); // 115200 is the baud rate of the serial port, same as the baud rate of the microcontroller
    });
}

Als je deze sketch nu test in een webbrowser die deze API ondersteunt (Chrome en Edge) dan zou je een popup moeten zien waarin je een seriële poort kunt selecteren. In dit venster kan je dan een aangesloten microcontroller selecteren. De live preview in VSCode ondersteunt dit niet.

Als dit lukt dan kun je verdergaan met het lezen van de data die de microcontroller verstuurt. Als het niet lukt controleer dan de console log in de webbrowser.

WebSerial poort openen

Lezen van de data

Als je op je microcontroller een programma hebt draaien dat data naar de seriële poort verstuurt dan kunnen we dat inlezen in de p5.js sketch. Een manier om data te versturen vanaf je microcontroller kan bijvoorbeeld zijn:

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

void loop() {
    Serial.println("test123");
    delay(1000);
}

Dit zal welke seconde het bericht “test123” versturen over de seriële poort. Nu kan je in de p5.js sketch de data proberen in te lezen.

function draw() {
    background(220); // set the background color to a light gray so we can see p5js is working

    if (serialPort && serialPort.available() > 0) {
        let data = serialPort.readUntil('\n');
        console.log(data);
    }
}

De console.log() functie zal de data die de microcontroller verstuurt naar de console log in de webbrowser schrijven. Open de netwerktool in de browser en kijk in de console log.

WebSerial poort openen

Wat er in dit stukje code allemaal staat is:

  • De serialPort variabele wordt gecheckt of deze bestaat en is ingevuld.
  • Met de available() functie wordt gecheckt of er data beschikbaar is op de seriële poort.
    • Deze functie geeft het aantal bytes dat beschikbaar is op de seriële poort terug.
    • Als deze groter is dan 0 dan is er data beschikbaar op de seriële poort om in te lezen.
    • Als deze 0 is dan is er geen data beschikbaar op de seriële poort om in te lezen.
  • De readUntil() functie wordt gebruikt om de data in te lezen.
    • Deze functie leest de data tot aan een bepaald teken, in dit geval het teken ‘\n’.
    • Het teken ‘\n’ is het newline teken, dit wil zeggen dat de data tot aan een nieuwe regel wordt gelezen.
    • Deze functie geeft het resultaat terug aan de variabel data.
  • De console.log() functie wordt gebruikt om de inhoud van de data-variabel naar de console log in de webbrowser te schrijven.
    • Deze functie schrijft de data naar de console log in de webbrowser.
    • Je kan allerlei datatypes uitprinten; strings, ints, doubles, arrays, objecten, …

Versturen van data naar de microcontroller

Naast het lezen van data vanaf de microcontroller kan je ook data naar de microcontroller versturen. De microcontroller zal de data dan ontvangen en kunnen gebruiken.

Een manier om dit te kunnen simuleren is door een programma te schrijven voor de microcontroller die een LED aan en uit zet.

void setup() {
    Serial.begin(115200);
    // Define the LED_BUILTIN-pin as output
    pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
    // Check if there is data available on the serial line to read from.
    if(Serial.available() > 0) {
      // Read one byte from the Serial communication.
      byte data = Serial.read();

      // Print the data as hexadecimal value
      Serial.printf("Data (hexadecimal): %02X\n", data);

      // Check if data compares to 0b0000 0001 (binary), or 1 (decimal), or 0x01 (hexadecimal)
      if(data == 0b00000001) {
        // Set the output of the LED_BUILTIN-pin to HIGH.
        digitalWrite(LED_BUILTIN, HIGH);
      // Check if data compares to 0b0000 0000 (binary), or 0 (decimal), or 0x00 (hexadecimal)
      } else if(data == 0b00000000) {
        // Set the output of the LED_BUILTIN-pin to LOW.
        digitalWrite(LED_BUILTIN, LOW);
      }
    }
}

Wat je in deze code kan lezen:

  • De LED_BUILTIN-pin wordt gedefinieerd als uitgang.
  • Via de Serial.available() functie wordt gecheckt of er data beschikbaar is op de seriële poort om in te lezen.
  • Er wordt één byte gelezen van de seriële poort via de Serial.read() functie.
    • Deze data wordt uitgeprint als hexadecimal waarde.
  • Er wordt gecheckt of de data gelijk is aan 0b0000 0001 (binary), of 1 (decimal), of 0x01 (hexadecimal).
    • Als de data gelijk is aan 0b0000 0001 (binary), of 1 (decimal), of 0x01 (hexadecimal) dan wordt de LED_BUILTIN-pin op HIGH gezet.
    • Als de data gelijk is aan 0b0000 0000 (binary), of 0 (decimal), of 0x00 (hexadecimal) dan wordt de LED_BUILTIN-pin op LOW gezet.

We weten nu dus dat we een waarde kunnen versturen naar de microcontroller en deze deze kan gebruiken om de LED aan en uit te zetten. Daarvoor kunnen we nu twee knoppen maken in de p5.js sketch.

let serialOpenButton;
let serialPort;
let ledOnButton;
let ledOffButton;

function setup() {
    createCanvas(400, 400);
    serialOpenButton = createButton('Open seriële poort');
    ledOnButton = createButton('LED aan');
    ledOffButton = createButton('LED uit');

    serialOpenButton.mousePressed(() => {
        console.log('Open seriële poort');
        serialPort = createSerial();
        serialPort.open(115200); // 115200 is the baud rate of the serial port, same as the baud rate of the microcontroller
    });
}

LED buttons

Nu de knoppen gemaakt zijn kan je een event listener toevoegen aan de knoppen om de data naar de microcontroller te versturen. Deze listeners hoeven eenmalig op te starten, dus plaats je in de setup functie van je p5.js sketch.

ledOnButton.mousePressed(() => {
    serialPort.write(1);
});
ledOffButton.mousePressed(() => {
    serialPort.write(0);
});

De serialPort.write() functie wordt gebruikt om de data naar de microcontroller te versturen.

Belangrijk is wat je meegeeft aan deze functie, dit kan een getal, een string of een array zijn (getallen worden als bytes verstuurd).

Wanneer je nu op de knoppen klikt zal de LED aan en uit moeten gaan. Mocht het niet werken controleer dan de console log in de webbrowser.