Tuesday, September 30, 2008

Interpreting Sharp IR sensor values

We're using the Sharp 2Y0A021YK IR sensors (10cm-80cm), but unfortunately it's not a linear output.  The datasheet has a graph, but it's print-only, they don't give you either values or a formula.

So, I plotted out about 50 points, put them into an excel spreadsheet, built a XY chart out of them, then used "Add Trendline" to get a line that fit the graph, and then got the formula from that.  So now we have the function that converts the voltage the sensor puts out into the actual distance (sure would be nice if this were on the datasheet)

dist_mm = 1085534.81 * (float)pow((float)voltage_mv, -1.2);

Where voltage is in in milivolts, and the returned distance is in milimeters.

Really sharp, put this on your datasheet!

Kallahar

1 comment:

Anonymous said...

Hello, thanks for you approximation of sensor readings. Im using this sensor for few months and you article (and getSharp2Y0A021YK method) helped me a lot.

At this moment, my sketch size is near its limit. I tried to find, what can be optimized - and getSharp2Y0A021YK was the first candidate. Im using method pow() just inside this method and it takes too much memory. Using following code, I downsized sketch by 870 bytes (10% of 8k atmega8 memory just by not using pow!):

unsigned int getSharp2Y0A021YK(int pin)
{
// read Sharp 2Y0A21 sensor on analog pin "pin"
// Sharp IR Sensor: GP2Y0A02YK, marked 2Y0A21 on the unit
// non-linear output
int dist_mm = 0;
int voltage_mv = analogRead(pin) / 1023.0 * 5000; // 0v = 0, 1024 = 5v

// convert voltage to non-linear dist_mm in meters
// old way: dist_mm = 1085534.81 * (float)pow((float)voltage_mv, -1.2);

dist_mm = dist_mm/4.;
for(pin=0;pin<=25;pin++)
{
dist_mm = (4*dist_mm + voltage_mv/(dist_mm^4))/5.;
}
dist_mm = 1085534.81 * 1./(voltage_mv*dist_mm);

// some limits
if (dist_mm < 100) { // close limit
dist_mm = 100;
} else if (dist_mm > 800) { // far limit
dist_mm = 800;
}
return dist_mm;
}


It is nasty, bruteforce solution, but it works :-). One drawback is cpu consumption - it is little bit slower than pow method, but is doesnt play role in my case.

Hope this helps anybody.

Marek