Arduino Sensor Data to Processing
For this example we are using the SparkFun Inventor’s Kit and following the Circuit #9 from the SIK Guide Code.zip. This will get the Flex LED working, and we can see the servo motor running.
Next, we’ll get the Flex sensor readings into Processing. I’ve written up a slightly different technique, and it’s based on SparkFun’s Arduino to Processing Tutorial. My technique is a bit simpler, I just want data in processing that I can use. Also, I decided to implement some error-catching code in Processing to create a more stable project. Macs are not happy with Serial ports that are not closed, and this error-handling code seems to help.
This example uses Circuit #9, the flex sensor to get an Analog reading into the Arduino’s A0 Analog In port. If you use another sensor, you’ll need to either use A0 (if it’s an analog sensor) or change the code accordingly.
Steps
IMPORTANT: If your Arduino crashes, or you have issues with it, use the Reset button on the Arduino rather than unplugging the USB to reset it. This seemed to help prevent hard crashes on the Mac when the Serial port was not closed properly.
- Install all drivers and examples from the SIK Guide book that comes with the Inventor’s Kit. And get the Blinking and LED example working
- Follow the instructions and get Circuit #9 working. The motor should turn when flexing the sensor.
- Open the Arduino Serial Monitor to view the incoming data, Command-Shift-M on a Mac. Take a look at the code to see how that information is written.
- Since we don’t need anything but a number for Processing, and we aren’t going to run the servo, we’ll use the File>Examples>Basics>AnalogReadSerial Arduino sketch instead. I made one change – a longer delay (100) instead of (1). Install/Upload the sketch to your Arduino
- Check the Arduino Serial Monitor to make sure data comes in while flexing the sensor.
- Quit out of Arduino and Open up Processing
- Paste the following Processing code into a new Processing sketch and save it.
- Run the code briefly, and then stop it. Check your console in Processing to make sure that you are grabbing data from the list of available Serial Ports printed at the start of the sketch. You need to change
Serial.list()[0]
to the correct port number to get the data. - Run the sketch and bend the sensor, the background color should change. Enjoy!
/*
AnalogReadSerial
Reads an analog input on pin 0, prints the result to the serial monitor.
Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
This example code is in the public domain.
*/
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}
// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// print out the value you read:
Serial.println(sensorValue);
delay(100); // delay in between reads for stability
}
import processing.serial.*;
Serial myPort;
boolean serialInited;
String val;
float value = 0;
void setup () {
//Print a list of available serial ports
println(Serial.list());
initSerial();
}
void draw () {
background(value);
if (serialInited) {
// serial is up and running
try {
val = myPort.readStringUntil('n');
println(val);
if (val != null) {
val = trim(val);
int num = Integer.parseInt(val);
value = map(num, 650, 850, 0, 255);
}
}
catch (RuntimeException e) {
// serial port closed
serialInited = false;
}
}
else {
// serial port is not available. bang on it until it is.
initSerial();
}
}
void initSerial () {
try {
//Based on the list of serial ports available, put the number of the port we want in the [ ] brackets
myPort = new Serial(this, Serial.list()[0], 9600);
serialInited = true;
}
catch (RuntimeException e) {
if (e.getMessage().contains("")) {
System.out.println("port in use, trying again later...");
serialInited = false;
}
}
}
Max Sonar Arduino Code
We have a couple of different Max Sonar Ultra Sonic range finders and here is a post with code to run this on the Arduino. To use this with the Processing example above, you’ll need to simplify the ‘Serial.print’ part of the code to simply print a number, either inches or centimeters.
Here is a sketch for Processing (with Arduino code included and commented out) to run two parallel wired MaxBotix XL-MaxSonar – EZ ultrasonic sensors.
/**
* Simple Read for Two MaxBotix XL Sensors
*
* Read data from the serial port and change the color of the background
* This example works with the Wiring / Arduino program that follows below.
*/
import processing.serial.*;
Serial myPort; // Create object from Serial class
float valueR = 10;
float valueL = 10;
float easingSpeed = .05;
float targetL, targetR;
boolean left = true;
void setup()
{
size(1000, 1000);
//Print the list of devices so we can get the number of the Arduino port
println(Serial.list());
//I'm using port 10
//String portName = Serial.list()[10];
String portName = "/dev/tty.usbserial-AM01PK0Q";
myPort = new Serial(this, portName, 38400);
}
void draw()
{
if ( myPort.available() > 0) { // If data is available,
int num = myPort.read();
println(num);
if (left) {
num = abs(num);
targetL = map(num, 11, 60, 0, 255);
}
else {
num = abs(num);
targetR = map(num, 11, 60, 0, 255);
}
left = !left;
}
valueR = Easing(valueR, targetR, easingSpeed);
valueL = Easing(valueL, targetL, easingSpeed);
background(100); // Set background to white
fill(valueL);
rect(0, 0, 400, 400);
fill(valueR);
rect(width/2, 0, 400, 400);
}
float Easing(float from, float to, float speed) {
float temp = to - from;
if (abs(temp) > 1 ) {
from += temp* speed;
}
return from;
}
//Arduino Code Follows
/*
/*
Two Maxbotix LV EZ1 sonic sensors wired in parallel
*/
//const int sonarSensorPinL = 5; //connected to left sonar pwm pin
//const int sonarSensorPinR = 6; //connected to right sonar pwm pin
//const int sonarTriggerPinR = 7; //connected to right sonar RX pin
//const int sonarTriggerPinL = 8; //connected to left sonar RX pin
//long valueL = 0;
//long valueR = 0;
//int inchesL = 0;
//int inchesR = 0;
//unsigned int calval = 0;
//
//
//void setup()
//{
// Serial.begin(38400);
// pinMode(sonarTriggerPinL, OUTPUT);
// pinMode(sonarTriggerPinR, OUTPUT);
//}
//
//void loop()
//{
// if (calval < 1) { // this calls the calibrate subroutine only once when the sketch begins
// calibrate ();
// }
// calval = calval + 1;
// // Read the value from each sensor pin
// digitalWrite(sonarTriggerPinR, HIGH);
// valueR = pulseIn(sonarSensorPinR, HIGH);
// inchesR = valueR / 147; // 147 microeconds per inch
// // Serial.print("inches right = ");
// // Serial.println(inchesR);
//
// Serial.write(inchesR);
// delayMicroseconds(20); // can be any langth of delay as long as it's >= 20 microseconds according to data sheet
// digitalWrite(sonarTriggerPinR, LOW); //turns off right sonic sensor so that it doesn't read from left sonic pulse
// delay(250); // delay for serial monitor
//
// digitalWrite(sonarTriggerPinL, HIGH);
// valueL = pulseIn(sonarSensorPinL, HIGH);
// inchesL = valueL / 147; // 147 microeconds per inch
// // Serial.print("inches left = ");
// // Serial.println(inchesL);
//
// Serial.write(inchesL);
// //Serial.println();
// delayMicroseconds(20); // can be any langth of delay as long as it's >= 20 microseconds according to data sheet
// digitalWrite(sonarTriggerPinL, LOW); //turns off left sonic sensor so that it doesn't read from right sonic pulse
// delay(1000); // delay for serial monitor
//}
//
//void calibrate ()
//{
// digitalWrite(sonarTriggerPinR, HIGH);
// valueR = pulseIn(sonarSensorPinR, HIGH);
// delay(250);
// digitalWrite(sonarTriggerPinL, HIGH);
// valueL = pulseIn(sonarSensorPinL, HIGH);
// delay(250);
//
//}
//
//