Go Down

Topic: Library for Distance Sensors (Read 12785 times) previous topic - next topic


Dec 19, 2011, 10:44 pm Last Edit: May 21, 2012, 10:27 pm by doggenj Reason: 1
I am starting this topic to inform you about a small lookup table based library for the Sharp GP2Y0A21YK analog IR distance sensor.
The main goal is to provide a library that simplifies the usage of this particular sensor in Arduino projects.


  • Download the source

  • Place the DistanceGP2Y0A21YK folder in your Arduino1.0+ "libraries" folder

  • Open example sketch: "file", "Examples", "DistanceGP2Y0A21YK", "Centimeter" (or "Voltage" or "Raw")

  • Connect the analog sensor to port A0 (and connect Vcc and GND)

  • Compile & upload code

  • Sensor data should be arriving over the serial port




So this lib is pretty usefull. But i wonder, how can I interpret a distance measurement with a displacement at the same time? Like having a xx mm/sec or  inch/min. Just like a feed rate
If you may have a hint, i'm stall on this and have not much idea.

thanks again


Jan 21, 2012, 01:15 pm Last Edit: Jan 21, 2012, 01:17 pm by doggenj Reason: 1
Depending on your program/goals you could:

  • Sample the sensor from time to time and use "millis()" to calculate the time that has passed and then calculate the average displacement

  • Sample the sensor using fixed timing, e.g. 10 samples per second, using a periodic wake-up of the board, and then calculate the average displacement. Periodic wake-up can be achieved using this nice library: https://github.com/rocketscream/Low-Power

I would prefer the second option.


Hi doggenj,

good work,

Have you checked my multimap article - http://arduino.cc/playground/Main/MultiMap - Wrote that because the standard map function could not handle the non-lineair function.
Multimap uses two small lookup tables with interpolation between points.

You could try to make your lib more generic by keep the device specific stuff separate.

2 cents

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)


Jan 22, 2012, 08:45 pm Last Edit: Jan 22, 2012, 08:47 pm by doggenj Reason: 1
Is was not aware of your multimap code, but it might be interesting to add your approach as an extra option since it will result in a smaller code size, at the expense of some execution speed.

What you are doing in the multimap function is almost what I did in a spreadsheet to calculate my LUT values.
I measured some values and calculated the intermediate points using two polynomial approximation of the tranfer function. (one for 80 to 20 cm, an other one for 20 to 5 cm).
You can find the (messy) spreadsheet here: (the comments are in Dutch): http://code.google.com/p/gp2y0a21yk-library/source/browse/Calculations/CalculationsDistanceSensorTransferfunctionLUT.xls

How exactly would this make the lib more generic? Since the only hardware specific code is the actual LUT.
I plan to make one generic "DistanceSensor" lib, that supports other distance sensors. (e.g. http://code.google.com/p/srf04-library ('sonar' sensor))


How exactly would this make the lib more generic? Since the only hardware specific code is the actual LUT.

That means the lib should have a reference to an external LUT in the constructor.  (Could not open the spreadsheet BTW..)

What do you think of an option for runtime calibration?
Or a separate sketch that can generate the LUT?            put the sensor at 10 cm press button, 20 cm press button etc

I plan to make one generic "DistanceSensor" lib, that supports other distance sensors.

Great , think the multimap approach can help to keep the different LUT's small !
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)


Jan 22, 2012, 10:05 pm Last Edit: Jan 22, 2012, 10:07 pm by doggenj Reason: 1
direct link to the spreadsheet: http://gp2y0a21yk-library.googlecode.com/hg/Calculations/CalculationsDistanceSensorTransferfunctionLUT.xls
(works fine for me using LibreOffice)

The option for runtime calibration is planned for "Version 0.6: Compare different sensors, calculate replacement LUT (at runtime) based on calibration points" (copy past from header file :-) )

I currently have 5 sensors that are tied together sitting on my desk.
My plan is to do this runtime testing/calibration using 5 sensors to check for inter-sensor differences.
I haven't done the experiment yet because I needed some extra wires + breadboard, to connect them all at the same time.

It think the best approach would be conditional compilation with 3 options:

  • speed optimized: my current code

  • code size optimed: the multimap version using your approach

  • default: 4(?) bit LUT combined with multimap 

A more (too?) complex solution might be:

  • a standard generic LUT: 8 bits

  • + a 'differential' LUT for each individual sensor: using calibrated values: 4 bits

Lots of possibilities...


I have a semi-decent version of the generic DistanceSensor class.
(warning: the code compiles but is not yet tested using actual sensors)

Top level class: DistanceSensor
Level1 classes: hardware type/group specific code: class for analog sensors and class for timing based/acoustic sensors (AccousticDistanceSensor, AnalogDistanceSensor)
Level2 classes: sensor type specific code:  (DistanceSRF04, DistanceGP2Y0A21YK)

Now adding other sensors with different LUTs or timing options should be straightforward: just add a new "level2" class.

Source: http://code.google.com/p/arduino-distance-sensor-library/

Doxygen documentation: http://arduino-distance-sensor-library.googlecode.com/hg/Documentation/latex/refman.pdf

Inheritance diagram:


Update: The current version provides a unified interface for four sensors:

SRF04 & SRF05 Ultrasonic Ranger
Sharp GP2Y0A21YK IR Distance sensor
Sharp GP2Y0A41SK IR Distance sensor

This version no longer uses a LUT, but calculates the transfer functions of 1/D at runtime (they are nearly linear).

Inheritance diagram:


Hey, great work.
Can I use the GP2Y0A21YK library with Arduino due ?



The version with the LUT is AVR specific, but the generic library that calculates 1/D should work just fine on the Due.



Hi Doggenj, I am newbi in Arduino Program.
Now I want to make detection obstacle using arduino and 3 pieces IR Sensor GP2Y0A21YK.
the IR will be working one by one by them self on 1 board Arduino.
They can detect the obstacle when IR near of the obstacle.

I hope you will answer me with fast. Thank you very much.

Go Up