Week 8
Oct 3, 2022
Week 8
Duplex Serial Communications
Basic Circuit
This program will send the two analog sensor values and then the pushbutton. All three will be ASCII-encoded numeric strings, separated by commas. The whole line of sensor values will be terminated by carriage return (r, ASCII 13) and newline (n, ASCII 10).

const
int
buttonPin
=
2
;
void
setup
() {
// configure the serial connection:
Serial.begin
(
9600
);
// configure the digital input:
pinMode
(buttonPin,
INPUT
);
}
void
loop
() {
// read the first analog sensor:
int
sensorValue
=
analogRead
(A0);
// print the results:
Serial.print
(sensorValue);
Serial.print
(
","
);
// read the second analog sensor:
sensorValue
=
analogRead
(A1);
// print the results:
Serial.print
(sensorValue);
Serial.print
(
","
);
// read the button:
sensorValue
=
digitalRead
(buttonPin);
// print the results:
Serial.println
(sensorValue);
}

Receive a data in P5.js
index.html
-> Edit the head of the document by adding these lines to include libraries. |
The setup of the sketch will initialize the P5.webserial library and define callback functions for serial events.
Code for sketch.js
// variable to hold an instance of the p5.webserial library:
const
serial
=
new p5.WebSerial();
// HTML button object:
let portButton;
let inData;
// for incoming serial data
let outData;
// for outgoing data
function
setup
() {
createCanvas(
400
,
300
);
// make the canvas
// check to see if serial is available:
if
(
!
navigator.serial) {
alert(
"WebSerial is not supported in this browser. Try Chrome or MS Edge."
);
}
// if serial is available, add connect/disconnect listeners:
navigator.serial.addEventListener(
"connect"
, portConnect);
navigator.serial.addEventListener(
"disconnect"
, portDisconnect);
// check for any ports that are available:
serial.getPorts();
// if there's no port chosen, choose one:
serial.on(
"noport"
, makePortButton);
// open whatever port is available:
serial.on(
"portavailable"
, openPort);
// handle serial errors:
serial.on(
"requesterror"
, portError);
// handle any incoming serial data:
serial.on(
"data"
, serialEvent);
serial.on(
"close"
, makePortButton);
}
function draw() {
}
// if there's no port selected,
// make a port select button appear:
function makePortButton() {
// create and position a port chooser button:
portButton
=
createButton(
'choose port'
);
portButton.position(
10
,
10
);
// give the port button a mousepressed handler:
portButton.mousePressed(choosePort);
}
// make the port selector window appear:
function choosePort() {
serial.requestPort();
}
// open the selected port, and make the port
// button invisible:
function openPort() {
// wait for the serial.open promise to return,
// then call the initiateSerial function
serial.open().then(initiateSerial);
// once the port opens, let the user know:
function initiateSerial() {
console.log(
"port open"
);
}
// hide the port button once a port is chosen:
if
(portButton) portButton.hide();
}
// read any incoming data as a byte:
function serialEvent() {
}
// pop up an alert if there's a port error:
function portError(err) {
alert(
"Serial port error: "
+
err);
}
// try to connect if a new serial port
// gets added (i.e. plugged in via USB):
function portConnect() {
console.log(
"port connected"
);
serial.getPorts();
}
// if a port is disconnected:
function portDisconnect() {
serial.close();
console.log(
"port disconnected"
);
}
function
serialEvent() {
// read a string from the serial port
// until you get carriage return and newline:
var
inString = serial.readStringUntil(
"rn"
);
//check to see that there's actually a string there:
if
(inString) {
// split the string on the commas:
var
sensors = split(inString,
","
);
if
(sensors.length > 2) {
// if there are three elements
// element 0 is the locH:
locH = map(sensors[0], 0, 1023, 0, width);
// element 1 is the locV:
locV = map(sensors[1], 0, 1023, 0, height);
// element 2 is the button:
circleColor = 255 - sensors[2] * 255;
}
}
}
and the draw() function will be like this
function
draw() {
background(0);
// black background
fill(circleColor);
// fill depends on the button
ellipse(locH, locV, 50, 50);
// draw the circle
}
and we need to set var locH and locW on the top or our code;
// variables for the circle to be drawn:
let
locH, locV;
let
circleColor = 255;

And it works! I can control X and Y positions of the circle with 2 potentiometers.
Flow Control: Call and Response (Handshaking)
Description by the lab:
Sometimes you can run into a problem when the sender sends faster than the receiver can read. When this happens, the receiver program slows down as the serial buffer fills up. You can manage this by implementing some form of flow control. The simplest way do to this is using a call-and-response method, where the sending program only sends when it’s told to do so, and the receiving program has to request new data every time it finishes reading what it’s got.You can add handshaking to the code above fairly simply. Modify the Arduino code as follows. First, add a new block of code in the
setup()
This block sends out a message until it gets a byte of data from the remote computer:
Arduino Codes
void
setup
() {
Serial.begin
(
9600
);
while
(
Serial.available
() <
=
0
) {
Serial.println
(
"hello"
);
// send a starting message
delay
(
300
);
// wait 1/3 second
}
}
void
loop
() {
if
(
Serial.available
() >
0
) {
// read the incoming byte:
int
inByte
=
Serial.read
();
// read the sensor:
sensorValue
=
analogRead
(A0);
// print the results:
Serial.print
(sensorValue);
Serial.print
(
","
);
// read the sensor:
sensorValue
=
analogRead
(A1);
// print the results:
Serial.print
(sensorValue);
Serial.print
(
","
);
// read the sensor:
sensorValue
=
digitalRead
(buttonPin);
// print the results:
Serial.println
(sensorValue);
}
}
p5.js
modify the serialEvent() and initiateSerial() functions to this;
function
serialEvent() {
// read a string from the serial port
// until you get carriage return and newline:
var
inString = serial.readStringUntil(
"rn"
);
//check to see that there's actually a string there:
if
(inString) {
if
(inString !==
"hello"
) {
// if you get hello, ignore it
// split the string on the commas:
var
sensors = split(inString,
","
);
if
(sensors.length > 2) {
// if there are three elements
// element 0 is the locH:
locH = map(sensors[0], 0, 1023, 0, width);
// element 1 is the locV:
locV = map(sensors[1], 0, 1023, 0, height);
// element 2 is the button:
circleColor = 255 - sensors[2] * 255;
// send a byte back to prompt for more data:
serial.print('x');
}
}
}
}
function
initiateSerial() {
console.log(
"port open"
);
// send a byte to start the microcontroller sending:
serial.print(
"x"
);
}

It also works :)
I didn’t have any trouble with this lab but I looked up for the checklists just in case..
p5.WebSerial Sketch Checklist
Most p5.WebSerial sketches that you write will have a similar structure to this one. The main difference between them all will be how you read and interpret incoming serial data, and how and when you send and format outgoing serial data. Here’s a checklist of the pieces you’re likely to see in every sketch:
- In the HTML file, include the p5.webserial library
- In the global variables of the sketch,
- make a new instance of the library
- include a port selector button or some way to invoke the serial port chooser dialogue box
- In the setup:
- Make sure WebSerial is supported in this browser
- Include a call to
serial.getPorts()
to check for available ports. - include
serial.on()
listeners for these events:- noport
- portavailable
- data
- close
- requesterror
- include navigator listeners for connect and disconnect
- Define handler functions for all of the events above. Most of these can be simple alerts or console.log messages
- Customize the function that responds to the
data
listener (usually calledserialEvent()
in these examples), as you’ll see below. - Decide when and how you’ll send serial data out, as you’ll see in the other p5.webserial labs.
The last two items of this list are the ones on which you’ll spend most of your time. The rest of the items are things you’re likely to copy from one sketch to another.
comment me here :)https://docs.google.com/spreadsheets/d/1-W06EclvrzTsQrbldnvYTIj56PC2BN_Xc2jTjxwCo6A/edit#gid=0