Arduino – Using a Sharp IR Sensor for Distance Calculation

Arduino testing Sharp IR

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 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 -
  Serial.println(distance);                       // print the distance
  delay(100);                                     // arbitary wait time.

[ad#Google Ad in content]

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.

And just so you can see my screen 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.


  • I wouldn’t be surprised if each cell in the CCD of the Sharp sensor increases output voltage by a constant. In that case, you are dealing with an (inverse) tangent. The further the objecct is away, the smaller the change in output is. This is what you want; an accuracy of 10 cm at 150 cm is as important to detect danger as an accuracy of 1 cm at 20 cm.
    So suppose the CCD has five cells. In that case: infinite-> first CCD cell gets illuminated. 150 cm->second CCD cell gets illuminated.75 cm-> third CCd cell gets illuminated. 30cm-> fourth cell gets illuminated. 15 cm-> fifth cell gets illuminated. <15 cm: reflection of IR beam on house internals make the signal go back through cells five, four, three, two, one. Now there are probably more than 5 cells, but the tangent remains (distance traveled sideways across CCD cells/distance away from sensor)=tan alpha, alpha is the angle between the outward and bounced IR beam at the point of reflection.

    • Correct me if I am wrong, but I am pretty sure that the SHARP IR sensor uses a PSD sensor, not a CCD.

      • Yep I actually think you’re right there! Will update that.

  • I used your exponential to linear conversion in Processing and it works fine! Thanks! Happy New Year!

  • I used your code with the GP2D120XJ00F sensor and it works reasonably well, but since this sensor has a much shorter range, 3 to 40cm, it’s not worth using it and losing so much precision.

    However, I got the best results with the values below. ADC reference voltage is 3.3V.

    float volts = analogRead(IRpin)*0.00322265624;
    float distance = 12.21*pow(volts, -1.15);

    • Hi , i’am newbie about microcontroller after i read your project make me more understand about this thing 🙂

      btw i wan’t to ask , is there a problem if i directly link the cable from IR sensor to arduino ( eliminate bread )


      • There’s no problem connecting the sensor directly to the Arduino – I just use the board out of habit 🙂

  • Hi, great article .

    Can anyone help me calculate the distance to a GP2Y0A21YK0F (0-80cm) sharp sensor?


    • Hi Miguel,

      You can use what I did as a basis but you need to datasheet here:

      So you should be able to re-do my work using the graph in that pdf. Taking the distance on the base of the graph and dividing that by the 1 divided by the voltage on the y axis, check a few points on the graph to get the best fit (works out to be 30 roughly)

      Then change all my work from that figure of 65 to use the figure of 30 (or whatever you work it out as)

  • Thanks Larry.

    Actually the factor i find more effective is 27.

    • I found I had to tweak my measurements when using the sensor but after that it was fairly reliable.

      Be sure to use an averaging method to iron out voltage spikes etc..

      So take 5 – 10 readings then average them. tends to be more accurate.

  • Something I found was that the the Sharp data sheet recommendation for a by-pass capacitor of 10uF or more between Vcc and GND was a good idea. Noticable improvement in the stability of the output signal when I put a 20uF in there.

    • Cheers for the heads up, I’d not tried a capacitor, I’ll have to give that go and see if that improves my accuracy when I next use this.

  • Hi there,

    newby here.

    What if i want inches and not centimeters as my final serialprint?

    i’m using a P2Y0A21YK0F (0-80cm) sharp sensor.
    sorry but the codes notation gets cut off by the webpage frame for some reason.
    What part of your equations tells it that it’s centimeters? is it the 10 in

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


    • Hi the equation is worked out from the graph which is in cm, so I guess do a conversion between cm and inches on my value of 65 would probably be a quick way of testing the equation.

      Or, much easier, convert my final value to inches so that would be something like: distance in cm / 2.54 = distance in inches

      Of course thats saying that my equation is 100% accurate :s

  • thanks larry. will try it out this weekend.


  • Wondering how you got that 65… can you be a bit more specific on how you got it. I have a whole bunch of different sharp sensors that i’m trying to linearise…


  • Wow, so i was working on and off for about 36 hrs. formulated a series of steps using logarithms… but after ‘calibration’ did not accurately measure any other distance lol.

    This seems so much simpler haha.

    thanks for showing another way

    • Took me a while as well trying to use logarithms and I gave up and just bodged it from the chart. 🙂 glad it helped you out as well – for other sensors though my magic value of 65 will be different.

  • hey larry,

    i tried to use the device with the code given and it appears that it has a problem and i dont get any output… can someone help me?

    int IRpin = 1; // analog pin for reading the IR sensor
    int val=0;
    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 –
    Serial.println(distance); // print the distance
    delay(100); // arbitary wait time.

    and this is what appears after running the code:

    Binary sketch size: 4448 bytes (of a 32256 byte maximum)

    regards irene!

    • Hi Irene,

      I am going to assume that you did hook up the arduino to your computer properly, and it did upload properly. Did you set the baud rate right when looking at the serial print from the arduino?

    • looks like the code is messed up, remove the comment line: S –

    • Yeah, I’m having the same problem. It is set at 9600 baud but nothing is printed in the main console. Also, the Serial Monitor keeps printing 0.

  • i used your code exactly as you present it, but the values of distance which i take as an output of the arduino board are not stable. The object and sensor are steady but the values keep changing within 30 and 50 cm.. Does this mean that my sensor is problematic?

    • are you using the exact same sensor as me? different sensors require different settings

  • Hi,

    I realize that this is a really old project, but in case you do still look at this, did the JST connectors come with your SHARP IR sensors? I feel kind of jipped because mine didn’t, and if I even choose to use them, I would have to pay about $2 to get a set. Are they even worth it or should I just go the cheap way, and remove the female JST, and just solder wires directly to the sensor?



    • Hi, I have to solder directly, the connector are a bit out of standard for my local sellers.

      • shouldn’t be an issue as long as the soldering irons not a high power one! failing that I might have a spare JST connector I can send

    • I had to pay extra I think – it is really annoying and seems to be mixed between suppliers. Some give them away.

  • There is a better way. Plot voltage / distance data in excel and let excel fit the curve with the needed formula. Worked great for me.

  • can you please explain that how you get the value 65

  • in this statement
    float distance = 65*pow(volts, -1.10);

    how you calculte the -1.10.can you please explain it more

  • […] up the Sharp IR distance sensor to transmit the distance over XBee to my explorer module. This post helped me get very accurate readings from the distance […]

  • can you make a sketch on how to put this to EEPROM??..thanks..

  • Worked great for me, and the values aren’t much off (for my needs anyways), thanks a bunch!

  • Don’t average! Never average with sensors! Use filters like reading 10 times, sort it, and discard the extreme values. This is better than average. 🙂

    • Sound advice there. Thanks. Every day is a school day 🙂

  • […] la mesure de distance avec ce capteur, j’ai utilisé les instructions très complètes de cette page, vous en retrouverez donc une partie du code dans […]

  • Hi Larry,

    Thanks for posting this up. I’m still confused about how you got 65. I’m using a GP2D120 sensor and I’m trying to modify your code to that.
    Please help.


    • Hi Ryder,

      I’m not positive about this, but I believe the 65 in Larry’s equations is the slope of the graph, sort of. I believe it’s 1 over the slope times -1:
      -1 * 1 / m
      where m is the slope derived from
      m = rise / run = (0.5 – 2.5)v / (150 – 20)cm = -2v / 130cm = -0.015384v/cm
      -1 * 1 / -0.015384v/cm = 65cm/v

      That’s my assumption, but you know what happens when you make those

  • I’m still having trouble understanding how you got the number 65? Is it the slope of the graph at a certain domain?

    • Hi,

      You can get the number from the data sheet. Pick a handful of distances on the data sheet graph and multiply the distance by V, where V is indicated by the graph. Do this for a number of values along the range of distances and then average them to find an approximation.

      In his case, you have:

      30cm and 2V – 30×2=60
      40cm and 1.5V – 40×1.5=60
      60cm and 1V – 60×1=60
      130cm and .5V – 130×0.5=65

      (60+60+60+65)/4 = 61.25

      In the ideal case, this number might provide a better estimate, but differences in individual sensors and environments will require adjustments to provide a better factor. Just go through that process to get a good starting point.

  • Hello!

    I want to test a distance measuring sensor: Sharp’s GP2Y0A21YK0F. Can I use the same program the one you used for the Sharp Infrared Arduino Sketch?

    Thank you

  • Hello from Greece i would like to ask a question about my IRsensor.. i have the Sharp 2Y0A21 and i want to measure the distance of a water tank. With your code my sensor works perfect but whet it faces water then start to measure wrong.. what should i do? what is the problem? Thank you.

  • This might be an overly simple question – but I’m building my first project using a sharp IR sensor and I’m not clear on how you’re supposed to create a circuit to power the sensor with only one power input pin? (i.e. no +/- terminals).

  • Excellent, I have the GP2Y0A41SK0F (4-30cm), I assume it will be very similar to this – So this helps a lot, thank you!

  • Hi Larry, Do you have any experience with the Digital Sharp Ir sensor, GP2Y0D21YK0F? I connect the sensor exactly like what you do to GP2Y0A02, except the digital output. I connect the Voutput of the sensor to a digital pin on Arduino. But it didn’t work, then I go through the data sheet again and realize there should be a 12kohm between +V and Voutput. But it still doesn’t work after I add the resistor between the two pins. Please help.

    GP2Y0D21YK0F datasheet:

  • Hi Larry,

    at the top of your post you compared the sensor’s accuracy with that of sonar sensors. Do you know how they compare as far as speed goes? IOW, can I get accurate readings for fast changing distances? (need a good sensor for real time music experiments…)

You must be logged in to post a comment.