The Sharp GP2Y0A02YK0F Proximity Proximity Sensor allows distance measurements between 20cm and 150cm. It is quite easy to get an Asian clone rated A02YK0 for less than €4. There are several Arduino libraries that support different versions of the Sharp sensor, but very often the returned measurement is totally incorrect for A02YK0 clones beyond 70cm. You will also be able to calibrate your sensor if the measurements are too random or not precise enough for your project.
We will see how to manually calibrate the proximity sensor to improve measurement accuracy. We will also see that it is possible to calibrate the sensor to measure a shorter distance below 120mm.
Measurement setup
The method consists in recording the analog signal returned by the sensor as a function of the distance with respect to a reference object (here a simple packaging box). A single meter will be enough.
The Sharp GP2Y0A02YK0F outputs an analog signal proportional to the measured distance. Connect the analog output (yellow wire) to an analog input of the Arduino (A0 for example).
Choice of the Arduino library
There are several libraries available from the Arduino IDE Library Manager. After having tested them all, I found that the zSharpIR library of zoubworldArduino (GitHub page) gave the best results
Code changes in the ZSharp library
The librarie ZSharp presents two errors that will have to be corrected manually before being able to use it. Open the Arduino -> Librarie -> ZSharp folder. Open the ZSharp.cpp file in a text editor (or the Arduino IDE) and make the following changes:
- Rename WMath.h to Math.h
- Comment the analogReadResolution (res) command at the end of the file
Save the changes
Proximity sensor test with ZSharp library
I made a series of measurements according to the distance. I simply measured the distance between the sensor and the wall in my office by varying the distance. To determine each point, I averaged 10 measurements at the frequency of one measurement per second.
Here is a small Arduino program to directly test your sensor using the ZSharp library. The sensor is connected to the A0 analog input of the Arduino or ESP8266.
Modify the model according to your sensor:
- 1080, GP2Y0A21YK0F (10 to 80 cm)
- GP2D12_24, 10cm to 80cm
- 20150, GP2Y0A02YK0F (20 to 150cm)
- 100500, GP2Y0A710K0F (100cm to 500cm)
- 430, GP2Y0A41SK0F (or GP2D120, 4cm to 30cm)
#include <ZSharpIR.h> #define ir A0 #define model 20150 //999 user type #define DELAY_REFRESH 1000 ZSharpIR SharpIR(ir, model); void setup() { Serial.begin(115200); } void loop() { // put your main code here, to run repeatedly: Serial.println(SharpIR.distance()); delay(DELAY_REFRESH); }
As you can see on the graph, the sensor, or at least the measurement returned by the ZSharp library, is correct up to 700mm. Beyond that, the measure drifts totally and becomes unusable.
Manual Calibration of Sharp GP2Y0A02YK0F
Let’s see now if it is possible to improve things.
Create a new Arduino sketch and paste the following code. It reads and displays on the serial monitor the analog signal returned by the proximity sensor. Vary the distance between an object (a wall for example) and the sensor every 100mm by noting the analog signal each time. Wait a few seconds for the signal to stabilize before proceeding to the next measurement.
void setup() { Serial.begin(115200); } void loop() { Serial.println(analogRead(A0)); delay(2000); }
Here is the signal reading according to the distance as well as the graphic representation of the latter. As you can see, the signal increases to an asymptote and then decreases again. This can be problematic in some projects. In this case, it would be very risky to use the sensor in a robotic project or autonomous car. It must be certain that the measured distance remains in the measuring range of the sensor.
Distance (mm) | Signal |
1500 | 70 |
1400 | 80 |
1300 | 90 |
1200 | 95 |
1100 | 112 |
1000 | 116 |
900 | 128 |
800 | 163 |
700 | 184 |
600 | 215 |
500 | 247 |
400 | 325 |
300 | 378 |
200 | 558 |
Using a spreadsheet (LibreOffice Calc for example), draw the curve of the distance according to the signal. Double click on the graph to edit it. Click on a point on the curve to add a regression curve.
Select the power type.
That is, we now have an equation that allows us to estimate whatever the analog signal is the distance in millimeters that separates the object from the sensor.
The measurement error can be estimated by theoretically calculating the distance that the equation returns as a function of the signal. Correct measurement should be obtained up to 1300mm (1.3m). Beyond, the signal is too weak for the equation to be precise.
Distance (mm) | Signal | Eval | Delta | Err |
1500 | 70 | 1 795 | 295,3 | 19,7% |
1400 | 80 | 1 566 | 166,0 | 11,9% |
1300 | 90 | 1 388 | 88,2 | 6,8% |
1200 | 95 | 1 313 | 113,4 | 9,5% |
1100 | 112 | 1 110 | 9,8 | 0,9% |
1000 | 116 | 1 071 | 70,7 | 7,1% |
900 | 128 | 968 | 68,1 | 7,6% |
800 | 163 | 756 | -44,1 | -5,5% |
700 | 184 | 668 | -32,3 | -4,6% |
600 | 215 | 569 | -30,6 | -5,1% |
500 | 247 | 494 | -6,0 | -1,2% |
400 | 325 | 373 | -26,9 | -6,7% |
300 | 378 | 320 | 19,6 | 6,5% |
200 | 558 | 215 | 14,6 | 7,3% |
Open ZSharp.cpp again and go right after the line
// Sort it sort(ir_val,NB_SAMPLE);
Add the following code, replacing the coefficient and the power corresponding to your curve
if (_model==999){ distanceMM=(int)(138773.464825 * pow(ir_val[0],-1.0233470)); }
Save and replace the model with 999 in the Arduino code before uploading.
Here is what I got by reproducing the previous tests. As one could sense, beyond 1300mm, the measurement is very random.
Here’s what it gives in numbers.
Distance (mm) | Sharp A02YK0 (calibrated) | Delta | Standart deviation |
200 | 212,0 | 12,0 | 0,32 |
300 | 283,4 | -16,6 | 1,84 |
400 | 384,4 | -15,6 | 7,52 |
500 | 481,7 | -18,3 | 11,81 |
600 | 606,3 | 6,3 | 28,02 |
700 | 721,2 | 21,2 | 44,27 |
800 | 805,9 | 5,9 | 59,35 |
900 | 954,0 | 54,0 | 92,49 |
1000 | 1 090,5 | 90,5 | 133,90 |
1100 | 1 131,6 | 31,6 | 128,11 |
1200 | 1 196,0 | -4,0 | 127,00 |
1300 | 1 221,7 | -78,3 | 31,91 |
1400 | 1 385,0 | -15,0 | 123,49 |
1500 | 1 412,3 | -87,7 | 84,00 |
Calibration test below 200mm
I then had fun to see if it was possible to calibrate the sensor for use below 200mm. The signal is exploitable up to 120mm then collapses.
Here, the sensor is sensitive from 20 to 120mm.
We will do the same as before but this time by choosing a polynomial curve of the second degree
Now we only have to write a small function that we can call each time we want to make a distance measurement with the Sharp sensor. Depending on the spreadsheet used, you can obtain a written equation according to the scientific notation. If you are angry with maths, you just have to shift the comma as many times as the number indicated on the power (here 10-4, so 4).
Then, we will just replace the x2 by x * x in the Arduino code which gives
1.936428309 · 10-4 x2 + 6.987226424 · 10-2 x – 14.32575223
therefore becomes
0.0001936428309 * x * X + 0.06987226424 * x – 14.32575223
Parentheses are not required in the Arduino code.
And that’s the finished function
float getDistanceSharp(){ int a0 = analogRead(PIN_GP2Y0A02YK0F); float dist = 0.0001936428309 * a0 *a0 + 0.06987226424 * a0 - 14.32575223; if ( dist < 20 ) { dist = 20; } return dist; }
That’s it, now you can integrate this Asian clone of Sharp GP2Y0A02YK0F into your robotic projects. As you have seen, the sensor tested has more limited features than the original version. Announced between 20 and 150cm, the signal becomes difficult to process beyond 130cm. Given the size similar to an ultrasound sensor HC-SR04, the interest of this clone Sharp GP2Y0A02YK0F is quite limited. In the next article, we will compare the Sharp A02YK0 with the ultra-sound HC-SR04 and VL53L0X which determines the distance by measuring the flight time of a laser.
- Get Started with HC-SR04, measure distance by ultrasound. Arduino code example
- ESP32, GPIO pins and associated functions. I/O, PWM, RTC, I2C, SPI, ADC, DAC
- ESP32-CAM pinout and equipments. ESP-EYE, AI Thinker, TTGO T-Camera, M5Stack Timer Camera …
- ESP32-CAM. Which model to choose? ESP-EYE, AI Thinker, TTGO T-Camera, M5Stack Timer Camera …
- M5Stack Atomic GPS. ESP32 TinyGPS++ tracker, GPX export on SD card, visualization on Google Maps or VSCode