This page exists because it DOESN'T work .. without a little help :)
Background
Device | Connector | Trigger and Sense | Price |   |
---|---|---|---|---|
PING))) ultrasonic rangefinder | 3 pins | shared pin | $30 | A single pin is used for both input and output, direction reversed as required |
HC-SR04 ultrasonic rangefinder | 4 pins | separate pins | <$1 from China | Unfortunately, some of these have a small design problem (feature)
"Fix" (actually, a work around) described below |
Grove ultrasonic rangefinder | 4 pins | shared pin | ~$14 | Their library reads echo using pulseIn |
File / Examples / 06.Sensors / Ping |
Code for the HC-SR04 is similar, but uses 2 separate Arduino pins. For example
Basic operation
When a trigger is received, the HC-SR04 produces 8 pulses at 40 KHz and sets the echo output high. When an echo is received, the echo output goes low. Assuming that you know the speed of sound (which is affected by air pressure, temperature, and humidity), it is possible to use the length of time that the echo output is high to compute the distance to a reflecting surface.
Using the example software (linked to above), the distance to an object is displayed in the serial monitor. To display the monitor, from the Arduino IDE menu select
Tools / Serial Monitor |
The software displays the distance between the sensor and some object. Unfortunately, the values are not very accurate because both programs use integer math and do not provide a way to adjust the values for the local speed of sound. This is, of course, acceptable for examples, but is something you should be aware of so you can "fix" it for your application (as required, or not).
NewPing Library
C:\downloads\Arduino\arduino-1.0.5-windows\arduino-1.0.5\libraries\NewPing |
File / Examples / NewPing |
To test a sensor
Unfortunately, this program suffers from the same problem as the other example programs.
Nominally, the HC-SR04 works as expected. The problem occurs when no echo is received.
Using the example software linked to above, objects a foot or two away are easily detected. However, when you point the sensor at an object more than 9 or 10 feet away - the echo is simply so weak that it is not detected. In that case, the software displays zero (no signal detected). The same thing happens if you cover the transmitter with your hand (makes testing easier), or do something else to keep a reflection from being detected.
The problem occurs when you now place an object back within the range of the sensor - you still get zeroes. Just zeroes. Until you manually reset the sensor.
I originally thought that this was simply a defective sensor .. until an internet search revealed that it is a fairly common problem. The only suggested solution was to use a transistor (driven by the Arduino) to cycle power to the device - a kludge at best! But it does work.
Using an oscilloscope, I verified that the ping pulses were not being generated when the next trigger occurred. Apparently, with some devices, the next trigger resets the unit, a ping is sent, and the device continues to work normally (as advertised in the provided documentation). However, with the devices I bought, the next trigger does not reset the device. (Very frustrating!)
One way to "fix" the problem (and to verify that a ping pulse is not being generated) is to just snap your fingers. The receiver will detect the snap and finish its timeout (send the echo line LOW). After that, the sensor will work as expected until another pulse is not detected.
Solution
int inputPin = 8; // Echo pin on D8 int outputPin = 7; // Trigger pin on D7 int distance = -1; // just a flag so it won't be zero the first time void setup() { Serial.begin(9600); pinMode( inputPin, INPUT); pinMode(outputPin, OUTPUT); } void loop() { if (distance == 0) { // only when there was no echo pinMode(inputPin, OUTPUT); digitalWrite(inputPin, LOW); delayMicroseconds(10); // shorter periods are not reliable pinMode(inputPin, INPUT); delayMicroseconds(10); distance = digitalRead(inputPin); // the echo pin should now be low if (distance == 1){ Serial.println("echo still high"); // mainly for debug delay(500); } } delayMicroseconds(2); digitalWrite(outputPin, HIGH); // Pulse for 10 µs to trigger ultrasonic sensor delayMicroseconds(10); digitalWrite(outputPin, LOW); distance = pulseIn(inputPin, HIGH, 20000); // Read receiver pulse time distance= distance/58; // Transform pulse time to distance Serial.println(distance); // Output distance delay(50); } |
Documentation
The module is not suggested to connect directly to electric, if connected electric, the GND terminal should be connected the module first, otherwise, it will affect the normal work of the module. |
The module should not be connected to a system which currently has power supplied. However, if you do, be sure to make the GND connection first. |
Schematics
Timing
digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); |
800 us / 2 / (73.746 us/in) = 5.42 in 800 us / 2 / (74 us/in) = 5.41 in (close enough, but reported as just 5 in) |
duration = pulseIn(echoPin, HIGH); // Default timeout is one second duration = pulseIn(echoPin, HIGH, 1000); // 1000 us works pretty good for test |