Infrared Distance Measurement with the Raspberry Pi (Sharp GP2Y0A02YK0F)

There are some infrared distance sensors from the manufacturer Sharp, which can be operated very simply with the Raspberry Pi. There are different distance meters, which cover different distance ranges. These modules work similarly to laser distance meters, but with infrared light. There, bundled light is emitted by a transmitter and an analogue voltage is transmitted through a receiver on the basis of the angle of incidence, whereby the distance can be calculated.

In this tutorial, the distance sensor GP2Y0A02YK0F shows how a distance can be determined. This may be useful, e.g. in the car as a car PC (rear view camera distance), as a robot car or in the context of home automation.


Required Hardware Parts – Distance Sensors

The IR transmitter is located on the "indented" side (right).

The IR transmitter is located on the “indented” side (right).

Overall, Sharp has several distance measures in the offer, where it individually should be looked which one is suitable for the task. This tutorial is designed for the Sharp GP2Y0A02YK0F, which is suitable for ranges from 20cm to 150cm. Distances outside this range are not measured correctly.
The following modules are available:

If you use a sensor other than the GP2Y0A02YK0F, you may need to adjust the steps. The data sheets are available on the Sharp homepage.

You will also need the following:



Operating the Infrared Distance Sensor

This IR sensor needs an input voltage between 4.5V and 5.5V, so it can be perfectly operated with the 5V of the Raspberry Pi. According to the datasheet, a different voltage is applied to the data pin, depending on how far the object measured by the sensor is. This is visible in the following graph:


Based on the voltage, the distance between about 15cm and 150cm can be derived relatively accurately.



Connection of the MCP3008


Since the outgoing voltage is analog, first we have to “translate” it with an analog-to-digital converter, so that we can evaluate it with the Raspberry Pi. This works best with an MCP3008 ADC.

This device is controlled via the Pi’s SPI bus and has eight channels to which analog voltages can be translated. These are divided into 2 ^ 20 so 1024 areas (0-1023). If the MCP3008 is connected to 3.3V, a signal of 1 means 0.00322V (3.22mV). Since the SPI bus of the Raspberry Pi works on 3.3V, no more power should be applied, otherwise, the GPIOs can be damaged.

The whole circuit looks like this:



RaspberryPi MCP3008
Pin 1 (3.3V) Pin 16 (VDD)
Pin 1 (3.3V) Pin 15 (VREF)
Pin 6 (GND) Pin 14 (AGND)
Pin 23 (SCLK) Pin 13 (CLK)
Pin 21 (MISO) Pin 12 (DOUT)
Pin 19 (MOSI) Pin 11 (DIN)
Pin 24 (CE0) Pin 10 (CS/SHDN)
Pin 6 (GND) Pin 9 (DGND)


The distance sensor has only three connections: red (5V), black (GND) and yellow, which is the data pin and connected to the MCP3008 ADC. For some, the alarm bells may sound and ask why a 5V module is connected directly, although the Pi’s SPI bus should not receive more than 3.3V input. The data sheet indicates that the output voltage of the sensor never exceeds 3V (see graph from the data sheet). Anyone who is afraid that something could happen to the Pi can put a voltage divider with 2 resistors in front of it, but this reduces the accuracy and also my used formula would have to be recalculated. In my tests, it never reached voltages above 2.7V (GP2Y0A02YK0F). This may differ for the other Sharp sensors.



Software for Reading the Distance

To control the MCP3008, the SPI bus must be activated. This works as follows:

sudo raspi-config

„8 Advanced Options“ -> „A6 SPI“ -> „Yes“.
After that, you have to confirm the restart.

In some cases, the module (spi-bcm2708) must also be entered in the / etc / modules file. For that just call

sudo nano /etc/modules

and add the following line at the end (if it does not exist):

Now the spidev library can be installed, if it has not already been done:

sudo apt-get install git python-dev
git clone git://
cd py-spidev/
sudo python install


Now that we have all the needed packages installed, we can create the script to measure the distance.

sudo nano

The script has the following content:

We can do it now with (sudo python, after we aim at an object, the distance is output.

What exactly happens here? First, the analog value (between 0 and 1023) is read out (line 15). However, since we want to know the voltage, the value is divided by 1023 and multiplied by 3.3 (volts).

Attention: In this case, we know (according to the data sheet) that the output voltage never exceeds 2.8V, although we supply the sensor with 5V. Other modules (analog and digital) often return signals with voltages as high as the applied voltage. Failure to do so may result in damage to the Raspberry Pi.


In line 16 of the script, I calculate the tension in centimetres. I have found the formula  here and adapted it a little. For this, I have tested different distances and changed the factors a bit so that the calculated distance is as accurate as possible. As I mentioned at the beginning, this formula is only for the Sharp GP2Y0A02YK0F sensor. Since the other sensors provide analog signals in the similar range, this formula needs to be adjusted for the corresponding sensors (if anyone does that, I’d be happy if he posts it below).
Alternatively, one can also interpolate between the areas (data sheet) by storing all clues (volts, distance) and reading out the specific value and calculating the distance to the measured voltage using linear interpolation.

Sooner or later I will have to attach such a module to the inside of the rear window of my car and have a distance meter when parking in reverse – if someone does not yet know what he can do with it 😉

19 Responses

  1. Hi

    I’ve attempted this project. I am new to spi and spidev. ive added print(v) to display the registered input voltage as well as the calculated distance. I am getting very small voltage values and large distances ~280-340 cm. Otherwise my script and hardware is wired as in your description. Maybe my sensor is bad?

    Any suggestions?

  2. I am trying to get this ir working and it only reads as 301 cm – not sure what is wrong?

  3. I am also having this issue. We have 4 people working on this and haven’t had any luck in the last several weeks.

  4. For those seeing the 301.44cm reading:

    The above circuit is using hardware SPI to wire the MCP3008. I found some of these chips don’t support hardware SPI but can still use the software SPI protocol.

    Here’s how to wire the chip:

    Lower row:
    CH0: Data from sensor

    Upper row (left to right, left is the “notch” position):
    VDD -> 3.3V
    VREF -> 3.3V
    AGND -> GND
    CLK -> GPIO 18
    DOUT -> GPIO 23
    DIN -> GPIO 24
    CS/SHDN -> GPIO 25
    DGND -> GND

    Afterwards do NOT install the py-spidev package but instead get the following packages using PIP:


    Finally use the following modified python3 code:

    import time
    import Adafruit_GPIO.SPI as SPI
    import Adafruit_MCP3008

    CLK = 18
    MISO = 23
    MOSI = 24
    CS = 25
    mcp = Adafruit_MCP3008.MCP3008(clk=CLK, cs=CS, miso=MISO, mosi=MOSI)

    while True:

    v = (mcp.read_adc(0) / 1023.0) * 3.3
    dist = 16.2537 * v**4 – 129.893 * v**3 + 382.268 * v**2 – 512.611 * v + 301.439
    print(“Distance {:.2f}”.format(dist))

    Hope that helps!

    • @wintergarten

      Hey there, when I try to lauch your script it just tells me this :

      « File “”, line 13
      v = (mcp.read_adc(0) / 1023.0) * 3.3
      IndentationError: expected an indented block »

      What’s the issue? Very new to this so I have no idea. (btw I renamed the script to « »)

      • Nevermind, I found out that there were a couple of errors in the code, but I got to correct them. The issue I have now is that my sensor gives me random values. Please note that I am using the GP2Y0A710K0F (100cm – 550cm) and not the GP2Y0A02YK0F (20cm – 150cm), the problem being that there aren’t any tutorials on the former…

      • @AlexP
        I have the same issue like you,can you teach me how to solve it?
        thanks in advance

    • This worked perfectly!! I made a single change though. When I installed Adafruit_MCP3008, I had to use pip3 rather than pip. Was receiving a no module found error prior to this. Thank you!

    • Thanks wintergarten, this worked much better but the figures i get are about double the expected distance. I am staying beyond the 20cm range. Anyone else see anything like this? using the following:

      v = (mcp.read_adc(0) / 1023.0) * 3.3
      dist = 16.2537 * v ** 4 – 129.893 * v ** 3 + 382.268 * v ** 2 – 512.611 * v + 301.439

    • Hi,

      I have wired my mcp3008 like you say, but i have a lot of issue when i run your piece of code.

      ImportError: No module named Adafruit_GPIO.SPI
      -bash: ImportError:: command not found


  5. Hi, can anyone help me when there is nothing in the script after doing all the steps and entering
    sudo nano
    It doesn’t show the script…

  6. The sensor I am using is GP2Y0A21.
    I tested it according to the author’s method, but my value is 11.43cm. No matter how I move the sensor, the result is still the same.
    What should I do?

      • I put this code in a loop for 30 seconds and I get one of two values at veery moment of time – 11.22/11.43 cm.
        I did everything according to this guide.. I will try to find a solution

  7. @wintergarten Thank you it helps me, I was trying with raspberry pi 3b+ and a Sharp 2Y0A21

  8. for Sharp 0A41SK (input 3.3V) between 0.48 and 2.25 Volt ( 5-30cm)
    dist = 8.53* v**4 -54.90*v**3 +131.26*v**2 -144.85*v +72.28
    or simpler
    dist = 13.91/v -1.48
    Thanx for great article!

  9. Excuse me, do you know if it is possible to change the MCP3008 for an ADS1115 and if it is possible, would there be a problem in obtaining data?


Leave a Comment

Your email address will not be published.

Subscribe to Raspberry Pi Tutorials and don't miss any new Tutorial!