Ultrasonic distance sensor HC-SR04 lack of timeout problem

I'm trying to use a HC-SR04 ultasonic distance sensor from Ebay (http://cgi.ebay.com.au/ws/eBayISAPI.dll?ViewItem&item=280640838032), but it doesn't appear to have an internal timeout for when it fails to detect an echo. This sometimes results in the echo line staying high forever, even if you re-trigger a measurement. The only way to get it to reset is by cycling the power.

The spec for the HC-SR04 is somewhat incomplete, however research indicates that this is a copy of the (Devantech) SRF04 sensor from the following site, http://www.robot-electronics.co.uk/htm/srf04tech.htm. The spec for this says that "If nothing is detected then the SRF04 will lower its echo line anyway after about 36mS.".

My HC-SR04 sensor doesn't do this. Does anyone else have the same sensor with a working timeout?

The vendor has scrubbed the IDs off the chips so I don't hold much hope for doing a retro-fix.

however research indicates that this is a copy of the (Devantech) SRF04

I've been using the Devantech devices for over ten years without any problems like you describe.

i think i have the same problem... my hc-sr04 is measuring the distance with no problems. but if there is no object in range, i become a 0 value and the sensor hangs and any next value ist 0 even when there are objects.... i should get 3 other sensors this week, so i'll tel you.. sry for my eng.. :roll_eyes:

Did you have the same problem with the other sensors?

Following up to myself....

I'm driving the sensor power rail from an Arduino pin and if the echo PWM signal gets stuck because of no echo I cycle the power off for 100ms, then wait for 100ms before taking a reading. So far it's been working very well. With this sensor I get distance resolution of about 1mm which is better than the spec of 3mm and much better than a DF Robotics sensor which only seems to measure in 10mm increments even when using the PWM output. Jitter is only about 2us in a 1448us round trip at a distance of 25cm, which equates to 0.14%.

Sorry to hijack your post, but I have a question for you. What kind of range do you get with yours? Mine seems to have a very limited range of about 5cm. Perhaps i'm coding incorrectly. What formula do you use to convert output to in/cm?

I've tried several examples always the same result.....

Max range to a flat hard perpendicular surface is about 1.5 meters.

The distance formula is given here. http://arduino.cc/en/Tutorial/Ping?from=Tutorial.UltrasoundSensor

5cm does not sound right at all.

Do you have access to an oscilloscope?

Sorry it's on the "I really need one but can't afford it list!" Any way it's just an ID10T prob or are my sensors bad? I know you can't tell with out testing, but what tests can I do lacking an Oscilloscope?

but what tests can I do lacking an Oscilloscope

Train your pet bat to flap its wings when it hears a 40kHz pulse?

Well funny as that may be, XD I'm still in need of guidance here. I'm gonna start a new post. I feel bad hijacking this one. sorry

This timout thing bugged me too. I applied a bit of RTFM strategy and found a solution. Good luck, and please let me know if this helps you.

// JamesHappy
// Arduino UNO 0022
// Demonstration sketch of HC-SR04 Ultrasonic Range Finder with echo timeout

// Onboard LED should blink while searching for surface
// Onboard LED should be solid when surface is within a specified distance
// Rangefinder should only wait for echos under a calculated timeout

// Reference: http://www.elecfreaks.com/244.html
// Reference: http://www.arduino.cc/en/Reference/PulseIn
// Note: HC-SR04 tested successful in both 5v and 3.5v

int iTrigger     = 2;  // Digital Pin 2
int iEcho        = 3;  // Digital Pin 3
int iAlertLED    = 13; // Digital Pin 13
int iEchoTimeout = 0;  // In Microseconds
int iMaxDistance = 20; // In Centimeters

int iTriggerPullDown = 2;  // In Microseconds
int iPingWidth       = 10; // In Microseconds

void setup() {
  pinMode(iTrigger,OUTPUT);
  pinMode(iEcho,INPUT);
  pinMode(iAlertLED, OUTPUT);
  iEchoTimeout = iMaxDistance*2*29;
}

void loop() {
  digitalWrite(iTrigger, LOW);
  delayMicroseconds(iTriggerPullDown);
  digitalWrite(iTrigger, HIGH);
  delayMicroseconds(iPingWidth);
  digitalWrite(iTrigger, LOW);
  unsigned long ulPing = pulseIn(iEcho,HIGH,iEchoTimeout);
  if(ulPing) {
    digitalWrite(iAlertLED, HIGH);
    SimulateLoad(250);
  }
  else {
    digitalWrite(iAlertLED, HIGH);
    delay(25);
    digitalWrite(iAlertLED, LOW);
    SimulateLoad(225);
  }
}

void SimulateLoad(int iDutyCycle) {
  delay(iDutyCycle);
}

Just ran into same problem too with HC-SR04. Tried to reset sonar's CPU by sending pulse to pin 7, but didn't help. For me it looks like analog part of the module works like some sort of trigger if there no enough external noise in background (yes, it did help when i just clap near module - starts working again).

So, i've doing pulse to discharge C9 capacitor ( http://kazus.ru/forums/attachment.php?attachmentid=75731&d=1423821255 ) by connecting it to one of digital pins of arduino through 500 ohm resistor (setting in INPUT mode, without pull-up most of time, OUTPUT mode + LOW for pulse). Needs a small delay to recharge the capacitor to right level after the pulse.

Hey,

I've been looking around for solutions for my sensors I just purchased. It will work fine, then all of a sudden it will keep returning 0. I have 4 from Sainsmart and they all seem to operate the same.

Vasimv has the only post so far that gave me some light in that, if I snap my fingers beside the sensor, 100% of the time it will start reporting distance again. At least for some random amount of time, till it starts to 0 out again. (usually a few seconds, some times even a few minutes)

Vasimv, would you be able to elaborate on your solution. I do not quite understand how you are discharging C9.

Are you sending it to a digital input and giving it an INPUT mode? or an OUTPUT mode? I'm a little confused you mentioned both.

toedip: Are you sending it to a digital input and giving it an INPUT mode? or an OUTPUT mode? I'm a little confused you mentioned both.

The pin should be in INPUT without pull-up all time (otherwise it'll mess divider's voltage on C9). When you need to reset the sensor - make it OUTPUT mode, LOW set, then some delay and switch to INPUT/no-pullup again.

define resetPin 3 /* D3 to C9 */

void reset_hcsr04 () { pinMode(resetPin, OUTPUT); digitalWrite(resetPin, LOW); delay(1); pinMode(resetPin, INPUT); digitalWrite(resetPin, LOW); }

Btw, i have idea that positive pulse on C9 could reset the sensor too (you have just put diode between C9 and trigger PIN, so positive pulse that starts the sensor - will "shock" the analog part and it'll start working if got locked up). But didn't test yet.

Some knock-off models of the HC-SR04 do not implement a timeout if no echo is detected at all. In that case, the echo pin will simply remain high forever and will not generate any new pings, regardless of what you do with the trigger pin. The original model from Robot Electronics times out after 36 ms and does not have this problem, but many (all?) cheap knock-off models do.

You can reproduce the problem easily by covering the receiver transducer with your thumb, then removing your thumb. If your sensor doesn’t have a timeout, it will stop generating pings and the only way to recover is to power cycle the sensor.

A workaround that works for me so far is to test the state of the echo pin 100 ms after triggering a ping. If it’s still high, you’re in a stuck state. If you wire power to the sensor through a transistor and control that transistor via another pin, then you can power cycle the sensor via software and get back to a working state.

put a 3MOhm restist between the pin 4 and 9 from the U1 EM78P153S Controller, now it works!

best regards

I worked hard on this issue (I bought that f***ing SRF04, next time I’ll get SRF05!) and I think I SOLVED it, and WITHOUT ANY ADDITIONAL HARDWARE!
When I detect the sensor is stuck, I simply switch echo pin to OUTPUT, put it into LOW state, and after a while re-set it to INPUT, then cycle again.
This is a code example to explain my solution:

// ... this is the reading loop
    long pulseDuration;
    long distance;
    int tries = 0;
    do
    {
        pulseDuration = pulseIn( echoPort, HIGH, 50000);
        distance = 0.034 * pulseDuration / 2;
        if ( pulseDuration == 0 ) {
            delay(100);
            pinMode(echoPort, OUTPUT);
            digitalWrite(echoPort, LOW);
            delay(100);
            pinMode(echoPort, INPUT);
        }
    } while (pulseDuration == 0 && ++tries < 3);
    if (pulseDuration == 0)
      // Out of range
    else
      // Read ok!

Hope it helps!

Hi.

I tried the 3Mohm resistor from pin 4-9. It never seems to time out, (which is good), however it seems to only read up to 60cm.

I may try the approach that SaintGimp mentioned. I thought of doing something like this before, just never got around to implementing it.

Cheers,

Hey, thanks docdoc this really works! Would be good to get this in as an option in NewPing for dodgy hardware. Thanks so much, have been tearing my hair out. Sensor works OK now, making a big three way sensor around tree for kids at school, this was very helpful, thanks.

docdoc:
I worked hard on this issue (I bought that f***ing SRF04, next time I’ll get SRF05!) and I think I SOLVED it, and WITHOUT ANY ADDITIONAL HARDWARE!
When I detect the sensor is stuck, I simply switch echo pin to OUTPUT, put it into LOW state, and after a while re-set it to INPUT, then cycle again.
This is a code example to explain my solution:

// ... this is the reading loop

long pulseDuration;
    long distance;
    int tries = 0;
    do
    {
        pulseDuration = pulseIn( echoPort, HIGH, 50000);
        distance = 0.034 * pulseDuration / 2;
        if ( pulseDuration == 0 ) {
            delay(100);
            pinMode(echoPort, OUTPUT);
            digitalWrite(echoPort, LOW);
            delay(100);
            pinMode(echoPort, INPUT);
        }
    } while (pulseDuration == 0 && ++tries < 3);
    if (pulseDuration == 0)
      // Out of range
    else
      // Read ok!



Hope it helps!

I’m using the HY-SRF05 (the one from Upgrade Industries sold by robot-electronics,) which I bought because they stated it is supposed to time out and it doesn’t time out. I contacted their (the manufacturer, Upgrade Industries) support to find out what’s happening and here’s what i sent them:

I’ve been having a problems with a lot of the common SRF04 and SRF05 Ultrasonic rangers, and in this case I’m using the HY-SRF05. I thought this one might operate better than the others because the datasheet indicates that if nothing is detected, the sensor will time out after 30 ms

(This is the one I’m referring too, but there are many other similar ones out there)
http://www.robotstorehk.com/sensors/doc/srf05tech.pdf

Specifically:
“If nothing is detected then the SRF05 will lower its echo line anyway after about 30mS.”

So that means this sensor could range about 20 times in a second. The problem I’m seeing is that it’s take over 200ms for the sensor to time out when no object is detected. It’s a very easy to reproduce problem, just point the sensor at nothing, and attach a scope to the echo pin and the trigger pin, then trigger on the scope on the trigger pin and watch as the echo pin goes high and doesn’t come back down for 200ms.

Do you know if there could be any odd error in the code below? I’ve tried many of these sensors, they all behave the same way but the data sheet for this and even other brands indicates they should be able to return low around 30-40ms after no object is detected.

I’ve attached copies of the scope output, the echo pin is on Channel 4, and the measurements at the bottom show the “Width” of the pulse in the dark blue color.

The easy way around this problem is to read the echo pin after the pulse times out and make sure you don’t try to trigger if it’s still high, if you don’t set a timeout, I’ve found so far that all of them eventually do come back, but the amount of time it takes to return is variable within a range depending on the particular device.

For example, this Hy-SRF05 is around 220ms (it varies about 20ms either way) and other brands I’ve tested come in at 180ms and 200ms. I’ve tried dozens of these from many vendors, and I have yet to find one that properly times out. Hy-SRF05 was my biggest hope too, but even their sensor behaves the same way.

Of course I don’t want to only be able to Scan 4 times a second, and it seems when the sensor is past the 50ms mark, it won’t retrigger for any reason unless it receives a pulse from another sensor or it reaches the 200ms (or whatever the range for that model is) mark.

DS1Z_QuickPrint1.png

DS1Z_QuickPrint2.png

DS1Z_QuickPrint3.png