In past tutorials, we have covered temperature, color, time, direction, but never distance or proximity. I think I strayed away from this because most of the lower cost proximity sensors are pretty drop-dead-simple to use and thought it might not be that useful. But the time has come, I'm writing about some distance/proximity sensors. While using them is technically simple, I have 3 pretty different sensors that all have pros/cons, and none of them would make a very suitable replacement for the others, so maybe this will help you choose the right one if you find yourself in need.

All 3 sensors will be outputting an analog voltage that we will be reading with our Arduino. The typical Arduino has 6 "Analog In" pins located on them. These analog inputs act just like a voltage meter, sensing the voltage on that pin, and are actually 10 bit Analog to digital converters (ADCs). The 10 bit part is the resolution of the ADC. 10bit, or 2^10 = 1024 values. That means that when we read the voltage on that pin, 0-5v value will be translated to between 0 (0V) and 1023(5V). Read our wiki article for more information on ADCs. This resolution limitation of the Arduino's ADCs are a large part of the reason that analog sensors are often inferior to their digital counterparts. But, digital distance sensors are pretty expensive and hard to come buy. So...

The 3 sensors we will be going over are:
Maxbotix LV-EZ0 Ultrasonic Range Finder
Sharp GP2Y0A21YK Infrared Proximity Sensor
QRD1114 infrared emitter / Phototransistor combo

Maxbotix LV-EZ0

First up is the Maxbotix LV-EZ0 because of the undeniable popularity of it. It is an ultrasonic range finder meaning that it uses a projected sound and measures how long it takes for the sound to bounce off of an object and come back. The sound is ultrasonic so it can not be heard.

Hooking it up

Hooking up the LV-EZ0 up is like day one of the Arduino tutorial. The only confusing part is that it has many output types. What you want is the "AN" pin. That is the analog output. Connect this to an analog input as seen in the illustration.

What it is good/bad for

The LV-EZ0's range is really dependent on the size of the object - About 8ft for something the size of a finger, to over 20ft for something the size of a piece of paper. The best part is that the output is linear, so something that is 6ft way will output half that of something 12 ft away. This makes it very easy to read actual distance with it.

Maxbotix says the LV-EZ0 has a 1 inch resolution and a range of 0 - 254in meaning you could track something with 1in reliability over 254in of movement from the sensor. The reality is that this guy has trouble sensing distances under 1ft, and the output can be pretty shaky especially when trying to sense objects that are not perpendicular with the sensor.

Other options

Maxbotix makes a few different versions of this sensor with various beam widths. A narrow beam is better when you only want to know about objects directly in front of the sensor, and wide is better if you need to know if anything is near. Maxbotix also offers a more precise line (XL Series) that has 1cm accuracy, longer distance, and better noise suppression (makes the read out less shaky)

Sharp GP2Y0A21YK IR Proximity Sensor

The Sharp GP2Y0A21YK is an Infrared proximity Sensor. It shines a beam of IR light from an LED, and measures the intensity of light that is bounced pack using a phototransistor. If you stare at the sensor, you can see one of the LEDs glowing slightly red as some of the IR falls into the visible-light spectrum.

Hooking it up

Hooking up the GP2Y0A21YK up is, again, like day one of a Arduino tutorial. The only issue, the sensor does not come wired, so I recommend buying the pigtail to connect to it. Connect this just as seen in the illustration with the yellow wire to an analog input.

Because the GP2Y0A21YK is sensing the intensity of its reflected IR light, the sensor outputs near 0V when nothing is in front of it (approx. > 3ft), and ramps up as an object comes near. At about 4in, the reading from the Arduino is about 630.

What it is good/bad for

The GP2Y0A21YK is half the cost of the LV-EZ0, and incredibly simple to use, but there are a few downfalls that make it unsuitable for sensing distance reliably. Unlike the LV-EZ0, its output is not linear, so using this to read actual distance is difficult. Also because it is sensing IR, I have seen the output value thrown off by a TV remote shined directly into it. And lastly, once an object comes within 4in of the GP2Y0A21YK, the read values start to drop again down to around 430 (reading from the arduino) when an object is in contact with the sensor.

But with all the downfalls... if you just need a sensor so your robot does not to bump into walls, this should work as a great low-cost solution.

Other options

Sharp does makes a few different versions of this sensor suitable for different ranges (between 1.2in to 5ft).

QRD1114 IR emitted / Phototransistor

Last, but not least, is the QRD1114. The QRD1114 is actually 2 components, an IR transmitter, and a phototransistor, held together in one package. This, like the GP2Y0A21YK, works by shining an IR light and seeing how much of it bounces back. An object that is closer will bounce back more light than one far away. The QRD1114 is only able to sense objects between 0 and 3cm away. On the Arduino, the read value will be in between 600 and 1024.

Hooking it up

The QRD1114 is a little more complicated to hook up than the other two, but that is because this is actually just two raw components. But... it only requires two resistors, (200-200ohm and a 4.7k - 5.6k ohm) to get it up and running. See the illustration on the right for exact wiring. The 4.7k - 5.6k resistor is a pull-up resistor, and changing this will change the values read by the Arduino, but can be used to make it more or less sensitive.

What it is good/bad for

Like the Sharp sensor, this is not intended for use in determining exact distance, but for checking the proximity of objects under 3cm away. This sensor can also be used to detect white vs black surfaces because a white surface will reflect more light than a black surface resulting in a higher reading. Because of this, an array of these can be used for line detection and following.

I have quite successfully used this sensor for detecting when an object passes over a track to trigger an event. In fact, it is so fast at this detection, that properly setup, an object the size of your finger could be detected passing over it at about 10 times the speed you can flick your finger.

Because the sensor component simply measures IR intensity and is unaware of the light's source, it is susceptible to false positives caused by outside sources that put off IR such as camera flashes, lamps, and even the sun. Just make sure you consider your environment before you use this as a mission critical component.

Other options

If you are looking at detecting lines alone, a better choice might be the QRE1113 specifically designed for line sensing. If you are looking at sensing when an object passes by, and the object is small enough, you might also consider Photo Interrupter. These are great for coin drop detection etc.

Code

The code for any of these sensors is incredibly simple, and at the core, is exactly the same. All this does is read value on analog pin 0 and output it via the serial terminal. This way you can see the values change as you put your hand in front of it. I added a small delay so that the output is a bit slower and easier to read. But this also slows the reaction speed. In your project, you will want to remove the delay for best results.

int sensorPin = 0; //analog pin 0

void setup(){
  Serial.begin(9600);
}

void loop(){
  int val = analogRead(sensorPin);
  Serial.println(val);

  //just to slow down the output - remove if trying to catch an object passing by
  delay(100);

}
Unless otherwise stated, this code is released under the MIT License - Please use, change and share it.

Extending this

Just because these sensors are designed to check proximity, don't let your imagination be limited to that. Obviously you could easily make a digital tripwire with a few of these, but... The LV-EZ0 can accurately sense distance, and you can ascertain time passed with your Arduino, so you can also find speed of an object. In fact I have used a device that used 2 IR reflectance sensors and could track a marble at 80+ MPH passing by just by knowing the time and exact distance between them.

These are very simple devices, but don't let that limit you to simple ideas. What about a jacket that alerts you when someone approaches behind you? Or dog door that only opens when the dog is near. I don't know, and we're not here to give you the idea, just supply the know-how. So make something crazy, and we'll see you next week.