I’ve really been unfocused recently with my robotics hobby. I have so much I want to play with. This post is to document playing with a couple of new toys all together. These are: a sharp GP2D12 range finding sensor (10 to 80cm), an Arduino (actually a seeduino), and the programming language Processing.
A big thanks to David Barnes (of the excellent Quotient Robotics blog) for giving me my first Arduino (an iDuino). I got the bug and have since bought a Seeduino which is the same thing but a bit more of a conventional layout for shields and such.
Note: I’m not claiming to be the first person to do this! The way I go about it may be different and may be useful to someone out there – that’s why I blog about it. My code is based on other examples which I will cite where appropriate.
Arduino Code – simple stuff. Move the servo take a measurement, and print both the angle and the range over serial. I used the example “Sweep” which is a kind of servos 101 example. Listing:
// Sweep servo, take range, send to serial
// by DMT195 <http://dmt195.wordpress.com> modified version of "sweep"
// originally by BARRAGAN <http://barraganstudio.com>
#include <Servo.h>
Servo myservo; // create servo object to control a servo
int pos = 0; // variable to store the servo position
char serialTemp[10]; //variable to create a serial string
int rang; //a variable to store the range value
void setup() {
Serial.begin(9600);
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}
void loop() {
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos);
delay(15); // waits 15ms for the servo to reach the position
rang=analogRead(0);
Serial.print(rang);
Serial.print(",");
Serial.println(pos); // reads the value at the analogue input and outputs this with position to the serial port
}
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos);
delay(15); // waits 15ms for the servo to reach the position
rang=analogRead(0);
Serial.print(rang);
Serial.print(",");
Serial.println(pos); // reads the value at the analogue input and outputs this with position to the serial port
}
}
I then used Processing to plot and visualise the output. I hadn’t come across it before but it seems very suited to this kind of thing. The language is very similar to the Arduino code. Again, I used existing code and modified it for my purposes. Standing on the shoulders of giants and all that. Listing:
// Graphing sketch
// This program takes ASCII-encoded strings
// from the serial port at 9600 baud and graphs them in a polar fassion.
// Original code Created 20 Apr 2005, by Tom Igoe
// Modified code by DMT195 and available free to all
// This example code is in the public domain.
import processing.serial.*;
Serial myPort; // The serial portint
xPos = 1; // anglefloat
deg2rad = PI/180; //conversion factor
float[] magn = new float[180]; //magnitude - somewhere to store the ranges with angle
int x1,x2,y1,y2;
void setup () { // set the window size:
size(800, 400);
stroke(0,255,0); // List all the available serial ports
println(Serial.list()); // I know that the first port in the serial list on my mac
// is always my Arduino, so I open Serial.list()[0].
// Open whatever port is the one you're using.
myPort = new Serial(this, Serial.list()[0], 9600);
// don't generate a serialEvent() unless you get a newline character:
myPort.bufferUntil('\n');
// set inital background:
background(0);
}
void draw () {
// everything happens in the serialEvent()
}
void serialEvent (Serial myPort) { // get the ASCII string:
String inString = myPort.readStringUntil('\n');
if (inString != null) { // trim off any whitespace:
inString = trim(inString);
int[] inArray = int(split(inString, ','));
// convert to an int and map to the screen height:
int inPos = inArray[1];
try{ //I don't claim to understand error handling that well but this seemed to stop the program from crashing
magn[inPos] = map(getRange(inArray[0]), 0, 800, 0, height);
}catch(Exception e){};
// draw the thing:
if((inPos%5)==0){ //This says that for every angle divisible by 5 refresh the drawing
background(0);
plotWhiteBits();
}
x1 = int(width/2-magn[0]);
y1 = height;
for(int i=0; i<180; i=i+1){
x2 = int(width/2-magn[i]*cos(i*deg2rad));
y2 = int(height-magn[i]*sin(i*deg2rad));
line(x1,y1,x2,y2);
x1=x2;
y1=y2;
}
}
}
int getRange(int volts){ //This is my fitting routine. I should check this works at some point!
float rangeInMm = 1/(0.000016*volts+0.0004516);
return int(rangeInMm);
}
void plotWhiteBits(){ //This is a function to draw the background reticules (lines and arcs)
int leng=height*3;
stroke(127,127,127);
for(int j=0; j<180; j=j+15){ //A chose a 15 degree angle between lines
line(int(width/2),int(height),int(width/2-1*leng*cos(j*deg2rad)),int(height-leng*sin(j*deg2rad)));
}
for(int j=1;j<9;j=j+1){ //And this is for the arcs
int spacer=height/4;
noFill();
ellipse(width/2, height, j*spacer, j*spacer);
}
stroke(0,255,0); //return the stroke colour back to the main one
}
I hope this is of use to someone. If you improve it please let me know!
Update: I’ve used XBee devices to do this wirelessly now! Works well.



Glad to see you’ve put that thing to use. Great work!
have problem with this code???