A scanning range finder using Arduino and Processing

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.

Plotting range with angle

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 <https://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.

Advertisements

3 Responses to A scanning range finder using Arduino and Processing

  1. Glad to see you’ve put that thing to use. Great work!

  2. kappa says:

    have problem with this code???

  3. Erwin says:

    I have also problem with the code of processing , something as expecte EOF found xPos

    Kind Regards

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: