Sending serial data from an Arduino circuit to a Processing application

From Knowledge Kitchen
Jump to navigation Jump to search


This example shows how to send data from an Arduino circuit to a Processing application via serial communication. Serial communication is a very common and standardized protocol that allows two computers or devices to talk to each other via a series of digital pulses over a few wires (in this case a USB cable).

In this example, we program the Arduino to read the analog value of a potentiometer plugged into a simple circuit. The Arduino then relays this potentiometer value to the desktop computer using serial communication over the USB cable. The Processing application on the computer then reads this serial data and uses it to control the diameter of a red circle on the yellow screen.


The circuit

You must build a circuit where a potentiometer is connected to one of the analog input pins of the Arduino. The code assumes this will be pin A0. If you have forgotten how to hook up a potentiometer to an Arduino, then perhaps reviewing a simple example of a reading potentiometer's value in Arduino to control an LED will help.

The Arduino code

Arduino code for sending serial data to Processing

Sending serial data to another device

This example code uses the Serial.write() method of the Arduino to send the potentiometer value as a single 8-bit binary value (i.e. a byte) out the serial port to the desktop computer. This is different from the Serial.println() method we have previously used to send a stream of values, each representing a single ASCII character] out the serial port. The println() method first converts the data to a string (a sequence of ASCII character codes - each one byte long), and then sends these out one byte for each of the character codes in that string. The two methods are useful for different purposes.

Mapping values to a different range

Note the use of the map() method in this example. This is a simple way to take the value from one range and map it to an equivalent value in a different range. In this example, we are taking an analog input value from 0 - 1023, and mapping it to an equivalent value in the range 0 to 127.

Arduino's analog input pins read values as 10 bits. In other words, an analog input value can only be between 0 - 1023.

Serial communication sends data one byte at a time. So if you just want to send one value, you must send data that takes up no more than 8 bits (i.e. 1 byte) of binary code. In other words, you must send a number between 0 to 255 in order for it to fit into one byte. So in this example, we are mapping the 10-bit 'analog' input signal to an 8 bit serial output signal.

The Processing code

//import the serial library
import processing.serial.*;

//a variable that will hold a serial port object
Serial arduinoPort;

//variables that will hold the position and radius of the ellipse we'll draw
int x
int y;
int radius;

//app-wide settings
void settings() {
	//set the window size
	size(320, 240);

	//set the initial values for the ellipse
	x = (int) width / 2;
	y = (int) height / 2;
	radius = 10;

	//DEBUG: output a list of the serial ports available on this computer
	//the arduino should show up on one of them
	println(Serial.list());

	//change the number 1 below to match the port of the arduino on your computer from the list printed above
	String portName = Serial.list()[1];

	//make a serial port object
	arduinoPort = new Serial(this, portName, 9600);
}

//settings for the first frame
void setup() {
	background(0, 255, 255); //draw the background color
	fill(255, 0, 0); //set the fill color
}

//logic for what to show on each frame of the animation
void draw() {
	//set the stage by wiping out the background
	background(0, 255, 255);

	//draw an ellipse
	ellipse(x, y, radius*2, radius*2);

}

//this method is automatically called if a new byte is available at the serial port
void serialEvent(Serial port) {
	//read a byte from the serial port... this will be a value between 0 - 255
	int byteValue = port.read();

	//PS: if you're expecting this byte to be a Unicode String, you can use the readString() method instead
	//String stringValue = port.readString();

	//DEBUG: print out the value we read from the serial port
	println(byteValue)

	//now do something interesting with this value
	//in this example, we simply map it to an x:y coordinate on the screen
	map(byteValue, 0, 255, 0, width); //map it to a value from 0 to the width of the screen

}


Once we have read in the serial data into the Processing code and have thereby obtained the potentiometer reading send from the Arduino, we use it to control the diameter of an ellipse which we continually draw to the screen.

Serial library

Notice that we import Processing's serial library that contains a lot of useful functions for dealing with serial communications.

Problems

If you see errors when trying to use the Processing Serial Library for the first time. Here are instructions on what to do if this happens.


Mapping values to a different range

As we did in the Arduino code, in Processing we can also use a map() method to map values from one range to another. In this case, we are mapping an 8-bit value between 0 - 255 (i.e. a single byte) to a value from 0 to whatever the width of the window is.

What links here