Connecting Arduino to Processing
Shaking Hands (Part 2)
For the Processing side of things, we've got to make a few changes. We're going to make use of the serialEvent()
method, which gets called every time we see a specific character in the serial buffer, which acts as our delimiter - basically it tells Processing that we're done with a specific 'chunk' of data - in our case, one 'Hello, world!'.
The beginning of our sketch is the same except for a new firstContact
boolean, which let's us know when we've made a connection to Arduino.
language:java
import processing.serial.*; //import the Serial library
Serial myPort; //the Serial port object
String val;
// since we're doing serial handshaking,
// we need to check if we've heard from the microcontroller
boolean firstContact = false;
Our setup()
function is the same as it was for our serial write program, except we added the myPort.bufferUntil('\n');
line. This let's us store the incoming data into a buffer, until we see a specific character we're looking for. In this case, it's a carriage return (\n) because we sent a Serial.println from Arduino. The 'ln' at the end means the String is terminated with a carriage return, so we know that'll be the last thing we see.
language:java
void setup() {
size(200, 200); //make our canvas 200 x 200 pixels big
// initialize your serial port and set the baud rate to 9600
myPort = new Serial(this, Serial.list()[4], 9600);
myPort.bufferUntil('\n');
}
Because we're continuously sending data, our serialEvent()
method now acts as our new draw()
loop, so we can leave it empty:
language:java
void draw() {
//we can leave the draw method empty,
//because all our programming happens in the serialEvent (see below)
}
Now for the big one: serialEvent()
. Each time we see a carriage return this method gets called. We need to do a few things each time to keep things running smoothly:
- read the incoming data
- see if there's actually anything in it (i.e. it's not empty or 'null')
- trim whitespace and other unimportant stuff
- if it's our first time hearing the right thing, change our
firstContact
boolean and let Arduino know we're ready for more data - if it's not our first run, print the data to the console and send back any valid mouse clicks (as 1's) we got in our window
- finally, tell Arduino we're ready for more data
That's a lot of steps, but luckily for us Processing has functions that make most of these tasks pretty easy. Let's take a look at how it all breaks down:
language:java
void serialEvent( Serial myPort) {
//put the incoming data into a String -
//the '\n' is our end delimiter indicating the end of a complete packet
val = myPort.readStringUntil('\n');
//make sure our data isn't empty before continuing
if (val != null) {
//trim whitespace and formatting characters (like carriage return)
val = trim(val);
println(val);
//look for our 'A' string to start the handshake
//if it's there, clear the buffer, and send a request for data
if (firstContact == false) {
if (val.equals("A")) {
myPort.clear();
firstContact = true;
myPort.write("A");
println("contact");
}
}
else { //if we've already established contact, keep getting and parsing data
println(val);
if (mousePressed == true)
{ //if we clicked in the window
myPort.write('1'); //send a 1
println("1");
}
// when you've parsed the data you have, ask for more:
myPort.write("A");
}
}
}
Oof. That's a lot to chew on, but if you read carefully line by line (especially the comments), it'll start to make sense. If you've got your Arduino code finished and loaded onto your board, try running this sketch. You should see 'Hello, world!' coming in on the console, and when you click in the Processing window, you should see the LED on pin 13 turn on and off. Success! You are now a serial handshake expert.