{"id":3818,"date":"2015-10-05T08:04:17","date_gmt":"2015-10-05T12:04:17","guid":{"rendered":"https:\/\/itp.nyu.edu\/physcomp\/?page_id=3818"},"modified":"2022-11-06T18:11:38","modified_gmt":"2022-11-06T23:11:38","slug":"two-way-duplex-serial-communication-using-p5js","status":"publish","type":"page","link":"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-serial-communication\/two-way-duplex-serial-communication-using-p5js\/","title":{"rendered":"Lab: Two-Way (Duplex) Serial Communication Using An Arduino and the p5.serialport Library"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Introduction\"><\/span><span id=\"Introduction\">Introduction<\/span><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>In the Introduction to <a href=\"https:\/\/itp.nyu.edu\/physcomp\/lab-intro-to-serial-communications\/\">Asynchronous Serial Communication lab<\/a>, you learned about various methods for managing the communications between computers via asynchronous serial communication. These included formatting your data as ASCII-encoded strings or raw serial bytes and managing the flow of data using handshaking. In the&nbsp;<a href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-serial-communication\/lab-serial-input-to-the-p5-js-ide\/\">P5.js Serial Input Lab<\/a>, you sent data from one sensor to a personal computer. In this lab, you\u2019ll send data from multiple sensors to a program in P5.js. You\u2019ll use the data from the sensors to create a pointing-and-selecting device (i.e. a mouse).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"What_You_Should_Know\"><\/span>What You Should Know<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>To get the most out of this tutorial, you should know <a href=\"https:\/\/itp.nyu.edu\/physcomp\/lessons\/microcontrollers__trashed\/microcontrollers-the-basics\/\" target=\"_blank\" rel=\"noreferrer noopener\">what a microcontroller is <\/a>and <a href=\"https:\/\/itp.nyu.edu\/physcomp\/lessons\/programming__trashed\/programming-terms-and-programming-environments\/\" target=\"_blank\" rel=\"noreferrer noopener\">how to program them<\/a>. You should also understand <a href=\"https:\/\/itp.nyu.edu\/physcomp\/lessons\/serial-communication__trashed\/serial-communication-the-basics\/\" target=\"_blank\" rel=\"noreferrer noopener\">asynchronous serial communication<\/a> between microcontrollers and personal computers. You should also understand the basics of <a href=\"http:\/\/www.p5js.org\/\">P5.js<\/a>. It would also help to go through the following labs first:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/itp.nyu.edu\/physcomp\/lab-intro-to-serial-communications\/\">Lab: Intro to Asynchronous Serial Communication<\/a><\/li><li><a href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-serial-communication\/lab-serial-input-to-the-p5-js-ide\/\">Lab: Serial Input to P5.js<\/a><\/li><li><a href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-serial-communication\/lab-serial-output-from-p5-js\/\">Lab:&nbsp;Serial Output From P5.js<\/a><\/li><\/ul>\n\n\n\n<p>These videos might&nbsp;help in understanding this lab as well:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Video:&nbsp;<a rel=\"noopener noreferrer\" href=\"https:\/\/vimeo.com\/380356863\" target=\"_blank\">Two-way Serial Communication<\/a> (Call-and-Response)<\/li><li>These videos are explained in the Processing programming environment, but the concepts still apply:\n<ul>\n<li>Video: <a rel=\"noopener noreferrer\" href=\"https:\/\/vimeo.com\/380357151\" target=\"_blank\">Reading Serial Strings in Processing<\/a><\/li>\n<li>Video: <a rel=\"noopener noreferrer\" href=\"https:\/\/vimeo.com\/380357361\" target=\"_blank\">Sending and Reading Multiple Serial Values in Processing<\/a><\/li>\n<\/ul>\n<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Things_Youll_Need\"><\/span><span id=\"Things_Youll_Need\">Things You\u2019ll Need<\/span><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>For this lab, you\u2019ll need the hardware below, and you\u2019ll need the same software setup as the&nbsp;<a href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-serial-communication\/lab-serial-input-to-the-p5-js-ide\/\">Serial Input to P5.js<\/a>&nbsp;lab: You\u2019ll create a&nbsp;<a href=\"https:\/\/p5js.0rg\/\">p5.js sketch<\/a>. You\u2019ll also use the&nbsp;<a href=\"https:\/\/github.com\/vanevery\/p5.serialport\">p5.serialport library<\/a>&nbsp;and the&nbsp;<a href=\"https:\/\/github.com\/p5-serial\/p5.serialcontrol\/releases\/tag\/0.1.2\">P5.serialcontrol app<\/a>. You can use the p5.js web editor or your favorite text editor for this (the&nbsp;<a href=\"https:\/\/code.visualstudio.com\/\">Visual Studio Code editor<\/a>&nbsp;or the&nbsp;&nbsp;<a href=\"http:\/\/p5js.org\/download\/\">Atom text editor<\/a>&nbsp;work well).<\/p>\n\n\n\n<p>Figures 1-5 below are the parts you&#8217;ll need for this exercise. Click on any image for a larger view.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft\"><a href=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/pcomp-kit-f2019-arduino-nano-33-iot.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/pcomp-kit-f2019-arduino-nano-33-iot-150x150.jpg\" alt=\"Photo of an Arduino Nano 33 IoT module. The USB connector is at the top of the image, and the physical pins are numbered in a U-shape from top left to bottom left, then from bottom right to top right.\" class=\"wp-image-5921\"\/><\/a><figcaption>Figure 1. Microcontroller. Shown here is an Arduino Nano 33 IoT<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft\"><a href=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/pcomp-kit-f2019-jumper-wires.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/pcomp-kit-f2019-jumper-wires-150x150.jpg\" alt=\"Photo of flexible jumper wires\" class=\"wp-image-5908\"\/><\/a><figcaption>Figure 2. Jumper wires.&nbsp; You can also use pre-cut solid-core jumper wires.<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft\"><a href=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/pcomp-kit-f2019-breadboard.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/pcomp-kit-f2019-breadboard-150x150.jpg\" alt=\"Photo of a solderless breadboard\" class=\"wp-image-5909\"\/><\/a><figcaption>Figure 3. A solderless breadboard<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft\"><a href=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/pcomp-kit-f2019-pushbuttons.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/pcomp-kit-f2019-pushbuttons-150x150.jpg\" alt=\"Photo of four breadboard-mounted pushbuttons\" class=\"wp-image-5918\"\/><\/a><figcaption>Figure 4. A pushbutton<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-thumbnail\"><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/pcomp-kit-f2019-potentiometer-150x150.jpg\" alt=\"Photo of two potentiometers\" class=\"wp-image-5924\"\/><figcaption><em>Figure 5. two potentiometers. You can use any two analog sensors in place of these if you prefer. <\/em><\/figcaption><\/figure><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Connect_the_Sensors\"><\/span><span id=\"Connect_the_sensors\">Connect the Sensors<\/span><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"vspace\"><meta charset=\"utf-8\">For this exercise, you&#8217;re going to need two analog inputs to your microcontroller, and one digital input. It doesn&#8217;t matter what they are, so use something that&#8217;s easy for you to set up. The photos and schematic in this lab show potentiometers and a pushbutton. You don&#8217;t have to use these, though. Any three sensor inputs will do the job. If you&#8217;re looking for options, consider:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-thumbnail\"><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/joystick-150x150.png\" alt=\"Photo of a breadboard-mountable joystick, This component is mounted on a printed circuit board that's about 4cm on each side. The joystick itself is about 6cm tall, controllable by a thumb. There are five pins on one side of the PCB for mounting on the breadboard.\" class=\"wp-image-1917\"\/><figcaption><em>Figure 6. A <a href=\"https:\/\/www.digikey.com\/en\/products\/detail\/512\/1528-2124-ND\/7056915\">joystick<\/a>, which consists of two potentiometers and a pushbutton<\/em><\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-thumbnail\"><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/pcomp-kit-f2019-rotary-encoder-150x150.jpg\" alt=\"Photo of a rotary encoder\" class=\"wp-image-5922\"\/><figcaption><em> Figure 7. <a href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/lab-using-a-rotary-encoder\/\" data-type=\"page\" data-id=\"8683\">Rotary encoders<\/a>, which include a built-in pushbutton<\/em><\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-thumbnail\"><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/nano_IMU-150x150.jpg\" alt=\"Photo of the IMU sensor on teh Nano 33 IoT. It's the small rectangular chip above and to the left of the main processor.\" class=\"wp-image-9006\" srcset=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/nano_IMU-150x150.jpg 150w, https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/nano_IMU-768x770.jpg 768w, https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/nano_IMU-1533x1536.jpg 1533w, https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/nano_IMU-2044x2048.jpg 2044w, https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/nano_IMU-1200x1202.jpg 1200w\" sizes=\"(max-width: 150px) 85vw, 150px\" \/><figcaption><em>Figure 8. The <a href=\"https:\/\/itp.nyu.edu\/physcomp\/lessons\/accelerometers-gyros-and-imus-the-basics\/#Built-in_IMUs\">built-in accelerometer on the Arduino Nano 33 IoT<\/a>, which measures acceleration on three axes<\/em><\/figcaption><\/figure><\/div>\n\n\n\n<hr style=\"width: 100%\">\n\n\n\n<p>As long as you have three sensors that will output changing readings, you can follow this lab. <\/p>\n\n\n\n<p>Connect the two analog sensors to analog pins 0 and 1 like you did in the&nbsp;<a class=\"wikilink\" style=\"color: #37aad1;\" title=\"Analog In with an Arduino\" rel=\"noopener noreferrer\" href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/analog-in-with-an-arduino\/\" target=\"_blank\">analog input to Arduino lab<\/a>. Connect a pushbutton to digital pin 2 like you did in the&nbsp;<a class=\"wikilink\" style=\"color: #37aad1;\" title=\"Digital Input and Output with an Arduino\" rel=\"noopener noreferrer\" href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/digital-input-and-output-with-an-arduino\/\" target=\"_blank\">digital input and output with Arduino lab<\/a>. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"560\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/Arduino_2_pots_button_schem.png\" alt=\"Schematic view of an Arduino attached to two potentiometers and a pushbutton. The potentiometers' center pins are connected to the Arduino's A0 and A1 inputs, respectively.\" class=\"wp-image-9007\"\/><figcaption><em>Figure 9. Schematic view of an Arduino attached to two potentiometers and a pushbutton. The potentiometers&#8217; center pins are connected to the Arduino&#8217;s A0 and A1 inputs, respectively. Their left pins are connected to the voltage bus, and the right pins are connected to the ground bus, respectively. The pushbutton is connected from the Arduino&#8217;s voltage output to pin D2. a 10-kilohm connects the junction of the switch and pin D2 to ground.<\/em><\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1359\" height=\"945\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/Uno_2_pots_button_bb-5.png\" alt=\"Breadboard view of an Arduino Uno attached to two potentiometers and a pushbutton.\" class=\"wp-image-9465\" srcset=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/Uno_2_pots_button_bb-5.png 1359w, https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/Uno_2_pots_button_bb-5-768x534.png 768w, https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/Uno_2_pots_button_bb-5-1200x834.png 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption><em>Figure 10. Breadboard view of an Arduino Uno attached to two potentiometers and a pushbutton. The potentiometers&#8217; center pins are connected to the Arduino&#8217;s A0 and A1 inputs, respectively. Their left pins are connected to the voltage bus, and the right pins are connected to the ground bus, respectively. The pushbutton is connected from the Arduino&#8217;s voltage output to pin D2. a 10-kilohm connects the junction of the switch and pin D2 to ground.<\/em><\/figcaption><\/figure><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"400\" height=\"636\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/Nano_2_pots_button_bb.png\" alt=\"Breadboard view of an Arduino Nano attached to two potentiometers and a pushbutton\" class=\"wp-image-9010\"\/><figcaption><em>Figure 11. Breadboard view of an Arduino Nano attached to two potentiometers and a pushbutton. The potentiometers&#8217; center pins are connected to the Arduino&#8217;s A0 and A1 inputs, respectively. Their left pins are connected to the voltage bus, and the right pins are connected to the ground bus, respectively. The pushbutton is connected from the Arduino&#8217;s voltage output to pin D2. a 10-kilohm connects the junction of the switch and pin D2 to ground.<\/em><\/figcaption><\/figure><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p><em><span style=\"color: #000000;\">(Diagrams made with&nbsp;<\/span><a class=\"urllink\" style=\"color: #37aad1;\" rel=\"nofollow\" href=\"http:\/\/fritzing.org\/\">Fritzing, a circuit design program<\/a>)<\/em><\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Sending_Multiple_Serial_Data_using_Punctuation\"><\/span>Sending Multiple Serial Data using Punctuation<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>You&#8217;re going to program the microcontroller to read the pushbutton and two analog sensors just like you did in the <a href=\"https:\/\/itp.nyu.edu\/physcomp\/lab-intro-to-serial-communications\/\">Intro to Serial Communications Lab<\/a>. When you have to send multiple data items, you need a way to separate them. If you&#8217;re sending them as ASCII-encoded strings, it&#8217;s simple: you can just put non-numeric punctuation bytes between them (like a comma or a space) and a unique termination punctuation at the end (like a newline and\/or carriage return).<\/p>\n\n\n\n<p>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).<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\nconst int buttonPin = 2;      \/\/ digital input\n\nvoid setup() {\n  \/\/ configure the serial connection:\n  Serial.begin(9600);\n  \/\/ configure the digital input:\n  pinMode(buttonPin, INPUT);\n}\n\nvoid loop() {\n  \/\/ read the first analog sensor:\n  int sensorValue = analogRead(A0);\n  \/\/ print the results:\n  Serial.print(sensorValue);\n  Serial.print(\",\");\n\n  \/\/ read the second analog sensor:\n  sensorValue = analogRead(A1);\n  \/\/ print the results:\n  Serial.print(sensorValue);\n  Serial.print(\",\");\n\n  \/\/ read the button:\n  sensorValue = digitalRead(buttonPin);\n  \/\/ print the results:\n  Serial.println(sensorValue);\n}\n<\/pre><\/div>\n\n\n<p>When you run this and output it to the Serial Monitor, you should see something like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">348,363,1<br>344,362,1<br>345,363,1<br>344,375,0<br>365,374,0<br>358,369,0<br>355,369,0<br>352,373,0<br>356,373,0<\/pre>\n\n\n\n<p>Turn the potentiometers (or tweak the analog sensors) and push the button. Now you&#8217;ve got a data format: three sensors, comma-separated, terminated by carriage return and newline. This means that you already have an algorithm for how you&#8217;re going to program P5.js to read the serial input:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Read the incoming serial data into a string until a carriage return and newline appear<\/li><li>split the string into substrings on the commas<\/li><li>convert the substrings into numbers<\/li><li>assign the numbers to variables to change your programNow that you&#8217;ve got a plan, put it into action.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Receive_the_data_in_P5js\"><\/span><span id=\"Receive_the_data_in_Processing\">Receive the data in&nbsp;P5.js<\/span><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Now write a P5.js&nbsp;sketch that reads the data as formatted by the Arduino program above. Download&nbsp;the latest version of the&nbsp;<a href=\"https:\/\/github.com\/vanevery\/p5.serialcontrol\/releases\">P5.serialcontrol<\/a>&nbsp;application if you haven&#8217;t already and save it in your Applications folder. When you run it, it will check serial ports on your machine. You don\u2019t need to do anything with the app, just have it open.<\/p>\n\n\n\n<p>You\u2019ll need to know&nbsp;the name of your serial port to get started. If you\u2019re not sure how to get this, see the&nbsp;<a href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-serial-communication\/lab-serial-input-to-the-p5-js-ide\/\">Serial Input to P5.js<\/a>&nbsp;lab for how to get a list of ports.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_P5js_Sketch\"><\/span>The P5.js Sketch<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The sketch you\u2019re going to write will control the microcontroller\u2019s LED from P5.js. Dragging the mouse up and down the canvas will dim or brighten the LED, and typing 0 through 9 will set the LED\u2019s brightness in increments from off (0) through almost full brightness (9). There\u2019s an alternate sketch that will make changing tones if you prefer that instead of a changing LED. The sketch will also receive serial input from the microcontroller just as in the&nbsp;<a href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-serial-communication\/lab-serial-input-to-the-p5-js-ide\/\">Serial Input to P5.js<\/a>&nbsp;lab, so that you can see that the microcontroller is getting the same values you\u2019re sending.<\/p>\n\n\n\n<p>As you saw in the&nbsp;<a href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-serial-communication\/lab-serial-input-to-the-p5-js-ide\/\">Serial Input to P5.js<\/a>&nbsp;lab, &nbsp;you\u2019ll need to <a href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-serial-communication\/lab-serial-input-to-the-p5-js-ide\/#Program_P5js_to_list_the_available_serial_ports\">copy the p5.seriaport.js lbrary into your sketch\u2019s libraries folder<\/a>. You&#8217;ll need to run p5.serialcontrol, or run the p5.serialserver from the command line&nbsp;as you did in the Serial Input to P5.js&nbsp;lab as well.<\/p>\n\n\n\n<p>Make a P5.js sketch. If you\u2019re using the&nbsp;<a href=\"http:\/\/alpha.editor.p5js.org\/\">p5.js web editor<\/a>, make a new sketch. Click the Sketch Files tab, and then choose the&nbsp;<code>index.html<\/code>&nbsp;file.&nbsp;In the head of the document, look for this line:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;script src=&quot;https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/p5.js\/1.4.0\/p5.js&quot;&gt;&lt;\/script&gt;\n<\/pre><\/div>\n\n\n<p>Right after that line, add this line:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;script language=&quot;javascript&quot; type=&quot;text\/javascript&quot; src=&quot;https:\/\/cdn.jsdelivr.net\/npm\/p5.serialserver@0.0.28\/lib\/p5.serialport.js&quot;&gt;&lt;\/script&gt;\n<\/pre><\/div>\n\n\n<p>The setup of your sketch will initialize the P5.serialport library and define your callback functions for serial events.&nbsp;, as you did in other sketches<\/p>\n\n\n\n<p> Then in the <code>setup()<\/code>, create a canvas, make an instance of the serialport library, and declare your callback functions. <\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\nvar serial;          \/\/ variable to hold an instance of the serialport library\n\nfunction setup() {\n  createCanvas(800, 600);          \/\/ make canvas\n  smooth();                        \/\/ antialias drawing lines\n  serial = new p5.SerialPort();    \/\/ make a new instance of the serialport library\n  serial.on('list', printList);    \/\/ set a callback function for the serialport list event\n  serial.on('connected', serverConnected); \/\/ callback for connecting to the server\n  serial.on('open', portOpen);     \/\/ callback for the port opening\n  serial.on('data', serialEvent);  \/\/ callback for when new data arrives\n  serial.on('error', serialError); \/\/ callback for errors\n  serial.on('close', portClose);   \/\/ callback for the port closing\n\n  serial.list();                   \/\/ list the serial ports\n}\n<\/pre><\/div>\n\n\n<p>This time, you&#8217;ll&nbsp;<a href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-serial-communication\/lab-serial-input-to-the-p5-js-ide\/#Adding_A_Serial_Port_Select_Menu\">add a serialport select menu<\/a>&nbsp;as you did in the&nbsp;<a href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-serial-communication\/lab-serial-input-to-the-p5-js-ide\/\">Serial Input to P5.js<\/a>&nbsp; lab.First, declare a global variable to hold the port menu at the top of your sketch like so:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\nvar portSelector; \/\/ a select menu for the port list\n<\/pre><\/div>\n\n\n<p>Then change the <code>printList<\/code> function like so:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\n\/\/ get the list of ports:\nfunction printList(portList) {\n  \/\/ make a select menu and position it:\n  portSelector = createSelect();\n  portSelector.position(10,10);\n  \n  \/\/ portList is an array of serial port names\n  for (var i = 0; i &lt; portList.length; i++) {\n    \/\/ Display the list the console:\n    \/\/ console.log(i + &quot; &quot; + portList&#x5B;i]);\n    \/\/ add item to the select menu:\n    portSelector.option(portList&#x5B;i]);\n  }\n  \/\/ set a handler for when a port is selected from the menu:\n  portSelector.changed(mySelectEvent);\n}\n<\/pre><\/div>\n\n\n<p>When the select menu&#8217;s value has changed, you can assume a serial port has been selected, so write a handler to open it like so:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\nfunction mySelectEvent() {\n  let item = portSelector.value();\n   \/\/ if there's a port open, close it:\n  if (serial.serialport != null) {\n    serial.close();\n  }\n  \/\/ open the new port:\n  serial.open(item);\n}\n<\/pre><\/div>\n\n\n<p>From now on, when you run this sketch, you&#8217;ll need to select the serial port to open the port. <\/p>\n\n\n\n<p>The rest of the serial event handlers are all the same as you saw in the P5.js Serial Input Lab, except for the <code>serialEvent()<\/code>. Here are all but the <code>serialEvent()<\/code>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nfunction serverConnected() {\n  console.log('connected to server.');\n}\n\nfunction portOpen() {\n  console.log('the serial port opened.')\n}\n\nfunction serialError(err) {\n  console.log('Something went wrong with the serial port. ' + err);\n}\n\nfunction portClose() {\n console.log('The serial port closed.');\n}\n<\/pre><\/div>\n\n\n<p>Program the <code>serialEvent()<\/code> function to read the incoming serial data as a string until it encounters a carriage return and newline (&#8216;\\r\\n&#8217;). Then check to see that the resulting string has a length greater than 0 bytes. If it does, use the <code>split()<\/code> function to split it in to an array of strings. If the resulting array is at least three elements long, you have your three sensor readings. The first reading is the first analog sensor, and can be mapped to the horizontal movement using the locH variable.&nbsp;The second is the second analog sensor and can be mapped to the locV variable. The third is the button. When it&#8217;s 0, set the circleColor variable equal to 255 and when it&#8217;s 1, set the variable&nbsp;to 0. Here&#8217;s how:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nfunction serialEvent() {\n  \/\/ read a string from the serial port\n  \/\/ until you get carriage return and newline:\n  var inString = serial.readStringUntil(&#039;\\r\\n&#039;);\n\n  \/\/check to see that there&#039;s actually a string there:\n  if (inString.length &gt; 0 ) {\n    var sensors = split(inString, &#039;,&#039;);            \/\/ split the string on the commas\n    if (sensors.length &gt; 2) {                      \/\/ if there are three elements\n      locH = map(sensors&#x5B;0], 0, 1023, 0, width);   \/\/ element 0 is the locH\n      locV = map(sensors&#x5B;1], 0, 1023, 0, height); \/\/ element 1 is the locV\n      circleColor = 255 - (sensors&#x5B;2] * 255);      \/\/ element 2 is the button\n    }\n  }\n}\n<\/pre><\/div>\n\n\n<p>Note the mappings of <code>sensor[0]<\/code> and <code>sensor[1]<\/code>. You should use the input mappings for your accelerometer instead of 0 and 1023.&nbsp;If your analog values are greater than the width of the sketch&nbsp;or the height, the circle&nbsp;will be offscreen, which is why you&nbsp;have to map your sensor range to the screen size.<\/p>\n\n\n\n<p>Program the <code>draw()<\/code> function to draw a circle that&#8217;s dependent on three global variables, locH, locV, and circleColor. Add these three globals to the top of the program:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nvar locH = 0;\nvar locV = 0;        \/\/ location of the circle\nvar circleColor = 255; \/\/ color of the circle\n<\/pre><\/div>\n\n\n<p>Finally, here is the draw function:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nfunction draw() {\n  background(0);               \/\/ black background\n  fill(circleColor);           \/\/ fill depends on the button\n  ellipse(locH, locV, 50, 50); \/\/ draw the circle\n}\n<\/pre><\/div>\n\n\n<p>If you run this, you should see the circle&nbsp;moving onscreen whenever you tilt the accelerometer. When you press&nbsp;the pushbutton, the circle&nbsp;will disappear. Okay, it&#8217;s not exactly a &nbsp;mouse, but you are controlling an animation from a device that you built.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Flow_Control_Call_and_Response_Handshaking\"><\/span>Flow Control: Call and Response (Handshaking)<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>You&#8217;ve seen now that by coming up with a serial format (called a <strong>protocol<\/strong>), you can write&nbsp;the algorithm for receiving it even before you see any data. You can send multiple pieces of data this way, as long as you format it consistently.<\/p>\n\n\n\n<p>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 <strong>flow control<\/strong>. The simplest way do to this is using a call-and-response method, where the sending program only sends when it&#8217;s told to do so, and&nbsp;the receiving program has to request new data every time it finishes reading what it&#8217;s got.<\/p>\n\n\n\n<p>You can add handshaking to the code above&nbsp;fairly simply.&nbsp;Modify the Arduino code as follows. First, add a a new block of code in the <code>setup()<\/code> This block&nbsp;sends out a message until it gets a byte of data from the remote computer:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\nvoid setup() {\n  Serial.begin(9600);\n  while (Serial.available() &lt;= 0) {\n    Serial.println(&quot;hello&quot;); \/\/ send a starting message\n    delay(300);              \/\/ wait 1\/3 second\n  }\n}\n<\/pre><\/div>\n\n\n<p>Now, modify the <code>loop()<\/code> by adding an <code>if()<\/code> statement to look for incoming serial data and read it.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\nvoid loop() {\n  if (Serial.available() &gt; 0) {\n    \/\/ read the incoming byte:\n    int inByte = Serial.read();\n    \/\/ read the sensor:\n    sensorValue = analogRead(A0);\n    \/\/ print the results:\n    Serial.print(sensorValue);\n    Serial.print(&quot;,&quot;);\n\n    \/\/ read the sensor:\n    sensorValue = analogRead(A1);\n    \/\/ print the results:\n    Serial.print(sensorValue);\n    Serial.print(&quot;,&quot;);\n\n    \/\/ read the sensor:\n    sensorValue = digitalRead(buttonPin);\n    \/\/ print the results:\n    Serial.println(sensorValue);\n  }\n}\n<\/pre><\/div>\n\n\n<p>The rest of the sketch remains the same. When you run this and open the serial monitor, you&#8217;ll see:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">hello\nhello\nhello\nhello<\/pre>\n\n\n\n<p>Type any character in the output box and click Send. You&#8217;ll get a string of sensor values at the end of your hellos:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">510,497,0<\/pre>\n\n\n\n<p>Type another character and click Send. It doesn&#8217;t matter what character you send, but the loop will always wait for an incoming byte before sending a new set of sensor values. When you write a program to receive this format, it just has to behave the same way you did:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Open the serial port<\/li><li>Wait for a Hello<\/li><li>Send a byte to request data<\/li><li>Begin loop:<\/li><li>Wait for one set of data<\/li><li>Send a byte to request new data<\/li><li>end loop<\/li><\/ul>\n\n\n\n<p>Next, modify the P5.js&nbsp;sketch. &nbsp;Most of the changes are in the <code>serialEvent()<\/code> function. The initial &#8220;hello&#8221; messages will trigger this function, so when you get a &#8220;hello&#8221; or any other string, you need&nbsp;to send a byte back so that the Arduino has a byte available to read. Here&#8217;s the new <tt>serialEvent()<\/tt>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; highlight: [7,14,15]; title: ; notranslate\" title=\"\">\nfunction serialEvent() {\n  \/\/ read a string from the serial port\n  \/\/ until you get carriage return and newline:\n  var inString = serial.readStringUntil(&#039;\\r\\n&#039;);\n  \/\/check to see that there&#039;s actually a string there:\n  if (inString.length &gt; 0) {\n    if (inString !== &#039;hello&#039;) { \/\/ if you get hello, ignore it\n      var sensors = split(inString, &#039;,&#039;); \/\/ split the string on the commas\n      if (sensors.length &gt; 2) { \/\/ if there are three elements\n        locH = map(sensors&#x5B;0], 0, 1023, 0, width); \/\/ element 0 is the locH\n        locV = map(sensors&#x5B;1], 0, 1023, 0, height); \/\/ element 1 is the locV\n        circleColor = 255 - (sensors&#x5B;2] * 255); \/\/ element 2 is the button\n      }\n    }\n    serial.write(&#039;x&#039;); \/\/ send a byte requesting more serial data\n  }\n}\n<\/pre><\/div>\n\n\n<p>You also need to add a line to the <code>openPort()<\/code> function like so:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; highlight: [3,4]; title: ; notranslate\" title=\"\">\nfunction portOpen() {\n  console.log('the serial port opened.')\n  \/\/ send a byte to prompt the microcontroller to send:\n  serial.write('x');\n}\n<\/pre><\/div>\n\n\n<p>The reason for this is that if your Arduino has already broken out of the loop (let&#8217;s say you opened the Serial monitor to check), then it is waiting for a byte from p5.js to send the next block of code. By sending a byte when you know the port has just been opened in p5.js, you force the Arduino to send you new data. <\/p>\n\n\n\n<p>That&#8217;s it. Your sketch should still run just as it did before, though the serial communication is managed better now, because Arduino&#8217;s only sending when P5.js is ready to receive.<\/p>\n\n\n\n<p>The full code for all the examples in this lab can be found in <a href=\"https:\/\/github.com\/ITPNYU\/physcomp\/tree\/master\/Labs\/P5SerialLabs\/P5SerialDuplex\">this gitHub repository<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Advantages_of_Raw_Binary_vs_ASCII\"><\/span><span id=\"Advantages_of_Raw_Binary_vs_ASCII\">Advantages of Raw Binary vs. ASCII<\/span><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>All the examples shown here sent the sensor values as ASCII-encoded strings. As mentioned above, that means you sent three bytes to send a three-digit value. If that same value was less than 255, you could send it in one raw binary byte. So ASCII is definitely less efficient. However, it\u2019s more readable for debugging purposes, and if the receiving program is well-suited to convert strings to numbers, then ASCII is a good way to go. If the receiver\u2019s not so good at converting strings to numbers (for example, it\u2019s more challenging to read a multiple byte string in Arduino than in Processing) then you may want to send your data as binary values.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Advantages_of_Punctuation_or_Call-and-Response\"><\/span><span id=\"Advantages_of_Punctuation_or_Call-and-Response\">Advantages of Punctuation or Call-and-Response<\/span><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The punctuation method for sending multiple serial values may seem simpler, but it has its limitations. You can\u2019t easily use it to send binary values, because you need to have a byte with a unique value for the punctuation. In the example above, you\u2019re using the value 10 (ASCII newline) as punctuation, so if you were sending your sensor values as raw bytes, you\u2019d be in trouble when the sensor\u2019s value is 10. The receiver would interpret the 10 as punctuation, not as a sensor value. In contrast, call-and-response can be used whether you\u2019re sending data as raw binary values or as ASCII-encoded values.<\/p>\n\n\n\n<p>Sometimes the receiver reads serial data slower than the sender sends it. For example, if you have a program that does a lot of graphic work, it may only read serial data every few milliseconds. The serial buffer will get full in that case, you\u2019ll notice a lag in response time. This is when it\u2019s good to switch to a call-and-response method.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Build_an_Application_of_Your_Own\"><\/span><span id=\"Get_creative\">Build an Application of Your Own<\/span><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>You just duplicated the basic functionality of a mouse; that is, a device with two analog sensors that affect X and Y, and a digital sensor (mouse button). What applications can you think of that could use a better physical interface for a mouse? A video editor that scrubs forward and back when you tilt a wand? An action game that reacts to how hard you hit a punching bag? An instructional presentation that speeds up if you shift in your chair too much? A music program driven by a custom musical instrument that you design?<\/p>\n\n\n\n<p>Create a prototype in Arduino and P5.js, Node.js, Processing, or whatever programming environment you choose. Come up with a physical interface that makes it clear what actions map to what movements and actions. Figure out which actions can and should be possible at the same time. Present a working software and hardware model of your idea.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial you&#8217;ll learn how to send data using asynchronous serial between an Arduino and p5.js in both directions.<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":1979,"menu_order":212,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"categories":[42,11,15,31,79,26,9],"tags":[],"class_list":["post-3818","page","type-page","status-publish","hentry","category-asynchronous-serial","category-code","category-lab","category-p5-js","category-p5-serialport","category-programming","category-serial-communication"],"_links":{"self":[{"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/pages\/3818"}],"collection":[{"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/comments?post=3818"}],"version-history":[{"count":75,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/pages\/3818\/revisions"}],"predecessor-version":[{"id":10729,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/pages\/3818\/revisions\/10729"}],"up":[{"embeddable":true,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/pages\/1979"}],"wp:attachment":[{"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/media?parent=3818"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/categories?post=3818"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/tags?post=3818"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}