I wrote a library just to handle this: - Arduino Playground - MultiMap -
my sample code - you need to update the arrays used as these are 20-150 cm, I callibrated the arrays with a measure stick (steps of 10 cm) you might do in in steps of 1 cm. but they don't need to be equidistant
//
// FILE: SharpDistanceSensor
// AUTHOR: Rob Tillaart
// VERSION: 0.1.01
// PURPOSE: Demo SHARP 2Y0A02 F 9Y - distance sensor
//
// HISTORY:
// 0.1.00 - 2011-01-22 initial version
// 0.1.01 - 2011-01-24 improved multimap
// Released to the public domain
//
#define RED 4
#define GREEN 5
void setup()
{
Serial.begin(19200);
pinMode(RED, OUTPUT);
pinMode(GREEN, OUTPUT);
analogReference(EXTERNAL);
Serial.println("Demo SHARP 2Y0A02 F 9Y - distance sensor");
Serial.println();
Serial.println("TIME\tRAW\tCM");
Serial.println();
}
void loop()
{
long raw = sharpRawAvg();
int mm = sharp2mm(raw);
Serial.print(millis());
Serial.print("\t");
Serial.print(raw);
Serial.print("\t");
Serial.print(mm);
Serial.print("\t");
for (int i=50; i<mm;i+=10) Serial.print("]");
if (mm > 750) digitalWrite(GREEN, HIGH);
else digitalWrite(GREEN, LOW);
if (mm < 850) digitalWrite(RED, HIGH);
else digitalWrite(RED, LOW);
// if (cm < 40)
// {
// digitalWrite(RED, HIGH);
// delay(cm/2);
// digitalWrite(RED, LOW);
// delay(cm/2);
// }
Serial.println();
}
///////////////////////////////////////////////////////////////////////
//
// SAMPLE FUNCTIONS
//
// multisample version
// as the sensor is not very steady in its reading
// doing 128 samples smooths the reading.
unsigned int sharpRawAvg()
{
unsigned long raw = 0;
for (byte i=0; i<32; i++)
{
raw += analogRead(A0);
//delay(1);
}
return raw/32;
}
// running average version
// use of 1024 == 10 bit shift
// + configurable ~1/1000
// + no floats
unsigned int sharpRawRA()
{
static unsigned long value = 0;
unsigned int a = 950;
value = (a * value + (1024-a) * analogRead(A0)) /1024;
return (unsigned int) value;
}
/*
TABLE OF MEASUREMENTS
CM RAW DELTA
150 91 91
140 97 6
130 105 8
120 113 8
110 124 9
100 135 11
90 147 12
80 164 17
70 185 21
60 218 33
50 255 37
40 317 62
30 408 91
20 506 98
*/
int sharp2mm(int val)
{
int out[] = {1500,1400,1300,1200,1100,1000,900,800,700,600,500,400,300,200};
// calibration 17-01
// internal reference 5,00 Volt
// factor 1.0
// range = 416
int in1[] = { 90, 97,105,113,124,134,147,164,185,218,255,317,408,506};
// (quick) calibration 24-01 (colder?)
// internal reference 5,00 Volt
// factor 1.0
// range = 396
int in2[] = { 87, 93,100,108,116,126,139,157,177,197,231,304,384,483};
// (quick) calibration 24-01
// external reference of ~3,07 V
// factor 1,6243 * _in2[]
// range = 644
int in3[] = {141,151,162,178,193,205,229,256,287,320,375,494,624,785};
return multiMap(val, in3, out, 14);
}
///////////////////////////////////////////////////////////////////////
//
// MULTILMAP FUNCTION
//
int multiMap(int val, int* _in, int* _out, int size)
{
val = constrain(val, _in[0], _in[size-1]);
// handle first value separately
if (val == _in[0]) return _out[0];
// search right interval
int pos = 0;
while(val > _in[pos] && pos < size) pos++;
// interpolate
return map(val, _in[pos-1], _in[pos], _out[pos-1], _out[pos]);
}
int sharp2cm2(int val)
{
val = constrain(val, 90, 506);
int _in[] = {0, 90, 97,105,113,124,134,147,164,185,218,255,317,408,506};
int _out[] = {0, 150,140,130,120,110,100, 90, 80, 70, 60, 50, 40, 30, 20};
int size = 15;
int pos = 0;
while(val > _in[pos] && pos < size) pos++;
return map(val, _in[pos-1], _in[pos], _out[pos-1], _out[pos]);
}