Thursday, October 15, 2009

Arduino/Serial Communication/Processing

This week we started to learn about serial communication. Serial communication allows us to send (or receive) data from another device. The other device can then use the data if a program on the device is able to access the serial port where my initial data is coming from. This was a fun lab and the implications are also fun. This lab starts to show the possibility of gathering data in the physical world via Arduino and doing something useful with it on a more powerful and robust computational device.

In this example, I am going to gather data with an Arduino microcontroller and an FSR.




I am then going to send this data to my computer via a serial connection and port and allow a fun little program called Processing to play around with it. Specifically, processing is going to be graphing my FSR data. When Processing receives a "high" value from my sensor that corresponds with a strong squeeze of my FSR, the graph will correspondingly go up.

First, the code for the Arduino is as follows:

int analogPin = 0;
int analogValue = 0;

void setup()
{
// start serial port at 9600 bps:
Serial.begin(9600);
}

void loop()
{
// read analog input, divide by 4 to make the range 0-255:
analogValue = analogRead(analogPin);
analogValue = analogValue / 4;
Serial.print(analogValue, BYTE);
// pause for 10 milliseconds:
delay(10);
}


This code is simply reading my FSR and printing the value as a byte in the serial monitor.

As previously mentioned, in order to do something useful with the data, I need to have another program access this data. In this instance I'll use Processing. Processing will take my values and create a graph that has the sensor byte value on the Y axis and time on the X axis.

Here is the Processing code:

/*
Sensor Graphing Sketch

This sketch takes raw bytes from the serial port at 9600 baud and graphs them.

Created 20 April 2005
Updated 5 August 2008
by Tom Igoe
*/

import processing.serial.*;

Serial myPort; // The serial port
int graphXPos = 1; // the horizontal position of the graph:

void setup () {
size(400, 300); // window size

// List all the available serial ports
println(Serial.list());
// I know that the fisrt port in the serial list on my mac
// is usually my Arduino module, so I open Serial.list()[0].
// Open whatever port is the one you're using.
myPort = new Serial(this, Serial.list()[0], 9600);

// set inital background:
background(48,31,65);
}
void draw () {
// nothing happens in draw. It all happens in SerialEvent()
}

void serialEvent (Serial myPort) {
// get the byte:
int inByte = myPort.read();
// print it:
println(inByte);
// set the drawing color. Pick a pretty color:
stroke(123,128,158);
// draw the line:
line(graphXPos, height, graphXPos, height - inByte);

// at the edge of the screen, go back to the beginning:
if (graphXPos >= width) {
graphXPos = 0;
// clear the screen:
background(48,31,65);
}
else {
// increment the horizontal position for the next reading:
graphXPos++;
}
}


ONE NOTE...When you load your Processing sketch, you must have your Arduino plugged in and running the aformentioned program. You need this so that the Processing code that looks at serial ports will capture the correct serial port. ALSO, this code works for Mac's as the first serial port that comes up in Processing is the serial port we want to access:

myPort = new Serial(this, Serial.list()[0], 9600);


This code in our Processing program is telling our program to access the first serial port in the array returned by this code:

println(Serial.list());

It might be slightly different on a PC.

Here is the finished product in action...