Cheap Sensors: HC-SR04
Sensors are an integral part of any robot, automation project, or anything involving mechatronics. Unfortunately they are normally quite expensive. This series of instructables aims to provide information about cheap sensors for whatever project you like. I'll be providing information on how to use them, some example code for Arduino, and what I think the sensor would be good for.
Sensors Tested So Far:
- RPR220
- HR-SR04 (This Instructable)
The HC-SR04 is an ultrasonic range sensor, the cheapest one you can find. As a result there is plenty of documentation around for it. However I've discovered two tricks: you can make it into a 3-wire device, and you can set the timeout. All ultrasonic range sensors are based on the same principle: sound takes time to travel. An ultrasonic sensor sends out a pulse, and waits until it hears it. Based on the time between these events, the distance can be measured.
The HC-SR04 can be bought for as little as $0.73, though most robotics online stores stock it for a few dollars.
Plugging It In
As with any electronics, a good place to start is the Datasheet. This device has been cloned so much that finding it's datasheet is actually quite hard. The best I've found is here, and it's pretty flimsy.
The HC-SR04 has 4 pins:
- Ground
- Trigger
- Echo
- Vcc (5v)
The two pins that need to get to a microcontroller are Trigger and Echo. To use the sensor, you send a pulse down Trigger, and measure a pulse from Echo. Because these pins are required at different times, and because of the way the triggering works, it is possible to turn the HC-SR04 from a 4-wire device requiring two pins, to a 3 wire device requiring only one. TO do this, you simply need to chuck a resistor on the echo line. The value isn't too fussy. It works all the way from 200 ohm to 100K ohm.
The connections for this are shown in the pictures.
Arduino Code
A typical complaint about ultrasonic sensors is how long it takes if it misses a pulse. The default Arduino PulseIn command will wait for up to a second. Thankfully the function has a second argument: timeout.
By looking at the timing diagram, we can establish that we only need to wait ... 60ms! If you don't wan't it's full range, and know you aren't going to poll it more often than that, then you can cut that time down (et you can poll out to 40cm in just 6ms, but you still can't get values more than 16 times per second.
Because we are using this device in 3-wire-mode (to save pins), the code to trigger has an extra line in it.
To convert from microseconds to time, we divide by 29 (microseconds per centimeter) and again by 2 (it's a return trip). The multiply by 10 is to convert it into mm.
#define ULTRASONIC_PIN 16<br> void setup(){ Serial.begin(9600); } void loop(){ Serial.println(readUltrasonic(ULTRASONIC_PIN)); delay(10); } int readUltrasonic(int pin){ //Returns distance in mm pinMode(pin, OUTPUT); digitalWrite(pin, HIGH); delayMicroseconds(10); digitalWrite(pin, LOW); pinMode(pin, INPUT); return pulseIn(pin, HIGH, (unsigned long)60000) * 10 / 29 / 2; }
Testing
The accuracy of this sensor is fine in certain circumstances. Coupled with it's price, this has made the HC-SR04 a go-to sensor for a huge number of hobby robotics. However, there are some limitations:
In still air, at a range of 5cm you can get 1mm accuracy, and at 3m, about 1cm. If you've got a breeze, don't expect your range to be more than a meter, and your accuracy will be poor.
Another consideration is the orientation of the target. If you're detecting a flat plate, the plate has to be square on. If there's more than a 5 degree tilt the sound's reflection won't come back to the sensor. If the object you're detecting has rounded corners you'll be fine, as there will always be a surface facing it.
A final consideration is the material of the target. A soft material (Eg fabric) absorbs the sound and so your range is limited. A thick jersey can't be detected at more than 10cm, but a metal plate can be detected at a couple of meters.
Summary
The HC-SR04 is a good cheap sensor, but it is far from perfect. In the real world, the HC-SR04 will prevent your robot from running into objects only some of the time. They take a long time to poll (using the basic method shown here), and will interfere with each other.
But they do offer good range and accuracy in certain situations. They are cheap and readily available, and easy to interface to a micro-controller. They do not require an ADC, and with very little work, can run on only a single pin.
So where would you use this sensor? Anywhere you know that the target will be a hard material that is perpendicular to the sensor. One project I say used these sensors to measure the extension of hydraulic rams, and they could measure them tremendously accurately. They don't work well indoors where there are sharp edges, and the don't work well outdoors where there is wind. So for mobile robotics, their use is limited.