Serial communication between Arduino and P5

Arduino transmitting
Using the the Arduino example “AnalogReadSerial” we get a simple source of values to transmit. NOTE! The last line in the code is something like “delay(2);”. That small delay will overwhelm P5. Instead try something like “delay(50);”. this will keep the pace quick but not choking.
After that, in the HTML-page in the P5 project we need to add a line at the top to include the library for serial communication:

<script src="https://unpkg.com/@gohai/p5.webserial@^1/libraries/p5.webserial.js"></script> 

P5 code to receive:

let port;
let connectBtn;

function setup() {
  createCanvas(400, 400);

  port = createSerial();

  // in setup, we can open ports we have used
  // previously without user interaction
  let usedPorts = usedSerialPorts();
  if (usedPorts.length > 0) {
    port.open(usedPorts[0], 9600);
  }

  // if this is first use, you connect via
  // user interaction (see connectBtnClick below)
  connectBtn = createButton('Connect to Arduino');
  connectBtn.position(0, 0);
  connectBtn.mousePressed(connectBtnClick);
}

function connectBtnClick() {
  if (!port.opened()) {
    port.open('Arduino', 9600);
  } else {
    port.close();
  }
}

function draw() {
  // reads in complete lines and uses
  // the value to draw an ellipse
  let value1 = port.readUntil("\n");

  // hides button if connected
  if (!port.opened()) {
    connectBtn.html('Connect to Arduino');
  } else {
    connectBtn.html('Disconnect');
    connectBtn.remove();
  }

  //Here we do something with value of value1
  if (value1.length > 0) {
    background(128);
    print(value1);
    ellipse(200,200,value1,value1);
  }
}



P5 receiving TWO values!
If we want to send several values we can have the Arduino do that with a comma between values as shown in the altered Arduino code beneath. Note the use of both print and println to make it all be one transmitted line.

  Serial.print(oneValue);
  Serial.print(",");
  Serial.println(otherValue);

By changing the part of draw() in the P5 code that deals with receiving data we can handle two values.

  // reads in complete lines and uses
  // the values to draw an ellipse
  let str = port.readUntil("\n");
  
  //create array to store values
  let values = [];
  
  // Split string using ',' as a 
  //delimiter/marker
  values = split(str, ","); 

  //Here we do something with value of str
  if (values[0]>0) {
    background(128);
    ellipse(width / 2, height / 2, values[0], values[1]);
  }

This means you now have the tool to influence anything you played around with in P5 (text, images, sound, filters, etc) with whatever input you put on Arduino (buttons, distance/light/pressure-sensors, knobs, sliders, etc).

P5 transmitting
We can also do the opposite. Control stuff in the real world with stuff on the computer. Keyboard, mouse, GUI, network etc.


P5 code to transmit
We start out with mostly the same P5 code as before, but in draw() we skip the code to manage receiving values and instead write the following. The first part is just a way to create a number to send. In this case by reading mouseX, rework it a bit and then put it in the variable “brightness”. The command port.write is what actually sends the number to Arduino.

//remember to round the values as
// you can't send decimal values   
  let brightness1 = round(map(mouseX,0,width,0,255))
  background(brightness1)

//send value,finish with a newline
//character for Arduino recieving  
  port.write(brightness1+'\n'); 


Arduino code to receive

void setup() {
   // initialize serial:
   Serial.begin(9600);
   // make the led pin an output:
   pinMode(9, OUTPUT);
}

void loop() {
   // if there's any serial data available, read it:
   while (Serial.available() > 0) {

     // look for the next valid integer in 
     // the incoming serial stream:
     int value1 = Serial.parseInt(); 

     // look for the newline. That's the end of your
     // sentence, then light up LED
     if (Serial.read() == '\n') {
       analogWrite(9, value1);
     }
   }
   delay(20);
}

Sending several values from P5
All you need to do is to add more variables to the port.write-command. Below I send the values of variables brightness1 and brightness2. Just make sure you add a comma in between and the /n at the end. This is to make the values distinct from eachother.

port.write(brightness1+','+brightness2+'\n'); 

Receiving several values on Arduino
It’s just a question of listening for more values. But it’s important that you program to receive as many as you send. Otherwise you can get unpredictable behaviour.

// look for the next integer in the incoming serial stream:
int value1 = Serial.parseInt(); 
// do it again:
int value2 = Serial.parseInt();