Go Down

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

docdoc

Since my laptop's battery is shot,
No, please don't shoot your laptop! :D :D
Anyway the 8th floor window proved ideal.
Seriously, such sensor can't reliably measure distances greater than a few metres (3 or 4 mt), any attempt to detect longer distance measures will give you high uncertain data due to increasing sound front width, reflexions, mixed obstacles, alignment of the obstacles (a glass surface at 45 degrees will give you no echo at all), and other technical issues like the power of the transmitter and the receiver sensitivity. For a very cheap SR04 all those things come in great consideration!
Btw, if you set the timeout to smaller values than 1.000.000 (1 sec) like 50.000 (50 ms) and don't live in a japanese-style capsule room, you have enough space to test with :D
You can have the same effect by completely covering the sensor with your hand, as this blocks any possible echo to get back to sensor.
Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

SCION06

Hm, what exactly gives you such large numbers? If it's the "cm" variable there's something wrong. If not, tell us where you read that (if you read hundreds, it'd be some time measure in microseconds?).Good.Hope you succeed, otherwise replace "put them into a project" with "throw them in a waste bin". :D And buy SRF05.

I am reading this is the serial monitor. The idea that it's in microseconds makes sense, looking at the original NewPing example and the timeout fix the math has been removed to convert microseconds to cm. Thats what i see I do not know the math guess thats next to work out

teckel

I am reading this is the serial monitor. The idea that it's in microseconds makes sense, looking at the original NewPing example and the timeout fix the math has been removed to convert microseconds to cm. Thats what i see I do not know the math guess thats next to work out

ping_cm() does the ping and converts the distance to CM automatically.  To get the reading in milliseconds, you would use the ping() method.

Also, if your sensors are proven to be defective, instead of throwing them away, send them my way.  I really need a defective one to correctly reprogram NewPing to work with these sensors.

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

SCION06

#48
Sep 24, 2015, 07:07 pm Last Edit: Sep 24, 2015, 07:11 pm by SCION06 Reason: noticed had posted the wrong sketch
Well today is the slowest day at work so I have been able to work on this.  NewPing code with reset that is working for me know,
Code: [Select]
// ---------------------------------------------------------------------------
// Example NewPing library sketch that does a ping about 20 times per second.
// ---------------------------------------------------------------------------

#include <NewPing.h>

#define TRIGGER_PIN  12  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     11  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

void setup() {
  Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
}

void loop() {
  delay(50);                      // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
 
  Serial.print("Ping: ");
  Serial.print(sonar.convert_cm(uS)); // Convert ping time to distance in cm and print result (0 = outside set distance range)
  Serial.println("cm");


if (uS == 0 && digitalRead(ECHO_PIN) == HIGH) {
    pinMode(ECHO_PIN, OUTPUT);
    digitalWrite(ECHO_PIN, LOW);
    delay(100);
    pinMode(ECHO_PIN, INPUT);   
  }
}

Notice the convert.sonar_cm line this was missing so my serial monitor (as docdoc suggested) only showing in microseconds. After some digging and returning to the library home page found some command lines I did not know about.
Thank you to those who helped and those who provided the library.
Tim I saw your post after I had posted this, let me know what you think. Readings on the serial monitor are correct now. My sensors are a buy from ebay as well, and work until they do not recieve a ping. With this reset in the program they are working.

teckel

Well today is the slowest day at work so I have been able to work on this.  NewPing code with reset that is working for me know,
Code: [Select]
// ---------------------------------------------------------------------------
// Example NewPing library sketch that does a ping about 20 times per second.
// ---------------------------------------------------------------------------

#include <NewPing.h>

#define TRIGGER_PIN  12  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     11  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

void setup() {
  Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
}

void loop() {
  delay(50);                      // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
 
  Serial.print("Ping: ");
  Serial.print(sonar.convert_cm(uS)); // Convert ping time to distance in cm and print result (0 = outside set distance range)
  Serial.println("cm");


if (uS == 0 && digitalRead(ECHO_PIN) == HIGH) {
    pinMode(ECHO_PIN, OUTPUT);
    digitalWrite(ECHO_PIN, LOW);
    delay(100);
    pinMode(ECHO_PIN, INPUT);   
  }
}

Notice the convert.sonar_cm line this was missing so my serial monitor (as docdoc suggested) only showing in microseconds. After some digging and returning to the library home page found some command lines I did not know about.
Thank you to those who helped and those who provided the library.
Tim I saw your post after I had posted this, let me know what you think. Readings on the serial monitor are correct now. My sensors are a buy from ebay as well, and work until they do not recieve a ping. With this reset in the program they are working.
You could also just use the  sonar.ping_cm() method.  In other words just do something like this:

Code: [Select]
unsigned int cm = sonar.ping_cm();
...
Serial.print(cm);


I'd love to have a sensor that doesn't work, all of my work all the time, even when pointed to infinity.

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

mzbas

the solution to the sensor being stuck at zero is in this link. its the 2. post, by docdoc. You will need the NewPing library which is far better.

A working code:

#include <NewPing.h>

#define TRIGGER_PIN 12

#define ECHO_PIN 11

#define MAX_DISTANCE 200

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

void setup() {

Serial.begin(9600);

}

void loop() {

delay(50);

unsigned int uS = sonar.ping();

pinMode(ECHO_PIN,OUTPUT);

digitalWrite(ECHO_PIN,LOW);

pinMode(ECHO_PIN,INPUT);

Serial.print("Ping: ");

Serial.print(uS / US_ROUNDTRIP_CM);

Serial.println("cm");

}

link: http://forum.arduino.cc/index.php?topic=55119.15

NewPing link: http://playground.arduino.cc/Code/NewPing

dilettant

Hi.

Recently I have bought 3 SR04 sensors from one vendor in China, all of them have the mentioned bug. Thanks Tim "teckel" & Alex "docdoc" for solution in post #41.

I will buy SRF05 for my future robot vacuum cleaner, but thank you for temporary solution. I won time to play with my robo-car until new sensors arrive!

boris.

dilettant

My joy was premature..

This SR04 sensor gets in HIGH state so frequently and so fast. Even if I introduce the above mentioned code to reset the ECHO_PIN
and place the next command to update the distance to obstacle and the next to print the state of the ECHO_PIN it becomes stack every several seconds!

It looks like fighting with this sensor is impossible.

if (distance == 0 && digitalRead(ECHO_PIN) == HIGH) // reset the defective SR04 sensor
  {
    pinMode(ECHO_PIN, OUTPUT);
    digitalWrite(ECHO_PIN, LOW);
    delay(100);
    pinMode(ECHO_PIN, INPUT); 
    distance = sonar.ping_cm();
  }
if(digitalRead(ECHO_PIN) == HIGH && distance == 0)
  {Serial.println("ECHO_PIN reset needed");
  }

P.S. Tim, I won't send you those sensors to USA.  :smiley-confuse:
boris.

macmac

I apologize for my English but use google translator. I saw that the sensor SR04, when he goes to 0, does not return to mark correct values unless power is removed or snapped his fingers in front of it ... Why is "reset" when they hear a noise?

mikb55

I apologize for my English but use google translator. I saw that the sensor SR04, when he goes to 0, does not return to mark correct values unless power is removed or snapped his fingers in front of it ... Why is "reset" when they hear a noise?

Presumably the sound of snapping fingers contains enough ultrasonic sound to trigger the receive circuit of sensor in the absence of a reflected pulse.

macmac

So it should not be a problem of the receiver. How can you do to send a new signal in the event of output = 0?

mikb55

So it should not be a problem of the receiver. How can you do to send a new signal in the event of output = 0?

Cycle the power. This always works.
Read earlier posts to see a possible software workaround. It may work for some modules, but not for others.

knut_ny

I have 2 different lots og SR04.   Five of them with a 4MHz x-tal the others with 8MHz x-tals.
ALL work perfect when uno has USB power (ca. 4.85V), but all with the 4MHz xtal fails as soon as I connect an additional external power (battery 8.4V)  Arduino voltage is then almost perfect 5V.

Have someone else experienced such behavior ?..  and is there a simple cure other than ideas already mentioned
Ny

Murray_C

I'd love to have a sensor that doesn't work, all of my work all the time, even when pointed to infinity.

Tim
The code you posted for the bug fix works fine after changing the "if" statement to

if (cm == 0 && digitalRead(ECHO_PIN) == HIGH)

Both of the sensors I purchased have the "lock" problem.  Thanks to you and Alex for  providing a workable solution.

While I don't have a spare sensor to send, here is the one I have

http://www.amazon.ca/gp/product/B00F167T2A?psc=1&redirect=true&ref_=oh_aui_detailpage_o06_s00

vgtlcs

Guys - I hate to be the bearer of a blinding flash of reality but NONE of your suggestions actually work for the HC-SR04 as claimed, be it either " add these lines after this line, or use New Ping, or what ever - all i ever get is the correct reading on opening the monitor which then returns incessant "0" thereafter until a restart - then the same process repeats!!! I do feel certain I will receive a fair smattering of "oh you must have a faulty unit" - which of course is plausible but there must be one hell of a lot of faulty units doing the rounds globally given the weight of people like myself who have raised this ongoing issue and then given up by bashing our collective heads against the wall!!!  I just wish you guys offering suggestions would include the complete code and how you are wiring it up etc etc as it is madeningly frustrating as a newby to follow all the "expert offers of how this works etc", only to find after wasting numerous hours that it simply doesn't!

Please don't get me wrong I am extremely appreciative of the efforts most of you guys go to help us 'not so experienced arduino users' out!

The one thing I haven't yet tried was docdoc's (?) suggestion of using the SR05 code and library then uncommenting the SR04 lock line of code - I would have done this except that I could not get a download of the SR05 library anywhere - at least one that only seemed a few years old at the latest!! But would this really work when using an SR04 unit???

Any helpful comments on trying to resolve this SR04 dilemma would be extremely well received by myself. Unfortunately I only have the SR04 units and do plan on buying the SR05's - but if I do do this - will I simply jumping from the frying pan into the fire????? can any of you guys offer reassurance that the SR05 does not suffer from similar problems the SR04 does? Cheers

Go Up