Go Down

Topic: Ultrasonic distance sensor HC-SR04 lack of timeout problem (Read 66142 times) previous topic - next topic

letch

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

best regards

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:
Code: [Select]

// ... 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!
Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

toedip

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,

kiwilee

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.

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:
Code: [Select]

// ... 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!


Slimicus

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:



Quote
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.

docdoc

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.
After my last post here I bought an HY-SRF05 also, and it seems to work fine... I mean, if it timeouts I get a 0 cm distance most of the times, but without the long delays you're complaining about. Don't know if yours is an issue of a somehow "buggy" series...

Please note I said "most of the times" returns zero, because mine has a small quirk: it seems to return an anomalous 3 cm distance alternated to (correct) zero, so I return "0" if current measure is 3 cm and the previous one was 0. And it worked fine this way.

So, the reason why I delayed this reply to original post is I made a library to help me (and anyone with the same problem too) manage either SR-04 or SRF-05 idiosyncrasies..:-) I hope you enjoy it, but I'll appreciate any feedback as I'm open to any suggestions and critics... ;)

Please note the class is called SRF05, but it works with both SRF05 and SR04.

After installing the library, open the example:
Code: [Select]
// SENSOR DEMO
#include "SRF05.h"

// trigPin, echoPin, MaxDist, readInterval
SRF05 Sensor(6, 7, 200, 500);

void setup() {
    Serial.begin(9600);
// If using SR04 enable the following line:
//Sensor.Unlock = true;
}

void loop() {
    // Distance read
    if ( Sensor.Read() > -1 ) {
        // New distance reading!
        if ( Sensor.Distance == 0 ) {
            Serial.println("Out of range");
        } else {
            // -------------
            Serial.print("Dist: ");
            Serial.print(Sensor.Distance);
            Serial.println(" cm");
        }
    }
}
As you can see, we simply create an SRF05 object with needed configuration parameters:
  • TrigPin: digital pin for Trig
  • EchoPin: digital pin for Echo
  • MaxDist: max measuring distance (cm); optional, default=300 (3mt)
  • ReadInterval: interval between measures(millis); optional, default=0

The first two don't need particular explanations I hope, while the third simply specifies the maximum distance we want to measure, usually not higher than sensor range.
ReadInterval makes it easy to manage reading intervals without a specific timer: usually we don't check the distance on every loop() call, so set ReadInterval to the desired milliseconds and the library will do the job for you.

This way, the loop() calls only the "Read()" method: it returns measured distance in centimeters but if called before "ReadInterval" milliseconds after the last read, it returns "-1" meaning "it's not the time!". 8)
If called after ReadInterval milliseconds or more, performs a new ping and returns the updated distance. If the sensor doesn't read obstacles within the range (no echo or echo after "MadDist" cm), the Read() method returns zero.

If for any reason you need to continuously read the distance, simpy set ReadInterval=0 and each Read() call will ping the sensor.

Apart from Read(), some public properties are available anyway, including constructor parameters and latest measured distance:
  • int TrigPin;
  • int EchoPin;
  • long MaxDistance;
  • long ReadInterval;
  • long Distance; // Last Read()

Library version 1.1 (attached one) includes a workaround for "locking" SR04 sensors when no echo is received. To enable this feature simply set "Unlock=true;" inside "setup()", as shown in the example.
Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

orje

I also had the problem that the sensor stayed HIGH when it couldn't reflect anything.
I tried to solve the problem through switching the Arduino ECHO input into output mode and setting it LOW, like docdoc it adviced. But this didn't help.
The direct power connect of the sensor to a Arduino output like mjbmikeb wrote worked either. It didn't hung but didn't also measure at all.
The only thing that helped was what SaintGimp wrote, to power the sensor over a transistor and switch that shortly off if the sensor hangs.
Nevertheless thanks to all for your effort.

docdoc

Yep, that's why I bought an SRF-05 and I'll never buy SR-04 anymore...
Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

Vinterwoo

I had the same problem, but docdoc's solution worked for me.

Thanks docdoc!


docdoc

You're welcome, I'm happy to see someone else solved this problem with this "too chinese" SR04! ;D

Btw, just to know, did you included my SRF05 library (and used Unlock=true) or changed your code?

Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

teckel

Or, you could use the NewPing library which has this and many other advantages (smaller code size, one pin mode, timer interrupt method, etc.).

Tim
My platforms Arduino, Teensy 3.2, Arduino Pro Mini, ATmega328
My libraries: NewPing, LCDBitmap, toneAC, toneAC2, NewTone, TimerFreeTone
My projects: https://dogblocker.com & https://baconorbeer.com
My beer: Great Lakes Brewing Co. Lake Erie Monster

docdoc

Are you sure NewPing fixes SR04 "lockout" on echo timeout?
I have seen nothing about this in its docs...

Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

teckel

Are you sure NewPing fixes SR04 "lockout" on echo timeout?
I have seen nothing about this in its docs...


That was the primary reason NewPing was written 3 years ago.  It's evolved from there.  This feature is listed as bullet item #3 in the introduction:

Doesn't lag for a full second if no ping echo is received like all other ultrasonic libraries.

NewPing


Tim
My platforms Arduino, Teensy 3.2, Arduino Pro Mini, ATmega328
My libraries: NewPing, LCDBitmap, toneAC, toneAC2, NewTone, TimerFreeTone
My projects: https://dogblocker.com & https://baconorbeer.com
My beer: Great Lakes Brewing Co. Lake Erie Monster

docdoc

That was the primary reason NewPing was written 3 years ago.  It's evolved from there.  This feature is listed as bullet item #3 in the introduction:
Doesn't lag for a full second if no ping echo is received like all other ultrasonic libraries.
Yeah, but i think you haven't got the point, that's not the problem I'm talking about (and solved with my lib)...

My SR04 sensor(s) doesn't simply "lag for a second" if no echo is received, it completeliy LOCKS UP, returning 0ms for all and every subsequent reads, until turned off and on, as suggested in other topics (using a pin to control a transistor to simulate physical disconnection of SR04 power cable). I still don't know if my SR04 (and the one used by many other users here) is a faulty series, or made by a "too-much-chinese" factory, by the way the problem was real and NewPing didn't solve it. After trying with 3 different SR04, I decided to buy SRF05 from now on, btw SF04 is a bit cheaper and I wanted to use them for low-purpose projects, and with my SRF05 library I have full control over it, without any hardware change!



Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

teckel

Yeah, but i think you haven't got the point, that's not the problem I'm talking about (and solved with my lib)...

My SR04 sensor(s) doesn't simply "lag for a second" if no echo is received, it completeliy LOCKS UP, returning 0ms for all and every subsequent reads, until turned off and on, as suggested in other topics (using a pin to control a transistor to simulate physical disconnection of SR04 power cable). I still don't know if my SR04 (and the one used by many other users here) is a faulty series, or made by a "too-much-chinese" factory, by the way the problem was real and NewPing didn't solve it. After trying with 3 different SR04, I decided to buy SRF05 from now on, btw SF04 is a bit cheaper and I wanted to use them for low-purpose projects, and with my SRF05 library I have full control over it, without any hardware change!
Sounds like you have a faulty sensor.  Obviously, it shouldn't stop working if it doesn't get a ping echo.  I have dozens of sensors, and none do that.  But, sounds like testing the state of the echo pin when a 0ms ping is received and if it's locked up cycling power to the sensor seems like the simple thing to do.

There's no need for a transistor to power the sensor to do this, the sensor doesn't draw much power so you can supply power directly from an Arduino pin.  Using my NewPing library and the one pin method, you could probably still control the sensor with just two pins (one for power and one for trigger/echo).  I do this with a ultra low power sensor that combines a PIR sensor and an ultrasonic sensor.  The PIR sensor detects motion, and if detected it activates a pin which turns on the ultrasonic sensor to get a distance measurement.  Not only does this reduce the power used to a trickle (using a pin interrupt), it also allows for a mostly passive sensor (except for the distance measurement).

Anyway, if this is just a defective sensor, I would think getting a working sensor would be the correct solution (as they cost about $1).  If there's a model of sensor that does this by design (not sure why), I would like to have one so my library could be modified to accommodate it.  It seems testing pin state when getting a 0cm result and cycling power would the easy thing to do.  Or something simple like this which is done after a ping:

Code: [Select]
  if (cm == 0 && digitalRead(ECHO_PIN) == LOW) {
    pinMode(ECHO_PIN, OUTPUT);
    digitalWrite(ECHO_PIN, LOW);
    delay(100);
    pinMode(ECHO_PIN, INPUT);   
  }


But, there's really no way for NewPing to be modified if no one can source a sensor that has this problem.  Also, there's a question of if anything should be done if it's just a defective sensor.  Heck, I'm not even sure the sensors are defective, maybe some people are just doing something else incorrectly.  In any case, can't know and can't really attempt to fix a problem that doesn't exist (at least for me).

Tim
My platforms Arduino, Teensy 3.2, Arduino Pro Mini, ATmega328
My libraries: NewPing, LCDBitmap, toneAC, toneAC2, NewTone, TimerFreeTone
My projects: https://dogblocker.com & https://baconorbeer.com
My beer: Great Lakes Brewing Co. Lake Erie Monster

Go Up