Week 7: Serial Output from P5.js and Two-Way Communication

Last week I learned to send data from my Arduino to control a sketch in P5.js. This week the focus shifted to P5 output to direct events on my Arduino. I also reinforced my understanding of two-way communication between the microcontroller and my P5 sketch in the browser.

Serial Output from P5.js

Here I've connected an LED to the Digital Pin 5 and through a 220 Ohm resistor to ground. This Arduino sketch looks for data at the serial port and uses it to set the brightness of the LED. The incoming values arrive from my P5 sketch and are dependent on the location on my mouse when it is dragged up and down the height of the canvas. The Y coordinate values of my mouse are mapped to a value range of 0-255, converted to a number, and sent as a byte via serial.write() to the serial port. My Arduino then uses Serial.read to interpret that byte and program the LED with a value, again between 0-255. The Arduino also sends that value back to the P5 sketch which displays on the canvas for reference. Likewise, keys 0-9 have also been mapped to a value range of 0-255 and when pressed, convert to raw bytes to send to the Arduino.


You can also take advantage of the ASCII value of specific letters to program your Arduino serially from P5, and in the next exercise I did just that. This P5 sketch uses the keyPressed() function to write each letter, H and L respectively, to the microcontroller, each as is as a single byte. The Arduino (sketch) looks up the ASCII value of each letter and writes the result to a specific behavior: in this case, H (ASCII value 72) turns the LED on or HIGH, and L (ASCII value 76) turns the LED off or LOW. I noticed that when on the P5 sketch I could press either "H" or "h" and also "L" or "l", but only capital letters worked in the Arduino serial monitor. 


In the last exercise of this lab, the P5 sketch from the first example (with the mouseDragged() function) is rewritten to send data as an ASCII-encoded string, In this case the value of Y along the height of the canvas mapped to 0-255 plus a newline delimiter '\n'. You can program the Arduino to read incoming ASCII strings with the String.parseInt() function until it finds your non-numeric newline character or the program times out in the case of this sketch

Two-Way (Duplex) Serial Communication Using An Arduino and P5.js

In this lab I again practiced sending multiple sensor values to a P5 sketch from Arduino and setting up flow control (or handshaking) to synchronize the communication between devices (see also last week's DOM and Serial Input to P5.js post). 

First, I connected three potentiometers to Analog Pins 0, 1, and 2 on my Arduino (sketch) and printed their values as ASCII strings separated by commas and capped off with a carriage return and newline (a la println()) to my P5 sketch. In P5, I used readStringUntil('\r\n') to read the incoming values until it saw those carriage return and new line inputs, and if everything before those was greater than zero, split the string on the commas, and put the resulting values into an array to map to variables in the sketch to control the position (X and Y coordinates) and the color fill of an ellipse.

My P5 sketch did not work right away. I began troubleshooting by printing the incoming string of values to the P5 console. I could see that data was coming in and changing as I adjusted the knobs on my pots. A bit more investigation revealed some typos in my draw() function, and I also realized that I needed to make the variables locH, locV, and circleColor global as they were called both in the draw() and serialEvent() functions. Success!

Because I used readStringUntil(), I could ask P5 to read until any character I specified in my Arduino sketch. As well, I could change the values' delimiter. So I updated both sketches to try these adjustments. First, I set the final character of my string in Arduino (sketch) to the letter, z, and the values' delimiter to the pound sign, #. Next, I made the corresponding adjustments in my P5 sketch. Everything worked just as before!

(Of note: these two sketches from ITP Resident, Chino, were helpful in solidifying my understanding of serial communication with multiple sensors these past two weeks: Arduino and P5.)

Here are the updated sketches with flow control implemented: Arduino and P5. Oh my goodness, I had a tough time implementing this. Though I noticed values in my Arduino's serial monitor, I could not print them in the P5 console. Re-flashing the Arduino with the sketch would leave a frame of the ellipse on the canvas but then nothing would happen. I copied and pasted the code from the PComp syllabus and started over. I even restarted my computer. Finally, after over an hour of troubleshooting, I realized that my P5 sketch was connecting to my bluetooth port even though this was not specifically named. Shutting down bluetooth on my laptop immediately solved the problem, and the sketch worked as expected. Good to know for the future that this might happen!