Sharp IR proximity sensors are cheap and easy to use, but do not produce linear output. NOTE: this is a different issue than noise or jitter in the sensor data. That can be fixed with capacitors to ensure stable power – read this for explanation.
Here is one simple conversion to linear for the commonly used GP2YOA1YK sensor, accuracy is about +/-5%, but its drawback is that pow() is a slow function on the Arduino:
// Linearize Sharp GP2YOA1YK
float distance = 12343.85 * pow(sensorValue, -1.15) // centimeters
Here is a library that uses a lookup table – a much faster method because no calculations are done on the fly, it’s all done beforehand (you can see the list if you look inside DistanceGP2Y0A21YK_LUTs.h (LUT = Look Up Table) – http://code.google.com/p/gp2y0a21yk-library/.
Here is an equation tweaked for the longer range Sharp GP2Y0A02YK:
// Linearize Sharp GP2Y0A02YK
float distance = 30431 * pow(sensorValue, -1.169) // centimeters
// *or: *
float distance = 21208 * pow(sensorValue, -1.251) // inches
Here is a similar conversion function for the Sharp GPD212: http://www.arduino.cc/playground/Main/ReadGp2d12Range
If you measure values yourself, you can make an array of values and this is a very efficient way to look up those values (an example is included for the Sharp 2Y0A02): http://arduino.cc/playground/Main/MultiMap
Here is another solution that gives you a universal function that can be calibrated for different sensors (more info):
typedef const struct
{
const signed short a;
const signed short b;
const signed short k;
}
ir_distance_sensor;
// Parameters for GP2Y0A21YK sensor
const ir_distance_sensor GP2Y0A21YK = { 5461, -17, 2 };
// Converting the values of the IR distance sensor to centimeters
// Returns -1 if the conversion did not succeed
signed short ir_distance_calculate_cm(ir_distance_sensor sensor,
unsigned short adc_value)
{
if (adc_value + sensor.b < 0)
{
return -1;
}
return sensor.a / (adc_value + sensor.b) - sensor.k;
}
Here is another accurate function that also accounts for how curve changes when <10cm, if you have other sensors detecting that (normally objects that close give unusable values with this sensor): http://clockfort.com/code/CSHSharpIRSensor/CSHSharpIRSensor.cpp
Hi Eric,
I am a student of NYU working on proximity sensor to detect human at certain distance. Your libraries helped for reference in my project. I have used your code for calibration but I am not getting good results. I have given 5.3 V power supply externally to the GP2YOA1YK and tried with Arduino Vcc also but not getting correct distance values. I was unable to understand how to set up a look up table which you set for your sensor. Please help me to get calibrated value of my sensor. Thanks
Reply back on my mail: adg427@nyu.edu
LikeLike
Unless you have an extremely performance sensitive application, don’t bother with a lookup table. For the sensor you’re using, just use the simple conversion referenced above:
float distance = 12343.85 * pow(sensorValue, -1.15) // centimeters
If you still want to use a lookup table but confused about how to implement it, try this library https://code.google.com/p/gp2y0a21yk-library/
LikeLike