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
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:
- GP2Y0A02YK0F (20cm – 150cm)
- GP2Y0A41SK0F (4cm – 30cm)
- GP2Y0A21 (10cm – 80cm)
- GP2Y0A710K0F (100cm – 550cm)
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:
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:
|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:
„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://github.com/doceme/py-spidev cd py-spidev/ sudo python setup.py install
Now that we have all the needed packages installed, we can create the script to measure the distance.
sudo nano ir_distance.py
The script has the following content:
spi = spidev.SpiDev()
val = spi.xfer2([1,(8+channel)<<4,0])
data = ((val&3) << 8) + val
if __name__ == "__main__":
dist = 16.2537 * v**4 - 129.893 * v**3 + 382.268 * v**2 - 512.611 * v + 301.439
print "Distanz: %.2f cm" % dist
We can do it now with (
sudo python ir_distance.py), 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 😉