When communicating between a microcontroller and a personal computer using asynchronous serial communication, you often need to transmit a value that is greater than 255. For example, if you want to send the value from a 10-bit analog-to-digital converter (e.g. the result from the Arduino analogRead() command) as a binary value, here’s how you do it:
int sensor = analogRead(A0);
The int data type of this variable takes multiple bytes in the Arduino’s memory. Reading the value 1023 from the ADC, for example, this is the arrangement of the bits in the bytes in memory:
first byte | second byte | |
Bit values of the byte: | 0 0 0 0 0 0 1 1 | 1 1 1 1 1 1 1 1 |
Decimal value of the byte | 3 | 255 |
To separate the original value into two bytes, you divide by 256 to get the first byte, and take the remainder (or modulo) to get the second byte. For example, 1023 / 256 = 3, remainder 255. You can see this in the Arduino code below. To send this value as two bytes from Arduino, you do the following:
// get a 10-bit ADC value:
int sensor = analogRead(A0);
// divide by 256 to get the first byte:
// (result is an integer):
byte firstByte = sensor / 256;
// modulo by 256 to get the second byte:
byte secondByte = sensor % 256;
// send the first of the two bytes:
Serial.write(firstByte);
// send the second of the two bytes:
Serial.write(secondByte);
When you receive this on the personal computer, you need to combine the two bytes back into a single value. To do this, you multiply the first byte by 256, then add the second byte. For example, 3 * 256 + 255 = 1023. Here’s how to do it in p5.js using p5.serial;ort:
// wait until you have two bytes:
if (serial.available() >= 2) {
// read the first byte:
var highByte = serial.read();
// read the second byte:
var lowByte = serial.read();
// combine them into a single value:
var result = (highByte * 256) + lowByte;
// put the result in the text div:
console.log("high byte: " + highByte +
" low byte: " + lowByte +
" result: " + result);
}
Here are the two full sketches for both Arduino and p5.js:
Arduino:
void setup() {
Serial.begin(9600);
}
void loop() {
// get a 10-bit ADC value:
int sensor = analogRead(A0);
// divide by 256 to get the first byte:
// (result is an integer):
byte firstByte = sensor / 256;
// modulo by 256 to get the second byte:
byte secondByte = sensor % 256;
// send the first of the two bytes:
Serial.write(firstByte);
// send the second of the two bytes:
Serial.write(secondByte);
}
The p5.js sketch:
// variable to hold an instance of the serialport library:
let serial;
// HTML Select option object:
let portSelector;
function setup() {
// new instance of the serialport library
serial = new p5.SerialPort();
// callback function for serialport list event
serial.on('list', printList);
// callback function for serialport data event
serial.on('data', serialEvent);
// list the serial ports
serial.list();
textDiv = createDiv('result will go here.')
}
// make a serial port selector object:
function printList(portList) {
// create a select object:
portSelector = createSelect();
portSelector.position(10, 10);
// portList is an array of serial port names
for (var i = 0; i < portList.length; i++) {
// add this port name to the select object:
portSelector.option(portList[i]);
}
// set an event listener for when the port is changed:
portSelector.changed(mySelectEvent);
}
function mySelectEvent() {
let item = portSelector.value();
// give it an extra property for hiding later:
portSelector.visible = true;
// if there's a port open, close it:
if (serial.serialport != null) {
serial.close();
}
// open the new port:
serial.open(item);
}
function serialEvent() {
// if you have received two or more bytes:
if (serial.available() >= 2) {
// read the first byte:
var highByte = serial.read();
// read the second byte:
var lowByte = serial.read();
// combine them into a single value:
var result = (highByte * 256) + lowByte;
// put the result in the text div:
console.log("high byte: " + highByte +
" low byte: " + lowByte +
" result: " + result);
}
}
Here’s the index.html page:
<!DOCTYPE html><html lang="en"><head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.min.js" integrity="sha512-WIklPM6qPCIp6d3fSSr90j+1unQHUOoWDS4sdTiR8gxUTnyZ8S2Mr8e10sKKJ/bhJgpAa/qG068RDkg6fIlNFA==" crossorigin="anonymous"></script>
<script language="javascript" type="text/javascript" src="https://cdn.jsdelivr.net/npm/p5.serialserver@0.0.29/lib/p5.serialport.js"></script>
<meta charset="utf-8">
</head>
<body>
<script src="sketch.js"></script>
</body></html>
You will also need the p5.serialcontrol app to connect the sketch in a browser to the serial port.