Sunday, 03 November 2013 17:49

Sharp GP2Y0A21 IR distance sensors

Sharp GP2Y0A21 is an infra-red distance measuring sensor unit,  it is extremely effective, easy to use, very affordable and has low power consumption. specification as follow:

  • Distance measuring range: 10 to 80cm (4" to 32")
  • Operating voltage: 4.5V to 5.5V
  • Output type: Analog voltage
  • Average power consumption : 35 mA
  • Peak power consumption : about 200 mA
  • Output voltage differential over distance range: 1.9V 
  • Maximum allowable Angle : > 40 °
  • The frequency of updates/cycle : 25 Hz/40 ms

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.

Distance measuring characteristic

 

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.

Soldering capacitors onto IR sensor

 

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.

Connecting Sharp GP2Y0A21 sensor to Arduino  

  1. /*
  2.   Read values from Sharp GP2Y0A21 distance sensor and output to serial
  3.  
  4.   Sharp Distance Sensor GP2Y0A21 (10-80cm)
  5.   3.1V at 10cm to 0.3V at 80cm
  6. */
  7.  
  8. int ir_sensor = A0;
  9.  
  10. void setup() {
  11. //initialize serial communications at 9600 bps
  12. Serial.begin(9600);
  13. }
  14.  
  15. void loop() {
  16. int sensor_value = analogRead(ir_sensor); //read the sensor value
  17. Serial.println(sensor_value); //print the sensor vlue
  18. delay(500); //delay 500ms (0.5 second)
  19. }

 

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.

  1. int ir_sensor = A0;
  2.  
  3. void setup() {
  4. Serial.begin(9600);
  5. }
  6.  
  7. void loop() {
  8. Serial.println(value_average(10)); //loop 10 times and get its average
  9. delay(500);
  10. }
  11.  
  12. int value_average(int average_count) {
  13. int sum = 0;
  14. for (int i=0; i<average_count; i++) {
  15. int sensor_value = analogRead(ir_sensor);
  16. sum = sum + sensor_value;
  17. }
  18. return(sum/average_count);
  19. }

 

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. 

  1. int ir_sensor = A0;
  2.  
  3. void setup() {
  4. //initialize serial communications at 9600 bps
  5. Serial.begin(9600);
  6. }
  7.  
  8. void loop() {
  9. int sensor_value = analogRead(ir_sensor); //read the sensor value
  10. //convert to voltage ranged from 0V to 5V
  11. int voltage = map(sensor_value, 0, 1023, 0, 5); //0V=0, 2.5V=512, 5V=1023
  12. Serial.println(voltage); //print the sensor vlue
  13. delay(500); //delay 500ms (0.5 second)
  14. }

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:

 

  1. int ir_sensor = A0;
  2.  
  3. void setup() {
  4. //initialize serial communications at 9600 bps
  5. Serial.begin(9600);
  6. }
  7.  
  8. void loop() {
  9. int sensor_value = analogRead(ir_sensor); //read the sensor value
  10. int distance_cm = pow(3027.4/sensor_value, 1.2134); //convert readings to distance(cm)
  11. Serial.println(distance_cm); //print the sensor value
  12. delay(500); //delay 500ms (0.5 second)
  13. }

 

Code below get 100 readings from the distance sensor and return its average. 

  1. int ir_sensor = A0;
  2.  
  3. void setup() {
  4. //initialize serial communications at 9600 bps
  5. Serial.begin(9600);
  6. }
  7.  
  8. void loop() {
  9. int distance = average_value(100); //loop 100 times and get its average
  10. Serial.println(distance); //print the sensor value
  11. delay(500); //delay 500ms (0.5 second)
  12. }
  13. int average_value(int average_count) {
  14. int sum = 0;
  15. for (int i=0; i<average_count; i++) {
  16. int sensor_value = analogRead(ir_sensor); //read the sensor value
  17. int distance_cm = pow(3027.4/sensor_value, 1.2134); //convert readings to distance(cm)
  18. sum = sum + distance_cm;
  19. }
  20. return(sum/average_count);
  21. }

 

 

 

Read 14598 times Last modified on Tuesday, 05 November 2013 19:03

Leave a comment

Back to Top