Wednesday, August 14, 2013

Testing Distance Sensor

We have tried to test and calibrate the distance sensor (SHARP 2Y0A21) using Arduino. Based on the lab test of a specific detector, the sensor data is noisy sometimes and only works for distance from 5 cm to 40 cm. We added a filter using median data of readings. And, we convert the readings to actual distance by using a quadratic regression curve fit. The test result is not perfect but acceptable. The Arduino code is attached below.

/********************************************************************
  Blinking two LED repeatly for visual effect.
  Measuring distance using SHARP 2YOA21 IR distance detector.
  Based on the lab test, the distance detector works between 5-40 cm.
*********************************************************************/

// pin 10 & pin 13 have LEDs connected.
int led1 = 13;
int led2 = 10;

// pin A2 has an distance detector connected.
int IRSensor = A2;

// number of readings used to smooth the sensor data.
const int numReadings = 5;

// distance detector readings array
int readings[numReadings];

// distance array for comparison
int IRState[numReadings];

// median of the "numReadings" distance detector readings
int IRMedian;

int i, j;
int tmp;
int distance;

// the setup routine runs once when you press reset:
void setup() {               
  // initialize the digital pin as an output.
  pinMode(led1, OUTPUT);   
  pinMode(led2, OUTPUT);  
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  // make the IRSensor's pin an input:
  pinMode(IRSensor, INPUT);
  // initialize arrays
  for (i = 0; i <
numReadings; i++)
  {
    readings[i] = 650;
    IRState[i] = 650;
  }
}

// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led1, HIGH);   // turn the LED on (HIGH is the voltage level)
  digitalWrite(led2, LOW);   // turn the LED on (HIGH is the voltage level)
  delay(20);               // wait for 0.02 second
  digitalWrite(led1, LOW);    // turn the LED off by making the voltage LOW
  digitalWrite(led2, HIGH);    // turn the LED off by making the voltage LOW
  delay(20);               // wait for 0.02 second
 
  // read the input pin and put the value at the end of the readings array:
  for (i = 0; i < numReadings - 1; i++)
    readings[i] = readings[i+1];
  readings[numReadings - 1] = 650 - analogRead(IRSensor);
 
  // copy readings array to IRState array for comparison
  for (i = 0; i < numReadings; i++)
    IRState[i] = readings[i];
 
  // bubble sort IRState array
  for (i = 0; i < numReadings - 1; i++)
  for (j = i+1; j < numReadings; j++)
    if(IRState[i] <= IRState[j])
    {
      tmp = IRState[i];
      IRState[i] = IRState[j];
      IRState[j] = tmp;
    }
  // find median 
  IRMedian = IRState[numReadings/2]; 
 
  // converting the sensor readings to distance through a quadratic regression curve fit
  distance = 0.000162059 * (float) IRMedian * (float) IRMedian - 0.0290382 * (float) IRMedian + 7.17082;

  // Print out the distance on serial port
  Serial.println(distance);
  delay(1);        // delay in between reads for stability
}

No comments:

Post a Comment