Arduino – Using a Sharp IR Sensor for Distance Calculation

Well, looks like my sonar sensor (SRF05) is a just a tad inaccurate for precise measurement as I found from my radar screen I made (Arduino Radar Sscreen). So I’ve...

Well, looks like my sonar sensor (SRF05) is a just a tad inaccurate for precise measurement as I found from my radar screen I made (Arduino Radar Sscreen).

So I’ve got hold of a Sharp GP2Y0A02 series infrared distance sensor. It’ll detect and measure anything within a 20-150cm range and it does this by triangulation from where it emits a beam of IR and from when it receives it – this isn’t too important to understand.

The hardest bit of this is actually just getting a rough distance value out of it. If we look at the data sheet you’ll see a graph of Volts to Distance and the greater the voltage the shorter the distance. So to measure distance we’ll need to measure the voltage change as the distance changes.

To do this I have to use the analog pins on the Arduino board, now first off because we’re connecting/ reading directly from the sensor we need to convert the digital value that the Arduino’s onboard analog to digital converters will give us. Sounds odd? Well when you use the analog pins it converts what ever arbitary analog value supplied to a byte value which is between 0 and 1023 (1024 variations).

Sharp-GP2Y0A02Looking at our graph above from the datasheet, this converted value is of no use to us so we need to convert this value back to the true analog value. How? We take the voltage rating of the power supply and divide by 1024 to give us a value per step. So for instance:

5v/1024 = 0.0048828125

We take this value and multiply by what the sensor sends back to get our voltage reading. The next stage is to work out an equation from the graph on the data sheet to get the theoretical distance from the voltage reading, if we look at the graph between 20 and 150cm you can see that its exponential.

To get our distance on the graph I came up with:

1/Volts * 65

I got 65 by taking the distance on the graph and dividing that by 1/Volts. So now we know what to multiply our voltage results by to get the distance. This is fine if we just had one value to read or if this was a linear graph, in that the change in voltage was always the same amount of distance.

For the exponential change we have to turn our value now into an exponent, a fancy way of saying x to the power of y. So our formula for distance from voltage reading is now something like:

distance = (Volts x)*65.

Since our graph is a decaying exponential the value of x will be a fraction – to write this as a exponent we have to use a minus number e.g. -1. The exponent -1 is the equivalent of the fraction 1/2 which is 0.5 as a decimal.

Now through trial and error I programmed this into my Arduino and changed the exponent until my readings became accurate(ish) I started at -1 and by co-incidence the next value I tried was -1.1 which is 11/10 as a fraction, 0.65 as a decimal and oddly enough 1/100th of my distance ration, 65!

Anyway its not spot on but this seems to work for my sensor, for any other Sharp IR sensor, first work out the distance ratio from the graph and then try changing the exponential until you get accurate results. If anyone can show me the equations for doing this that’d be great as I only did this through trial and error.

In Arduino the code for my equation is:

float volts = analogRead(IRpin)*0.0048828125; ;
float distance = 65*pow(volts, -1.10);

I’m using float for my values as the expected result will not be integer and the pow(number, exponent) function is an Arduino function that lets us raise a specified number by a power/ exponent.

So the only other hassle is wiring up the sensor which has 3 pins from a JST connector (Japan Solderless Terminal). Picture below for mapping the Power (Vcc), GND and Reading (Vo).

Arduino Sharp IR Distance Sensor Circuit

Pretty easy – I’ve got a JST lead plugged it in and removed the casing on the wires to expose them and I’ve just jabbed that into a breadboard. Then i’ve run standard jumper wires from these to the Arduino board.

Sharp-GP2Y0A02-circuit

Sharp Infrared Arduino Sketch

Again, pretty easy, read the analog pin and apply my above logic, printing the value to the serial port.

int IRpin = 1;                                    // analog pin for reading the IR sensor

void setup() {
  Serial.begin(9600);                             // start the serial port
}

void loop() {
  float volts = analogRead(IRpin)*0.0048828125;   // value from sensor * (5/1024) - if running 3.3.volts then change 5 to 3.3
  float distance = 65*pow(volts, -1.10);          // worked out from graph 65 = theretical distance / (1/Volts)S - luckylarry.co.uk
  Serial.println(distance);                       // print the distance
  delay(100);                                     // arbitary wait time.
}

Seems pretty accurate, although there does seem to be spikes but with the same approach to the sonar sensor we can smooth this by taking an average of multiple readings. Next step is to run my radar visualisation on it.

Arduino-testing-Sharp-IR
And just so you can see my screen readings:

Sharp-GP2Y0A02-readings

Pretty much measuring spot on, though of course if you’re closer than 20cm are futher than 150cm then the measurements will be grossly inaccurate as this is out side of the sensors evironment.

This content is published under the Attribution-Noncommercial-Share Alike 3.0 Unported license.

Technorati Tags: , , , , , , ,

  1. Arduino + Processing – Make a Radar Screen – Part 3: Visualising the Data from Sharp Infrared Range Finder
  2. Arduino + Processing – 3D Sensor Data Visualisation
  3. 3 LED Crossfade with PWM and Arduino
  4. Arduino – A Basic Theremin
  5. Arduino – Getting my LCD Screen to work.
  6. larryBot – Arduino robot versions 0.1 to 0.5 lessons learned
  7. Arduino – making a basic drum machine
  8. Arduino – IR remote/ intervalometer for Nikon D80 DSLR (that means timelapse photography yarrr!)
  9. Arduino – Control a DC motor with TIP120, potentiometer and multiple power supplies
  10. Using Processing to Send Values using the Serial Port to Arduino