As shown in figure below is the distance measuring characteristic of the Sharp GP2Y0A21 sensor. The voltage produced by the sensor is nonlinear with respect to distance, eg. the sensor readings may be 1, 2, and 3, but the distance might be 10cm, 30cm, and 80cm.
Furthermore, the output is non-continuity, the Sharp GP2Y0A21 sensor do not work properly at very close range, eg. smaller than 8cm.
Eliminate noises
The Sharp GP2Y0A21 sensor can produce noises (spikes) at its output, a simple solution is to add two capacitors in parallel (100nF & 10-100µF) between VCC and GND. The capacitors must be connected as close as possible on the distance sensor as shown in figure below.
Interfacing Sharp GP2Y0A21 sensor with Arduino
Interfacing to most microcontrollers is straightforward, the only analog output from the Sharp GP2Y0A21 sensor can be connected to an analog-to-digital converter for taking distance measurements, here we use an Arduino to read the value from the Sharp GP2Y0A21 sensor.
/* Read values from Sharp GP2Y0A21 distance sensor and output to serial Sharp Distance Sensor GP2Y0A21 (10-80cm) 3.1V at 10cm to 0.3V at 80cm */ int ir_sensor = A0; void setup() { //initialize serial communications at 9600 bps Serial.begin(9600); } void loop() { int sensor_value = analogRead(ir_sensor); //read the sensor value Serial.println(sensor_value); //print the sensor vlue delay(500); //delay 500ms (0.5 second) }
Since there is sensor noise, ten readings in the same exact situation could give you ten near yet different values. We can smooth this by taking an average of multiple readings. Code below get 10 readings from the distance sensor and return its average.
int ir_sensor = A0; void setup() { Serial.begin(9600); } void loop() { Serial.println(value_average(10)); //loop 10 times and get its average delay(500); } int value_average(int average_count) { int sum = 0; for (int i=0; i<average_count; i++) { int sensor_value = analogRead(ir_sensor); sum = sum + sensor_value; } return(sum/average_count); }
The Uno has 6 analog inputs, labeled A0 through A5, each of which provide 10 bits of resolution (i.e. 1024 different values). By default they measure from ground to 5 volts. Therefore 5V may only read as 1023, 2.5V may read as 512 and so on. Following code convert 10 bits value to voltage.
int ir_sensor = A0; void setup() { //initialize serial communications at 9600 bps Serial.begin(9600); } void loop() { int sensor_value = analogRead(ir_sensor); //read the sensor value //convert to voltage ranged from 0V to 5V int voltage = map(sensor_value, 0, 1023, 0, 5); //0V=0, 2.5V=512, 5V=1023 Serial.println(voltage); //print the sensor vlue delay(500); //delay 500ms (0.5 second) }
The above example only shows four different values (voltage), i.e 0V, 1V, 2V & 3V, you should map to a bigger value in real life, eg. map(sensor_value, 0, 1023, 0, 255)
Equation converting readings to distance (cm)
To calculate the range (in centimeters) based on Sharp GP2Y0A21 characteristic, use this equation:
int ir_sensor = A0; void setup() { //initialize serial communications at 9600 bps Serial.begin(9600); } void loop() { int sensor_value = analogRead(ir_sensor); //read the sensor value int distance_cm = pow(3027.4/sensor_value, 1.2134); //convert readings to distance(cm) Serial.println(distance_cm); //print the sensor value delay(500); //delay 500ms (0.5 second) }
Code below get 100 readings from the distance sensor and return its average.
int ir_sensor = A0; void setup() { //initialize serial communications at 9600 bps Serial.begin(9600); } void loop() { int distance = average_value(100); //loop 100 times and get its average Serial.println(distance); //print the sensor value delay(500); //delay 500ms (0.5 second) } int average_value(int average_count) { int sum = 0; for (int i=0; i<average_count; i++) { int sensor_value = analogRead(ir_sensor); //read the sensor value int distance_cm = pow(3027.4/sensor_value, 1.2134); //convert readings to distance(cm) sum = sum + distance_cm; } return(sum/average_count); }