In this tutorial you will learn how to use the GP2Y0E03 Infrared Distance Sensor with an Arduino or any other common microcontroller (ESP32/ESP8266) to measure distances up to 50 cm.
The GP2Y0E03 uses the reflection of IR light and triangulation to determine the distance to objects. Typical applications are cleaning robots, touchless switches and gaming machines.
Required Parts
Firstly, you will need an GP2Y0E03 Distance Sensor. Secondly, you will need a microcontroller. I used an Arduino Uno for this project, but any other Arduino or any ESP32/ESP8266 will be fine as well.
GP2Y0E03 Distance Sensor
Arduino Uno
USB Cable for Arduino UNO
Dupont Wire Set
Breadboard
Makerguides.com is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to products on Amazon.com. As an Amazon Associate we earn from qualifying purchases.
Features of GP2Y0E03 Distance Sensor
The GP2Y0E03 is a small sensor that use Infrared (IR) light and triangulation to measure the distance to an object. The sensor sends out an IR pulse and depending on the distance of the object, the reflected pulse appears shifted on the detector plate. See the picture below for illustration.
The measurement range is from 4 to 50 cm with a refresh interval between measurements of about 40ms. The supply voltage for the GP2Y0E03 sensor is 2.7 to 5.5V and the average current consumption is 26mA.
Pinout of GP2Y0E03
The GP2Y0E03 sensor is part of the family that includes the GP2Y0E02A and GP2Y0E02B sensors. However, the GP2Y0E03 is the only one that has an analog and a digital output (I2C). The picture below shows the pinout of the sensor.
- Pin 1 is the positive power supply (2.7 to 5.5V).
- Pin 2 is Vout(A) is the analog output that returns a voltage inversely proportional to the distance.
- Pin 3 is ground (GND) of the power supply.
- Pin 4 is VIN(IO), the supply voltage for the I2C interface, which must be 1.8 and 3.3V.
- Pin 5 is GPIO1, which can be used to enable or disable the sensor.
- Pin 7 and Pin 6 are the SDA and SCL lines of the I2C interface.
The sensor typically comes with a 7 pin Japanese Solderless Terminal (JST) Connector and cables that fit most Sharp distance sensors. Note, however, that the color coding of the wires is misleading. For instance, black is NOT ground and red is NOT positive power. See the picture of the sensor cables below:
Internal Schematic of GP2Y0E03
The Internal Schematic Diagram of the GP2Y0E03 below shows the IR LED with its LED driver that is responsible for sending out the IR pulse. The CMOS Imager (detector) receives the reflected pulse, and an AD converter converts into a digital signal that is processed by the Digital Signal Processor (DSP).
The DSP computes the distance to the object and reports it via the I2C interface (SCL, SDA). In addition, this digital distance measurement is converted to an analog signal via the DA Converter and sent to the Vout output pin.
Specification of GP2Y0E03
According to the datasheet the main features of the GP2Y0E03 Sensor are as follows:
- Built-in signal processing circuit (DSP)
- Distance measuring range : 4 to 50 cm
- Low voltage operation : Min 2.7V
- Compact size (16.7 × 11.0 × 5.2mm)
- Digital(I2C) and Analog output type
I found that the sensor can actually measure distances between 3cm up to 60cm or a bit more. On the other hand, the measurements are not very accurate, especially when compared to Time-of-Flight Laser range distance sensors.
For more details have a look at the datasheet and the application notes of the GP2Y0E03 linked below:
Connecting the GP2Y0E03 to Arduino
The GP2Y0E03 offers a digital (I2C) output and an analog output. You could use either of them but in the wiring diagram below I connected both, so that we can compare the distances reported via the digital or the analog interface.
For the I2C interface we connect the SDA line by connecting A4 of the Arduino with pin 7 of the GP2Y0E03. For the SCL line connect A5 with pin 6. See the picture below.
For the analog output (vout), we connect pin 2 of the GP2Y0E03 with A3 of the Arduino. You could use any of the other remaining analog inputs (A0…A2) as well but you will have to adjust the code that I show you in the later sections.
Next we connect the power supply. We start be connecting ground (GND) of the Arduino with pin 3 of the GP2Y0E03. Finally, we connect 3.3V of the Arduino with pin 5 (GPIO1), pin 4 (VIN(IO)) and pin 1 (VDD).
Note that according to the datasheet of the GP2Y0E03, VDD of the GP2Y0E03 can be up to 5.5V but VIN(IO) can only be up to 3.3V (see operation conditions below). We therefore need to use 3.3V for VIN and VIO. Though I tried 5V and the sensor worked and survived (not recommended, however).
The GPIO1 (pin 5) input allows you to enable (active) or disable (standby) the sensor. You could connect GPIO1 to a digital output of the Arduino to switch it on or off. This is useful if you want to connect multiple GP2Y0E03 sensors with the same I2C address to the same I2C interface, or if you want to preserve power between measurements.
In standby mode (disabled) the GP2Y0E03 consumes only 20µA, while on average it consumes 26mA. However, the datasheet states that you need a power supply that can deliver up to 150mA since the IR Led pulse current is 100mA.
Code for measuring distance with GP2Y0E03
In this section we will write some simple code that reads the distances the GP2Y0E03 measures and prints them to the Serial Monitor.
Install GP2Y0E03 library
Unfortunately there is no Arduino library for GP2Y0E03 Sensor (as of Oct 2024). So, I implemented my own. To install this GP2Y0E03 library go to the GP2Y0E03_arduino_lib repo and click on the green “Code” button. Then click on “Download Zip” as show below:
Then go “Sketch” -> “Include Library” -> “Add .Zip Library..” and select the “GP2Y0E03_arduino_lib-main.zip” file you just downloaded before:
Alternatively, you can just download the entire code of the repo, zip it and then include the library in the same way as described above. Or you just copy an paste the GP2Y0E03.h and the GP2Y0E03.cpp files into your project folder.
Code to measure distances with GP2Y0E03
The following example code shows you how to measure distances with the GP2Y0E03 sensor using its digital and its analog output at the same time.
#include "GP2Y0E03.h" GP2Y0E03 sensor = GP2Y0E03(); void setup() { Serial.begin(9600); sensor.init(A3); } void loop() { Serial.print("digital:"); Serial.println(sensor.distDigital()); Serial.print("analog:"); Serial.println(sensor.distAnalog()); Serial.println(); delay(1000); }
We start by including the GP2Y0E03 header file and creating the sensor object:
#include "GP2Y0E03.h" GP2Y0E03 sensor = GP2Y0E03();
The default 7-bit I2C address of the GP2Y0E03 is 0x40
. But you can also specify a different I2C address in the constructor GP2Y0E03(address)
.
In the setup
function, we initiate serial communication with a baud rate of 9600 and also initiate the sensor, with it is analog output (vout
) connected to the analog input A3 of the Arduino:
void setup() { Serial.begin(9600); sensor.init(A3); }
If you don’t want to use the analog output just initialize the sensor with init()
or init(-1)
. Also, if you need to use specific SDA and SCL pins on your microcontroller you can call init(vout, sda, scl)
or init(sda, scl)
.
In the loop
function we then call sensor.distDigital()
to read the distance via I2C, and sensor.distAnalog()
to read the distance via the analog output of the GP2Y0E03.
void loop() { Serial.print("digital:"); Serial.println(sensor.distDigital()); Serial.print("analog:"); Serial.println(sensor.distAnalog()); Serial.println(); delay(1000); }
We print both distances to the Serial Monitor and then wait for 1 second. Note that you should not poll faster than 40ms.
Output on Serial Monitor and Serial Plotter
The screenshot below shows some example output of the code on the Serial Monitor. You can see that the measured distances differ depending on the digital or the analog output. This is partly due to the calibration of the analog signal (more about that later).
If you play a bit with the sensor and code you will notice that a value of -1 is returned if you get too close to the sensor (< 3cm) or if the distance exceeds 60 cm.
The Serial Plotter shows that the distances returned by the analog and digital output are highly correlated but that the analog output shows outliers (negative distances):
Calibration of Analog Output
The digital output (I2C) of the GP2Y0E03 delivers the measured distance directly in centimetres. The analog output, however, just returns an output voltage (Vout) that needs to be calibrated to convert to a distance.
The following plot shows that there is an inverse relationship between Vout and the distance:
The GP2Y0E03 library performs this calibration internally but also allows you to adjust the calibration for your specific sensor or micrcontroller, if necessary. The process is as follows:
- Place the sensor at a small distance of an object, e.g. 3 cm (distMin)
- Record the corresponding Vout value, e.g. 448 (voutMin)
- Place the sensor at a long distance of an object, e.g. 30 cm (distMax)
- Record the corresponding Vout value, e.g. 289 (voutMax)
- Calibrate the sensor:
calibrateAnalog(voutMin, voutMax, distMin, distMax);
You can use the following code to print out Vout, where Vout is not a voltage but the digital value produced by the Analog-Digital Converter of the Arduino. Depending on your microcontroller and its AD converter you may read different values.
#include "GP2Y0E03.h" GP2Y0E03 sensor = GP2Y0E03(); void setup() { Serial.begin(9600); sensor.init(A3); } void loop() { Serial.println(sensor.vout()); delay(1000); }
Once you have the measurements for voutMin, voutMax, distMin
and distMax
, (lets say 448, 289, 3, 30) you can then calibrate the analog distance measurement as follows:
#include "GP2Y0E03.h" GP2Y0E03 sensor = GP2Y0E03(); void setup() { Serial.begin(9600); sensor.init(A3); sensor.calibrateAnalog(448, 289, 3, 30); } void loop() { Serial.print("analog:"); Serial.println(sensor.distAnalog()); delay(1000); }
Conclusions
In this tutorial you learned how to use the GP2Y0E03 Distance Sensor with an Arduino to measure distances.
The GP2Y0E03 is similar to other infrared distance sensors such as the GP2Y0A710K0F or the GP2Y0A21YK0F and uses triangulation to determine the distance to an object. However, in addition to the common analog output it also has a digital (I2C) output.
Compared to Time-of-Flight (ToF) laser range distance sensors such as the VL6180X, VL53L1X, VL53L0X or TOF10120, triangulation based sensors are less accurate and have a shorter range. Another, disadvantage is that they can’t measure distances when the object gets too close (e.g. < 3cm) and have difficulties with objects that are highly reflective (e.g. angled mirror). On the other hand, these sensors tend to be cheaper than ToF distance sensors.
If you have any questions feel free to leave them in the comment section.
Happy Tinkering ; )
Stefan is a professional software developer and researcher. He has worked in robotics, bioinformatics, image/audio processing and education at Siemens, IBM and Google. He specializes in AI and machine learning and has a keen interest in DIY projects involving Arduino and 3D printing.