How can you measure distance with light?
Note: Apologies to OddBot. It seems I posted something he has already explored. My mistake for not reading his page(s) more carefully. I thought they were just proximity detectors, but he is actually using analog reading. Find his page here: http://letsmakerobots.com/node/2907
which was the predecessor of his compound eye: http://letsmakerobots.com/node/10822
Added note: Let me clarify something. Because of some of the responses I've gotten, I wish to mention that this method will NOT work perfectly in all conditions. It will work in places where you have obstacles that are smooth and will reflect back light. Just as a line-follower trying to find its way on a shag carpet without lines, it will not work so well against uneven surfaces that do not reflect light back evenly.
However, it WILL work in many common situations, and may save you money where you are able to use it, [especially if you turn up the brightness of the infrared LED either by additional current (lower series resistance) or by using more than one LED as the light source and adjusting your reading accordingly.
How does an IR distance detector (such as Sharp) work? Or more specifically, is it possible make a cheap sensor that uses a simple method to measure distance so we do not need to buy the more expensive Sharp sensors?
Some people think Sharp sensors work like radar or lidar, measuring the time that it takes for a light beam to hit a target and bounce back.
However, to find distance by measuring the time it takes for a pulse of light to go out to an object only a few centimetres away, and reflect back to a detector requires a device capable of timing in fractions of a nanosecond (less than one thousand millionth of a second). This method will not work with a microcontroller. Normal microcontrollers cannot measure time less than a microsecond, which is a thousand times greater than what you need for such measurements. Light travels roughly 1 foot (or 30 cm) in a nanosecond or 300 meters per microsecond. If you were measuring distance in kilometres, you could do it with a microcontroller, but anything less, —no.
Sharp sensors measure distance by triangulation, using a PSD (position sensitive device) to figure out the angles that light travels to its target and back and contain a precision lens that bends the light further to get a good measurement.
This is one type of commercially available PSD.
A PSD is a special detector somewhat similar to a PIR, but the output will vary according to where the light hits the sensor. Thus it is immune to brightness/darkness effects. It will work no matter how much light is reflected back to the sensor. The surface of the sensor can be thought of as having a series of light sensitive bands or islands. If the light hits in the center of the sensor you will get a balanced reading at the outputs. As the light strikes further from the center the output will change indicating the angle at which the light came in.
Thanks to Merser's investigation, it appears that Sharp sensors are indeed PSDs. A PSD is essentially a CCD array, such as found in a camera to take pictures. In the case of a PSD, the various pixels in each row are used (with a light-bending focusing lens) to determine a distance mathematically according to which pixels are lit up by light bouncing back to the sensor array.
>>Regardless of the actual method used by Sharp, the method I give here can be used to some success employing a method which is much cheaper and that you can make at home in your own robot workshop. You will use a sensor arrangement like what you use for proximity detectors..
This new detector will contain a simple light-detecting diode, (which has no way of telling angles). When building this new sensor, you will mount an infrared LED and an infrared sensitive detector solidly in place on a backing such as a piece of circuit board, but with a slight inward angle dependant on the range the sensor is meant for. (A new job for our robot-tested standby, hot-glue?)
So what is this simpler method of measuring distance using the light?
Since the PSD is basically a camera pickup, all the pixels are the same, so you can ignore the brightness of the light hitting the sensor and just measure the angle by reading out where in the matrix the light is hitting. This can be quite accurate, but is hard to duplicate in a home robot-shop environment unless you actually use a small camera device and video processing to get your answers.
We are looking instead at something much simpler that you can do at home, will be cheap and is sufficiently accurate for "most" robot projects. We are all familiar with the "funny response curve" we get using those "Sharp-type" devices.
Here is what this curve tells me.
First of all the useful distance for the sensor in this diagram is given as 10 cm to 80 cm. At less than 5 or 6 cm the input of light is being blocked by the plastic ridge which is intended to prevent light from the LED from directly hitting the detector. When the sensor tries to respond to an object closer than that distance, the light is blocked more and more, the closer the object is.
Since it appears Sharp is actually using a PSD device, the amount of light hitting a pixel should not matter. The PSD should only answer the question, "Is light hitting that pixel or not?" If it is, then the light is coming in at a certain angle in order to hit that pixel and therefore the distance is "XX". Because of that I do not see why the curve should look the way it does. Compare the response curve drawing to an illustration of the inverse square law. If we ignore the part of the curve where the light is being partially blocked by the plastic case, we see that the curves are "essentially" identical.
[They may not be absolutely identical because of the actual response of a photodiode when light of various levels hits it, or the response of other components in the circuit.] Why are these curves even close? With a PSD pickup, there is no reason for a curve at all. The PSD in a Sharp appears to be one with enough external leads that it can tell where in the array the light is hitting and as I mentioned, it is either hitting certain pixels or it is not. The response should be a straight line. (I can only presume that this curve is introduced due to some design oddity. (Perhaps in the way they average the distance readings when light is hitting more than one pixel.)
- - - - - - - - - - - - -Plot of the Inverse Square Law - - - - - - - - - - - - - - -
So why the similarity? What is this inverse square law thing, anyway?
- - - - - - - - - - This example shows why the amount of light relates to the distance. - - - - - - - - - -
When a bright light (in this case infrared light) hits a regular photo-detector, the resistance of the detector decreases to a very small value. On the other hand, if the detector is completely dark, then it's internal resistance is quite high. By varying the amount of light hitting the detector, you will vary the internal resistance at the same time. As shown in the following illustration, when the distance light travels is doubled the area covered by that same light is quadrupled (multiplied by four), so the light is only one–fourth as bright at a certain spot. If the first distance (shown by the letter 'r') were 10 cm, then at 20 cm (2r) the brightness would be only one quarter what it was at 10 cm. At 40 cm (4r) the brightness would be only one sixteenth what it was at 10 cm. By the time you get out to 80 cm (or 8r) since 8x8=64, the light will be only one sixty-fourth as bright. As you can see this will give a wide range of readings for a small difference in distance. However, you will also notice that since the amount of light is changing by the square of the distance, when you plot it out, the graph will be a curve rather than a straight line. In fact the curve will look like those above.
The working part of our simple sensor contains a light emitter in the form of an infrared LED and a light detector in the form of an infrared-sensitive photodiode (or phototransistor, etc.). Infrared is used because it tends to reflect back fairly evenly from surfaces of various visible light colours.
We have used an LED and photo detector pair before in making a proximity detector, so how do we use the same components and suddenly make it detect distances? That is simple. We hook the output of the detector to an analog input on our micro-controller, instead of a digital input. Hooked to a digital input we get only a yes/no or high/low response, but if we tie it to an analog input, we find a broad range of numbers. All that is needed then it to convert these output values into distances. I seem to recall that we have to do that with the Sharp sensors, don't we?
Sosee, it really is simple after all. There is nothing new to learn... Just hook your detector output to an analog input rather than a digital one. Now why didn't we think of that before?
In the drawing above, I presented a sampling of ways a light sensor may be connected to the input of a microcontroller. One thing I should point out here is that you will likely need to alter the 10 K resistors in the drawing above to different value. You may want to experiment by putting a 50KΩ to 100KΩ potentiometer in its place until your distances are falling in an acceptable range. Here is what I mean. The amount of light coming from the LED will result in the light hitting the photo detector falling different places in the voltage range. It may take you several tries to get the values correct, so the output from the sensor falls in a spot where the curve falls within the right range to give useable readings, —ones that may be easily translated into proper distances.
If you do not have the exact current through the LED correct, you can fix it in software, by adjusting the readings.
What is an easy way to do that? –By making test measurements. Set up your test circuit with the LED and the light detector (whether diode, junction transistor, fet or ldr) tied to an analog input of your µController. Using a ruler, set a piece of paper or other object exactly at a certain distance (such as 10 cm or 2 inches). Read the value at the analog input. Move the object to a different distance and take another reading. Do this as often as you like and get enough points to plot the results on a graph. From the Inverse Square Law curve in the diagram above, you know what your plot should look like, but this will give you the exact plot for your new sensor. You may have to add or subtract a value to make your readings come out in the proper range, and apply a multiplier. This is done in programming —but isn't that more satisfying than paying €15 / $15 / £10 and more with shipping?
If you are in an area where there is a lot of background infrared light (such as in direct sunlight) that may give you problems. There are ways of minimizing that. One easy way to minimize the effect of background light is by taking one reading of the light level with the LED off, turn the LED on, and then take another reading. This can be done quite quickly in programming. With the LED off, you get the background light level value, so all we have to do is take that amount away from the reading with the LED on to get a valid value to convert to a distance. Once you correct for the background light, your readings should return to (or at least approximate) the curve you already plotted although there may be more error with excess background lighting. You might also increase the current going to your LED to increase the light output, so it shows up better against a bright background. Just remember to adjust the readings if you change the light level.
That is really all we have to do.
Another method I may give more time to later involves flashing the LED on and off at a set rate (frequency) and then checking the incoming signal at the detector for light at that same frequency.