{"id":1737,"date":"2014-08-23T10:40:04","date_gmt":"2014-08-23T14:40:04","guid":{"rendered":"https:\/\/itp.nyu.edu\/physicalcomputing\/?page_id=1737"},"modified":"2022-11-06T18:00:46","modified_gmt":"2022-11-06T23:00:46","slug":"interpreting-serial-data","status":"publish","type":"page","link":"https:\/\/itp.nyu.edu\/physcomp\/lessons\/interpreting-serial-data\/","title":{"rendered":"Interpreting Serial Data"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Introduction\"><\/span>Introduction<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Serial data is passed byte by byte from one device to another, but it\u2019s up to you to decide how each device (computer or microcontroller) should interpret those bytes, when the beginning of a message is, when the end is, and what to do with the bytes in between. &nbsp;<strong>Serial communication protocols<\/strong> define the structure of communication between devices. These notes explain how serial data is interpreted by computers.<\/p>\n\n\n\n<p>To get the most out of these notes, you should know&nbsp;<a title=\"Microcontrollers: The Basics\" rel=\"noopener noreferrer\" href=\"https:\/\/itp.nyu.edu\/physcomp\/lessons\/microcontrollers-the-basics\/\" target=\"_blank\">what a microcontroller is&nbsp;<\/a>and have an understanding of the&nbsp;<a title=\"Lab: Digital Input and Output with an Arduino\" rel=\"noopener noreferrer\" href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-arduino-digital-and-analog\/digital-input-and-output-with-an-arduino\/\" target=\"_blank\">basics of microcontroller programming<\/a>. You should also understand the <a title=\"Serial Communication: The Basics\" rel=\"noopener noreferrer\" href=\"https:\/\/itp.nyu.edu\/physcomp\/lessons\/serial-communication-the-basics\/\" target=\"_blank\">basics of serial communication<\/a>. You should have some understanding of programming a personal computer as well, ideally in a language that can access the serial ports of the computer, like <a href=\"https:\/\/p5js.org\/\">p5.js<\/a>, the&nbsp;<a rel=\"noopener noreferrer\" href=\"http:\/\/www.processing.org\/\" target=\"_blank\">Processing programming environment<\/a>, the <a rel=\"noopener noreferrer\" href=\"http:\/\/www.nodejs.org\/\" target=\"_blank\">node.js programming environment<\/a>, Python, or Java.<\/p>\n\n\n\n<p>This is a useful page to return to when you have a specific advanced serial communication problem to solve. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"ASCII_and_Binary\"><\/span>ASCII and Binary<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p><a rel=\"noopener noreferrer\" href=\"https:\/\/vimeo.com\/380355716\" target=\"_blank\">Related video: ASCII Bytes Explained<\/a><\/p>\n\n\n\n<p>Imagine that you&#8217;re sending the value of one sensor from a microcontroller to a personal computer. If the sensor&#8217;s value&nbsp;is always less than 255, you know it can fit in a single byte. This kind of message is easy. Just send the value&nbsp;over and over, and the receiver&nbsp;can read the latest byte to have your whole message. In Arduino, you can do this using the <a href=\"https:\/\/www.arduino.cc\/en\/Serial\/Write\"><tt>Serial.write()<\/tt> command<\/a>, as shown in the Arduino sketch below:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Binary_Serial_Arduino_Program\"><\/span>Binary Serial Arduino Program<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\nvoid setup() {\n  Serial.begin(9600);\n}\n\nvoid loop() {\n  \/\/ read the sensor:\n  int sensorValue = analogRead(A0);\n  \/\/ divide by 4 to reduce the range to 0-255:\n  sensorValue = sensorValue \/ 4;\n  \/\/ send it:\n  Serial.write(sensorValue);\n}\n<\/pre><\/div>\n\n\n<p>Imagine a typical&nbsp;stream of bytes sent by the&nbsp;program above:<\/p>\n\n\n\n<p><code>23 23 23 23 24 24 25 25 26 28 27 27 27<\/code><\/p>\n\n\n\n<p>Every value you send&nbsp;can range from 0 to 255, the full range that can fit in a byte. &nbsp;A protocol like this is often called a <strong>binary protocol<\/strong>, because there&#8217;s no other meaning to each byte&#8217;s value other than the value of the number itself.<\/p>\n\n\n\n<p>Now imagine you want to send two sensor readings. &nbsp;You might think &#8220;No problem; just add another <a href=\"https:\/\/www.arduino.cc\/reference\/en\/language\/functions\/analog-io\/analogread\/\" target=\"_blank\" rel=\"noreferrer noopener\">analogRead() command<\/a> and another <a rel=\"noopener noreferrer\" href=\"https:\/\/www.arduino.cc\/en\/Serial\/Write\" target=\"_blank\">Serial.write() command<\/a>.&#8221; But the resulting stream of data would look the same. Each byte would range from 0 to 255, and you&#8217;d have no way to know which byte represents which sensor. You need some punctuation bytes.<\/p>\n\n\n\n<p>If you\u2019re sending more than one value&nbsp;(and you usually are),&nbsp;then the receiving computer has to know when the message starts and when it ends, and it needs to know how to put the bytes together into a message.<\/p>\n\n\n\n<p>Computers use numbers to represent alphanumeric characters (letters and numbers and punctuation) in bytes. The first&nbsp;standard code for doing this was called the <strong>ASCII code<\/strong> which&nbsp;stands for <em>American Standard Code for Information Interchange.<\/em>&nbsp;ASCII assigns each number or letter a specific byte value from 0 to 127. &nbsp;For example, capital A is ASCII value 65. Capital B is 66. A space is ASCII value 32. The numeral 0 is ASCII 48. ASCII includes only the characters for the English alphabet, though, so a newer protocol, the <a rel=\"noopener noreferrer\" href=\"http:\/\/unicode-table.com\/en\/\" target=\"_blank\">Unicode protocol<\/a>, includes the ASCII character set and includes codes for other alphabets as well.&nbsp;<a href=\"http:\/\/www.utf-8.com\/\">The simplest&nbsp;subset&nbsp;of Unicode,&nbsp;UTF-8<\/a>, is compatible with ASCII.<\/p>\n\n\n\n<p>The <a rel=\"noopener noreferrer\" href=\"http:\/\/www.asciitable.com\/\" target=\"_blank\">ASCII table<\/a> and Unicode set can be found in many computer manuals\u2019 indexes, and all over the place online.&nbsp;These codes are used for number-to-character translation in every computer operating system and programming language.<\/p>\n\n\n\n<p>Because ASCII and Unicode assign each alphanumeric character a unique&nbsp;value, including punctuation symbols, you can now differentiate the values in your serial stream by ASCII-encoding them. &nbsp;Change the <code>Serial.write()<\/code> in the program above to a<a rel=\"noopener noreferrer\" href=\"https:\/\/www.arduino.cc\/en\/Serial\/Print\" target=\"_blank\"> Serial.print() command<\/a>, and add one more line:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"ASCII-encoded_Serial_Arduino_Program\"><\/span>ASCII-encoded Serial Arduino Program<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\nvoid setup() {\n  Serial.begin(9600);\n}\n\nvoid loop() {\n  \/\/ read the sensor:\n  int sensorValue = analogRead(A0);\n  \/\/ divide by 4 to reduce the range to 0-255:\n  sensorValue = sensorValue \/ 4;\n  \/\/ send it:\n  Serial.print(sensorValue);\n  Serial.print(\",\");\n}\n<\/pre><\/div>\n\n\n<p>Now you&#8217;ve got a string of bytes representing numeric characters, AND a byte representing a comma. &nbsp;What would the values of the bytes be?<\/p>\n\n\n\n<p><code>50 51 44 50 51 44&nbsp;50 51 44&nbsp;50 51 44&nbsp;50 52 44&nbsp;50 52 44&nbsp;50 53 44 50 53 44 50 54 44&nbsp;50 56 44&nbsp;50 55 44&nbsp;50 55 44&nbsp;50 55 44<\/code><\/p>\n\n\n\n<p>Why is it so much longer, and what are all those 44s doing in there so regularly? &nbsp;If you look at the ASCII table, you&#8217;ll see why. The sensor values are ASCII-encoded now. &nbsp;That means that the value 23 is represented by the character &#8220;2&#8221; followed by the character &#8220;3&#8221;. In ASCII, &#8220;2&#8221; has the value 50 and &#8220;3&#8221; has the value 51. And &#8220;,&#8221; has the value 44. &nbsp;So the numbers above, read as ASCII, translate to:<\/p>\n\n\n\n<p><code>\"23,23,23,23,24,24,25,25,26,28,27,27,27\"<\/code><\/p>\n\n\n\n<p>It takes more bytes to send data this way, but you have a more human-readable protocol, because most receiving programs will default to displaying byte values using the ASCII or unicode characters assigned to them.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Serial_Terminal_Programs\"><\/span>Serial Terminal Programs<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p><a rel=\"noopener noreferrer\" href=\"https:\/\/vimeo.com\/380356878\" target=\"_blank\">Related video: Serial 4 &#8211; Devices and Bytes<\/a><\/p>\n\n\n\n<p>Most serial terminal programs assume that when you&#8217;re receiving serial data, it should be interpreted as ASCII characters, This is why you&#8217;ll see random characters when you open the Serial Monitor in Arduino after uploading the binary serial program above: the Arduino&#8217;s using a binary protocol, but the Serial Monitor thinks it&#8217;s an ASCII protocol.<\/p>\n\n\n\n<p>The freeware program <a rel=\"noopener noreferrer\" href=\"http:\/\/freeware.the-meiers.org\/\" target=\"_blank\">CoolTerm<\/a> is a useful Serial Terminal application, because it can show you both ASCII and raw binary values. Download it, then open it. Click the Options icon, then choose your serial port from the Serial Port menu:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/coolTerm_config.png\"><img loading=\"lazy\" decoding=\"async\" width=\"716\" height=\"588\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/coolTerm_config.png\" alt=\"Screenshot of the CoolTerm options menu, showing the port name that's the same as your Arduino, and a rate of 9600 bps\" class=\"wp-image-1848\" srcset=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/coolTerm_config.png 716w, https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/coolTerm_config-300x246.png 300w\" sizes=\"(max-width: 716px) 85vw, 716px\" \/><\/a><figcaption>Figure 1. CoolTerm options menu<\/figcaption><\/figure><\/div>\n\n\n\n<p>Click OK, then click Connect (Figure 1). You should see the same random characters you were seeing in the Arduino IDE&#8217;s Serial Monitor as shown in Figure 2. (make sure you have the Serial Monitor closed before you connect in CoolTerm because&nbsp;<span style=\"font-weight: bold;\">Serial ports&nbsp;can only be controlled by one program at a time)<\/span>. But if you click on the View Hex icon, you&#8217;ll see a very different view:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/coolTerm_hex.png\"><img loading=\"lazy\" decoding=\"async\" width=\"802\" height=\"672\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/coolTerm_hex.png\" alt=\"CoolTerm &quot;view hex&quot; view\" class=\"wp-image-1847\" srcset=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/coolTerm_hex.png 802w, https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/coolTerm_hex-300x251.png 300w\" sizes=\"(max-width: 802px) 85vw, 802px\" \/><\/a><figcaption>Figure 2. The CoolTerm serial terminal application showing the hexadecimal view.<\/figcaption><\/figure><\/div>\n\n\n\n<p>Now you&#8217;re looking at the ASCII characters for each byte in the right hand column, and the raw binary values in the center column (in hexadecimal notation) as shown in Figure 3. This is really handy when you&#8217;re trying to interpret a binary protocol.<\/p>\n\n\n\n<p>Click the Disconnect icon in CoolTerm &nbsp;(because&nbsp;&nbsp;<span style=\"font-weight: bold;\">Serial ports&nbsp;can only be controlled by one program at a time<\/span>) and upload the ASCII-encoded Serial Arduino program above. Once the program&#8217;s uploaded, connect in CoolTerm again and look at how the hex view has changed:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/coolTerm_hex_view_2.png\"><img loading=\"lazy\" decoding=\"async\" width=\"802\" height=\"672\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/coolTerm_hex_view_2.png\" alt=\"The CoolTerm serial terminal application showing the hexadecimal view. The screen is filled with hexadecimal values in the center, along with the ASCII characters corresponding to those values running down the side. This time you see the numeric values of the ASCIII characters.\" class=\"wp-image-1849\" srcset=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/coolTerm_hex_view_2.png 802w, https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/coolTerm_hex_view_2-300x251.png 300w\" sizes=\"(max-width: 802px) 85vw, 802px\" \/><\/a><figcaption>Figure 3. The CoolTerm serial terminal application showing the hexadecimal view. This time you see the numeric values of the ASCIII characters.<\/figcaption><\/figure><\/div>\n\n\n\n<p>With this version of the program, the ASCII view is more readable. In the hex view, you can tell the commas from the regular data, because every third byte is 0x2C, or 44 in decimal, or &#8220;,&#8221; in ASCII.<\/p>\n\n\n\n<p><a rel=\"noopener noreferrer\" href=\"https:\/\/vimeo.com\/380357151\" target=\"_blank\">Related video: Serial 7 &#8211; Reading Strings<\/a><\/p>\n\n\n\n<p>Make the following&nbsp;final improvement to the program above:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"ASCII-Encoded_Serial_Arduino_Sketch_with_Line_Break\"><\/span>ASCII-Encoded Serial Arduino Sketch with Line Break<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\nvoid setup() {\n  Serial.begin(9600);\n}\n\nvoid loop() {\n  \/\/ read the sensor:\n  int sensorValue = analogRead(A0);\n  \/\/ divide by 4 to reduce the range to 0-255:\n  sensorValue = sensorValue \/ 4;\n  \/\/ send it:\n  Serial.print(sensorValue);\n  Serial.print(\",\");\n\n  \/\/ read another sensor:\n  int sensorValue2 = analogRead(A1);\n  \/\/ divide by 4 to reduce the range to 0-255:\n  sensorValue2 = sensorValue2 \/ 4;\n  \/\/ send it:\n  Serial.println(sensorValue2);\n}\n<\/pre><\/div>\n\n\n<p>When you view the output of this, you&#8217;ll see you get a string of two numbers, with a linefeed after each string. In hex view, these will be represented as 0x0A (linefeed) and 0x0D (carriage return). This is a simple multi-value protocol. You&#8217;ve got a comma separating the values, and a linefeed and carriage return separating each set of values. \u00a0This protocol is both easy to read, and easy for most personal computer programming environments to interpret. For more on that, see the <a rel=\"noreferrer noopener\" href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-serial-communication\/lab-two-way-duplex-webserial-communication\/\" target=\"_blank\"><meta charset=\"utf-8\"><a href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-serial-communication\/lab-two-way-duplex-webserial-communication\/\">Serial Duplex Lab using P5.js and p5.webserial<\/a><\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Managing_the_Serial_Buffer\"><\/span>Managing the Serial Buffer<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Before you read this section, try\u00a0the <a rel=\"noreferrer noopener\" href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-serial-communication\/lab-two-way-duplex-webserial-communication\/\" target=\"_blank\"><meta charset=\"utf-8\"><a href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-serial-communication\/lab-two-way-duplex-webserial-communication\/\">Serial Duplex Lab using P5.js and p5.webserial<\/a><\/a>. This section will make more sense when you&#8217;ve seen the programs in that lab in operation.<\/p>\n\n\n\n<p>The reason this form of&nbsp;&nbsp;serial communication is called&nbsp;&nbsp;&#8220;asynchronous&#8221; is that the&nbsp;data between the two devices involved is not synchronized. The sender can send when the receiver is not listening, and vice versa. Both sides typically maintain a serial buffer, which is a place in memory to store incoming serial data before it is used, as mentioned in the <a rel=\"noreferrer noopener\" href=\"https:\/\/itp.nyu.edu\/physcomp\/lessons\/serial-communication-the-basics\/\" target=\"_blank\">serial basics notes<\/a>.&nbsp;On computers with an operating system, this serial buffer is maintained even when your program isn&#8217;t running. So when you stop your program and re-start it, there may be data in the buffer from a previous run of the program. This can cause errors. Most programming  environments automatically flush this buffer every time you restart the program, but if the one you are using does not, then look for a function that flushes the buffer. It&#8217;s often called <code>flush()<\/code> and it&#8217;s good to run it right after you open the serial port. In Processing and p5.webserial it&#8217;s called <code>clear()<\/code>. <\/p>\n\n\n\n<p>In Processing:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \">\n\/\/ in your setup() after you create a new serial object called myPort:\n  myPort.clear();\n<\/div>\n\n\n<p>In p5.js with p5.webserial:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nfunction openPort() {\n  \/\/ wait for the serial.open promise to return,\n  \/\/ then call the initiateSerial function\n  serial.open().then(initiateSerial);\n\n  \/\/ once the port opens, let the user know:\n  function initiateSerial() {\n    serial.clear();\n  }\n}\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Make_Sure_Theres_Any_Data_To_Read\"><\/span>Make Sure There&#8217;s Any Data To Read<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The first thing you can do wrong is to assume there&#8217;s data there to read when there isn&#8217;t.&nbsp;Imagine the following situation:<\/p>\n\n\n\n<p>Your microcontroller is continually sending a string of three sensors values to a program on your personal computer, ASCII-encoded, comma-separated, and terminated by a newline, like so:<\/p>\n\n\n\n<p><code>234,23,142\\n<\/code><\/p>\n\n\n\n<p>The controller is not waiting for a response from your desktop program, it&#8217;s just continually sending as fast as it can. The desktop program reading this data is waiting until it sees a newline character, then reading the whole buffer. Then it splits the incoming string into an array and converts the values to integers. You want to read only when a newline character comes in. <\/p>\n\n\n\n<p>In p5.js using the p5.webserial library it might look like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nfunction serialEvent(){\n  let inputString = serial.readStringUntil(\"\\r\\n\");\n  \/\/ split the string into an array:\n  let sensorReadings = split(inputString, \",\");\n}\n<\/pre><\/div>\n\n\n<p>In Processing, it might look like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \">\n\/\/ in the setup(), configure the serial object to generate serial events\n\/\/ only when a newline arrives, like so:\nmyPort.bufferUntil(&#8216;\\n&#8217;);\n\n\/\/ then your serialEvent function looks like this:\nvoid serialEvent(Serial myPort){\n  String inputString = myPort.readString();\n  \/\/ split the string into an array:\n  String[] sensorReadings = split(inputString, &#8220;,&#8221;);\n}\n<\/div>\n\n\n<p>The receiving program may not be reading as frequently as the microcontroller is sending, and the personal computer&#8217;s serial buffer contains the unread bytes.&nbsp;You stop the desktop program, and there&#8217;s still a byte in the buffer, like this:<\/p>\n\n\n\n<p><code>\\n<\/code><\/p>\n\n\n\n<p>The next time you start your program, there&#8217;s a newline in the buffer even if the Arduino&#8217;s not running, so a serial data event is generated and your <code>serialEvent()<\/code> function is called. But there&#8217;s no string preceding the newline character, so when you try to <a rel=\"noopener noreferrer\" href=\"https:\/\/processing.org\/reference\/split_.html\" target=\"_blank\">split<\/a> the string into an array, you get an error . &nbsp;The serial communication between the devices was working properly, but because it&#8217;s asynchronous, it&#8217;s your job to check that the data in the buffer is what you think it is. That&#8217;s your job as programmer. You might address this problem by checking that there&#8217;s a valid string to read first:<\/p>\n\n\n\n<p>in p5.js with p5.webserial:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n let inputString = myPort.readStringUntil(\"\\r\\n\");\n  if (inputString != null) {\n    \/\/ when you know you've got a good string, take action:\n    \/\/ split the string into an array:\n    let sensorReadings = split(inputString, \",\");\n  }\n<\/pre><\/div>\n\n\n<p>in Processing:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \">\n String inputString = myPort.readString();\n  if (inputString != null) {\n    \/\/ when you know you&#8217;ve got a good string, take action on it:\n    \/\/ split the string into an array:\n    String[] sensorReadings = split(inputString, &#8220;,&#8221;);\n  }\n<\/div>\n\n\n<p>Similar problems can happen in all serial environments.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Clear_Any_Old_Data_Before_Reading\"><\/span>Clear Any Old Data Before Reading<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Although this solution works if you&#8217;re reading the serial buffer as a string, it doesn&#8217;t solve every problem. Another way to avoid this particular problem&nbsp;is to make sure that you&#8217;ve cleared out the serial buffer at the beginning of your program before you start reading new data. Once you&#8217;ve configured your serial object and opened the port, clear the buffer <meta charset=\"utf-8\">by calling serial.clear().<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Make_Sure_All_The_Data_Has_Been_Received\"><\/span>Make Sure&nbsp;All The Data Has Been Received<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>You can still get errors even if you&#8217;ve cleared the buffer and made sure there&#8217;s data to read if the data there to read doesn&#8217;t match your expectations. In the example above, your data sentence includes three ASCII-encoded numbers and a newline. &nbsp;But what if the microcontroller doesn&#8217;t send that? &nbsp;Maybe there&#8217;s an error in its program, or maybe there&#8217;s still data in the serial buffer (because you didn&#8217;t clear the buffer). &nbsp;You should check to make sure that everything you expect is present before you operate on it. For example, imagine you&#8217;re splitting the input data into an array of three strings, then copying those strings into global <a rel=\"noopener noreferrer\" href=\"https:\/\/itp.nyu.edu\/physcomp\/lessons\/programming\/variables\/\" target=\"_blank\">variables<\/a> like so:<\/p>\n\n\n\n<p>in Processing:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \">\n\/\/ global variables:\nint xPosition, yPosition, zPositon;\n\n\/\/ then your serialEvent function looks like this:\nvoid serialEvent(Serial myPort){\n  String inputString = myPort.readString();\n  \/\/ split the string into an array:\n  String[] sensorReadings = split(inputString, &#8220;,&#8221;);\n  \/\/ copy the first element into xPosition:\n  xPosition = int(sensorReadings[0]); \n  \/\/ copy the second element  into yPosition:\n  yPosition = int(sensorReadings[1]); \n  \/\/ copy the third element into zPosition: \n  zPosition = int(sensorReadings[2]);  \n}\n<\/div>\n\n\n<p>In p5.js with p5.webserial:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n\/\/ global variables:\nlet xPosition, yPosition, zPositon;\n\n\/\/ then your serialEvent function looks like this:\nfunction serialEvent(){\n  let inputString = serial.readStringUntil(\"\\r\\n\");\n  \/\/ split the string into an array:\n  let sensorReadings = split(inputString, \",\");\n  \/\/ copy the first element into xPosition:\n  xPosition = Number(sensorReadings&#x5B;0]);\n  \/\/ copy the second element  into yPosition:  \n  yPosition = Number(sensorReadings&#x5B;1]); \n  \/\/ copy the third element into zPosition: \n  zPosition = Number(sensorReadings&#x5B;2]);  \n}\n<\/pre><\/div>\n\n\n<p>This works great until you don&#8217;t have three elements in the array. If there wasn&#8217;t a full sentence of data, the array might have only one or two elements, and your error is back. To solve this, make sure the length of the array is as long as the number of elements you&#8217;re trying to read from it like so:<\/p>\n\n\n\n<p>in Processing:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \">\n\/\/ global variables:\nint xPosition, yPosition, zPositon;\n\n\/\/ then your serialEvent function looks like this:\nvoid serialEvent(Serial myPort){\n  String inputString = myPort.readString();\n  \/\/ split the string into an array:\n  String[] sensorReadings = split(inputString, &#8220;,&#8221;);\n  if (sensorReadings.length > 2) {  \n    \/\/ copy the first element into xPosition:\n    xPosition = int(sensorReadings[0]);  \n    \/\/ copy the second element  into yPosition:\n    yPosition = int(sensorReadings[1]);  \n    \/\/ copy the third element into zPosition:\n    zPosition = int(sensorReadings[2]);  \n  }\n}\n<\/div>\n\n\n<p>In p5.js with p5.webserial:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n\/\/ global variables:\nlet xPosition, yPosition, zPositon;\n\n\/\/ then your serialEvent function looks like this:\nfunction serialEvent(){\n  let inputString = serial.readStringUntil(&quot;\\r\\n&quot;);\n  \/\/ split the string into an array:\n  let sensorReadings = split(inputString, &quot;,&quot;);\n  if (sensorReadings.length &gt; 2) {  \n    \/\/ copy the first element into xPosition:\n    xPosition = Number(sensorReadings&#x5B;0]);\n    \/\/ copy the second element  into yPosition:  \n    yPosition = Number(sensorReadings&#x5B;1]); \n    \/\/ copy the third element into zPosition: \n    zPosition = Number(sensorReadings&#x5B;2]);\n  }  \n}\n<\/pre><\/div>\n\n\n<p>If all of the data isn&#8217;t there for any reason, this if statement will prevent an error by skipping the part where you look for data that&#8217;s not there. &nbsp;When you combine it with the check for a null string above, and the clearing of the serial buffer, you make your serial reading much more stable.&nbsp; The final result might look like this:<\/p>\n\n\n\n<p>in Processing:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \">\n\/\/ global variables:\nint xPosition, yPosition, zPositon;\n\n\/\/ then your serialEvent function looks like this:\nvoid serialEvent(Serial myPort){\n  String inputString = myPort.readString();\n  if (!inputString) return;\n  \/\/ split the string into an array:\n  String[] sensorReadings = split(inputString, &#8220;,&#8221;);\n  if (sensorReadings.length > 2) {  \n    \/\/ copy the first element into xPosition:\n    xPosition = int(sensorReadings[0]);  \n    \/\/ copy the second element  into yPosition:\n    yPosition = int(sensorReadings[1]);  \n    \/\/ copy the third element into zPosition:\n    zPosition = int(sensorReadings[2]);  \n  }\n}\n<\/div>\n\n\n<p>In p5.js with p5.webserial:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n\/\/ global variables:\nlet xPosition, yPosition, zPositon;\n\n\/\/ then your serialEvent function looks like this:\nfunction serialEvent(){\n  let inputString = serial.readStringUntil(&quot;\\r\\n&quot;);\n  if (!inputString) return;\n  \/\/ split the string into an array:\n  let sensorReadings = split(inputString, &quot;,&quot;);\n  if (sensorReadings.length &gt; 2) {  \n    \/\/ copy the first element into xPosition:\n    xPosition = Number(sensorReadings&#x5B;0]);\n    \/\/ copy the second element  into yPosition:  \n    yPosition = Number(sensorReadings&#x5B;1]); \n    \/\/ copy the third element into zPosition: \n    zPosition = Number(sensorReadings&#x5B;2]);\n  }  \n}\n<\/pre><\/div>\n\n\n<p>When combined with a handshaking methodology as seen in the <a href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-serial-communication\/lab-two-way-duplex-webserial-communication\/\">Serial Duplex Lab using P5.js and p5.webserial<\/a>, you also ensure that the serial buffer is only filled when you&#8217;re ready for new data. All of these practices are good serial communication practices and will make your projects more stable.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Parsing_Text_in_Arduino\"><\/span>Parsing Text in Arduino<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>There are some tools in the Serial library of Arduino that make it simpler to parse text strings. For example if you know you are getting a string of numbers separated by commas, you can use <code>Serial.parseInt()<\/code> like so:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\nvoid setup() {\n  \/\/ initialize serial\n  Serial.begin(9600);\n}\n\nvoid loop() {\n  if (Serial.available()) {\n    int x = Serial.parseInt();\n    int y = Serial.parseInt();\n    int z = Serial.parseInt();\n    Serial.print(\"x = \");\n    Serial.print(x);\n    Serial.print(\", y = \");\n    Serial.print(y);\n    Serial.print(\", z = \");\n    Serial.println(z);\n  }\n}\n<\/pre><\/div>\n\n\n<p>Try sending comma-separated strings of three numbers to this from the Serial Monitor. You should get an output like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">x = 34, y = 45, z = 56<\/pre>\n\n\n\n<p>Sometimes you will get 0 values if a non-numeric character arrives (like a newline or carriage return). You can catch these by checking for the right number of bytes. For example, <code>34, 56, 78<\/code> followed by carriage return and newline is 10 bytes. So if you know you can expect at least 10 bytes, you could use <code>if (Serial.available() &gt; 10)<\/code>. There are a number of other useful finding and parsing functions in the Serial library, including:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Serial.find()<\/li><li>Serial.findUntil()<\/li><li>Serial.parseInt()<\/li><li>Serial.parseFloat()<\/li><li>Serial.readBytes()<\/li><li>Serial.readBytesUntil()<\/li><li>Serial.readString()<\/li><li>Serial.readStringUntil()<\/li><\/ul>\n\n\n\n<p>For more on these, see the full <a href=\"https:\/\/www.arduino.cc\/reference\/en\/language\/functions\/communication\/serial\/\">Arduino Serial reference<\/a>. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Data_Protocols\"><\/span>Data Protocols<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>What you&#8217;ve seen in these notes has been a common data protocol called Comma Separated Values (CSV), in which the values of different data items, whether numeric or otherwise, are encoded as text and separated by commas. Here are a few examples:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">23,35,423,24,554,23,51,443,63,74,0,43<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">cat, dog, chicken, eel, pig, donkey, monkey, ocelot<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">23.5, 96.8, 2.343, 0.65, -17.34<\/pre>\n\n\n\n<p>CSV is probably the simplest of data formats, because Unicode is ubiquitous, and almost all programming APIs have a function for splitting strings on a delimiter like a comma. However, there might be more complex data protocols.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"URL_Encoding\"><\/span>URL Encoding <span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>You may have seen something like this at the end of a web URL:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">?lat=40.8028523&amp;long=-73.9562655&amp;name=coco%20nail%20salon<\/pre>\n\n\n\n<p>This is called <a href=\"https:\/\/www.w3schools.com\/tags\/ref_urlencode.asp\">URL encoding<\/a>, and it&#8217;s a common way of formatting data so that it can be included with the hypertext transport protocol, HTTP. You&#8217;ll notice that it always starts with a ?. Web locations can&#8217;t include a ?, so it delimits the beginning of a query string. Items are separated by &amp; symbols, and each item&#8217;s key (or name) comes first, followed by an = sign, then the item&#8217;s value. This is more complex than CSV, but it&#8217;s possible to come up with an algorithm to read it, and functions to do so are common in web-native programming APIs.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"JavaScript_Object_Notation\"><\/span>JavaScript Object Notation<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>A common format used in JavaScript is JavaScript Object Notation, or JSON. A JSON string looks like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n{ \"name\": \"Sandy\",\n  \"age\": 99,\n  \"employed\": true\n}\n<\/pre><\/div>\n\n\n<p>JSON data is always enclosed in braces {}, and each key-value data pair is separated by a colon (:). pairs are separated by commas. Data items can be of any data type, because JavaScript itself is an untyped language. <\/p>\n\n\n\n<p>Since p5.js is a JavaScript API, let&#8217;s look at how it&#8217;d be handy if we sent data serially to it. Here&#8217;s a sample Arduino program to send JSON to p5.js:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\nvoid setup() {\n  Serial.begin(9600);\n}\n\nvoid loop() {\n  Serial.println(\"{\\\"x\\\": 34, \\\"y\\\": 45, \\\"z\\\": 200}\");\n  delay(100);\n}\n<\/pre><\/div>\n\n\n<p>Now here&#8217;s a <code>serialEvent() <\/code>function you can use in p5.js with p5.webserial to receive the data. Take <a href=\"https:\/\/github.com\/ITPNYU\/physcomp\/blob\/main\/Labs\/P5SerialLabs\/P5SerialDuplex\/readMultipleWebSerial\/sketch.js\">this sketch<\/a> and replace the serialEvent function it with the following:<\/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(\"\\r\\n\");\n    \/\/check to see that there's actually a string there:\n    if (inString) {\n      \/\/ parse the string as JSON:\n      var sensors = JSON.parse(inString);\n      locH = sensors.x; \n      locV = sensors.y; \n      circleColor = sensors.z; \n      console.log(sensors);\n  }\n}\n<\/pre><\/div>\n\n\n<p>What&#8217;s happening here is that p5.js is expecting a JSON-formatted string, and parsing it (<code>JSON.parse()<\/code>), and then you get to use the values in it just like a regular JSON object. It&#8217;s simpler than parsing all the pieces out with <code>split()<\/code>.  Of course, it&#8217;s a pain to have to format a complex JSON-formatted string in Arduino, but there is a library that&#8217;ll help, called <a href=\"https:\/\/github.com\/arduino-libraries\/Arduino_JSON\">Arduino_JSON<\/a>.  You can install it from the Library manager (search for the name with the underscore, Arduino_JSON), and install it. There are several examples that come with it, but here&#8217;s a simple one for putting sensor values into a JSON string:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\n#include &lt;Arduino_JSON.h&gt;\n\/\/ make a new JSONVar object called device:\nJSONVar device;\n\nvoid setup() {\n  Serial.begin(9600);\n}\n\nvoid loop() {\n  \/\/ make a data item called x in the JSONVar object:\n  device&#x5B;&quot;x&quot;] = analogRead(A0);\n  delay(1);\n  \/\/ make a data item called y in the JSONVar object:\n  device&#x5B;&quot;y&quot;] = analogRead(A1);\n  delay(1);\n  \/\/ make a data item called z in the JSONVar object:\n  device&#x5B;&quot;z&quot;] = analogRead(A2);\n  \/\/ print out the JSONVar object:\n  Serial.println(device);\n}\n<\/pre><\/div>\n\n\n<p>Add three analog sensors to pins A0 through A2 (potentiometers will do the job). Then try this with the same sketch. p5.js will read the data from the sensors and use them to set the position and color of the ball. <\/p>\n\n\n\n<p>To see the sketch running on GitHub at&nbsp;<a href=\"https:\/\/ITPNYU.github.io\/physcomp\/Labs\/P5SerialLabs\/P5SerialDuplex\/readWebSerialJSON\" target=\"_blank\" rel=\"noreferrer noopener\">this link<\/a>. You can see the source files for copying into the p5.js editor at&nbsp;<a href=\"https:\/\/github.com\/ITPNYU\/physcomp\/tree\/main\/Labs\/P5SerialLabs\/P5SerialDuplex\/readWebSerialJSON\" target=\"_blank\" rel=\"noreferrer noopener\">this link<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>There are lots of different data formats out there, for different applications. Learning how they are structured and how to format them will simplify communication from device to device. Most protocols are either binary, as you saw at the beginning of these notes, or ASCII-encoded, like the ones in the latter half of these notes. Of the ASCII-encoded protocols, CSV is the simplest and most common, but all of them can be learned and interpreted with a little work. When you are using a well-known protocol, it&#8217;s always worth checking to see if there&#8217;s a library to format or interpret it in whatever programming environment you are using. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Serial data is passed byte by byte from one device to another, but it\u2019s up to you to decide how each device (computer or microcontroller) should interpret those bytes, when the beginning of a message is, when the end is, and what to do with the bytes in between. &nbsp;Serial communication protocols define the &hellip; <a href=\"https:\/\/itp.nyu.edu\/physcomp\/lessons\/interpreting-serial-data\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Interpreting Serial Data&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"parent":13,"menu_order":2,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"categories":[42,11,52,54,26,9],"tags":[],"class_list":["post-1737","page","type-page","status-publish","hentry","category-asynchronous-serial","category-code","category-lesson","category-microcontrollers","category-programming","category-serial-communication"],"_links":{"self":[{"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/pages\/1737"}],"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=1737"}],"version-history":[{"count":39,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/pages\/1737\/revisions"}],"predecessor-version":[{"id":10713,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/pages\/1737\/revisions\/10713"}],"up":[{"embeddable":true,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/pages\/13"}],"wp:attachment":[{"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/media?parent=1737"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/categories?post=1737"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/tags?post=1737"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}