# HC-SR04 ping sensor cutting out at ~3 meters

I have some HC-SR04 ultrasonic sensors that I purchased from eBay not long ago. I hooked one up to an Arduino and wrote a quick sketch to test them, and found that none of them work consistently.

It seems that they all stop working when the distance gets too large. I can turn on the Arduino and I hear the sensor clicking while it is pointed at the ceiling ~1.5 meters away. When I turn it towards the other end of the room ~3 meters away, though, the clicking stops and the pulsein() method times out and the distances read 0 cm. Pointing the sensor back at the ceiling does not solve the problem, power must be cycled. I Actually discovered that flicking the sensor can sometimes get it to work again as well, without cycling the power. I searched for people having trouble with the sensor but no one seems to have the problem I am having.

EDIT: I have done some more experimenting and I now think there must not be an internal timeout when a 'click' is sent and not received. The sensor works when aimed at solid surfaces as far as 3 meters away. It stops working in two cases: aimed out a door or aimed at a soft surface. The documentation on the sensor says that it has a range of 4 meters and doesn't work well on soft (sound absorbing) surfaces. My guess is that in these two cases, an echo is not heard at all. The sensor is then stuck waiting for an echo. Flicking it creates the echo it was waiting for and it resumes until another echo is missed.

There are three ICs on the board: an amplifier, a max3232 level shifter, and an unidentifiable one. My guess would be that the third one is some sort of micro controller, so I may try reprogramming or replacing it. Any input on that would be appreciated, though it looks like I answered my own question to the extent possible.

Here is the code I am using. I have triple checked all of the connections and the fact that it works briefly suggests that they are indeed correct.


const int trig = 3;
const int echo = 4;

float elapsed, distance;

void setup() {

pinMode(trig, OUTPUT);
pinMode(echo, INPUT);

Serial.begin(9600);

}

void loop() {

digitalWrite(trig, HIGH);
delayMicroseconds(20);
digitalWrite(trig, LOW);

elapsed = pulseIn(echo, HIGH, 1000000);
// timeout in microseconds

distance = elapsed / 58;

Serial.println((String)(distance) + " cm");

delay(500);

}

• You can use the pulseIn(pin, value, timeout) form to specify a maximum time to listen for an echo so your sketch doesn't hang in an out-of-range situation. – Chris Stratton May 21 '15 at 2:37
• I am using a timeout in my arduino sketch, and it is timing out. I suspect there is a microcontroller on the sensor board itself that is not timing out, thus it gets stuck (not sending clicks) until I flick the board, which creates an artificial echo. – Keith May 21 '15 at 2:40
• The code you posted is using the non-timeout version of pulseIn() If that is not what you are using, then you should update your question. – Chris Stratton May 21 '15 at 2:45
• The default timeout is one second. I will add it for clarity though. – Keith May 21 '15 at 2:47
• @Samee87 suggestion was OK. Not sure why deleted. – Russell McMahon May 21 '15 at 6:14

It's probably working "well enough".

At present your code should NOT hang but should loop every 1.5 seconds - 1 second for the Arduino mediated pulsein timeout and 500 ms due to delay(500). Nothing the SR04 module does should be able to prvent your code looping every ~= 1.5s. If you eg turn on the on board LED during the delay(500) period you should be able to see that the loop is occurring.

Odds are that your system is not "hearing" the return on soft targets at larger ranges, as per manual, timing out at 1s, delaying for 500 mS then repeating.

The 500 mS delay is not needed (but helps if a heartbeat LED is used) as the 1 second pulsein timeout is independent of the SR04 which has long before "given up".

IF the above is correct then a proof of sorts would be in flicking the sensor JUST AS / AFTER the added heart beat LED goes out. This should work every time if you are fast enough. Whereas flicking it eg when the heartbeat LED goes on would not help.

And/or pointing it at a close object for at least 1.54+ seconds should restore operation.

Bonus:

I would not think it would explain the behaviour BUT the trigger pulse is meant to be 10 uS - not 20 uS plus. The processor will add finite time to that delay - but 'with luck' the low to high and high to low delays of the digitalWrite's will cancel. BUT I'd try 10 uS delay, and also look at the pulse on a scope, if available. |

I have exactly the same problem. Did anybody find a working solution ? My only solution is to power the sensor with a digital output (the working current is 15mA so it's ok) and to reset it when pulseIn return me 0. But there should be a permanent solution to fix this... Thank you, Fardenco

EDIT : I've found a solution : You just need to put the echo pin in OUTPUT mode and to send it a LOW pulse, put it back to INPUT mode and here you go !! http://forum.arduino.cc/index.php?topic=55119.15

• Answers are for answers only. You should edit your answer so it's just the solution you found, and perhaps elaborate a little more? – Nick Williams Sep 8 '15 at 12:50