On door to my room there is HC-SR04 that triggers led-wave. The shorter the distance, the faster the led-wave (8 leds).

The circuit works fine in synthetic tests – moving hand or flat object towards the sensor generates gradually accelerating wave.

However, when placed on door to detect approaching persons it generates short correct (<=170 cm) impulses and the wave starts and immediately stops, again starts, etc. I guess HC-SR04 isn't good enough to detect people.

Are there any alternatives to this sensor that will correctly detect human approaching?

  • 1
    You should run some tests that show the calculated values. You may want to filter out any values that are extremely high (and disregard them).
    – Paul
    Dec 1, 2016 at 9:59
  • Are you powering it differently in your tests vs on the door?
    – sa_leinad
    Dec 1, 2016 at 11:41
  • The typical HC-SR04 code uses pulseIn() with a default 1 second timeout. If there is nothing for the sound to reflect off in range (i.e., a wall within a couple of meters) the pulseIn() will cause massive delays in your operation.
    – Majenko
    Dec 1, 2016 at 11:57
  • arduino.stackexchange.com/questions/39388/… Use the code in this link to solve your problem. Jun 11, 2017 at 20:15

2 Answers 2


Try to find where the error comes from.

I suggest loading up a piece of code that outputs the measurements to through the serial terminal.

  • You should typically filter out any values that are > 200cm (since it's out of range).

  • You should take the average of a few readings, to be more accurate and less error-prone.

  • Find why some readings are weird, is the object fuzzy (may absorb the ultrasound)?

If all fails, you may look at IR distance sensors (SHARP) like:




Alternatively, you could use a combination of (multiple) IR and ultrasonic sensors. But I doubt you really need that mount of accuracy.

You could also go for a Raspberry Pi + camera and openCV, but that's a whole other matter.

  • I've had to take not average, but minimum value, from last 7 values (distances) – it looked like the sensor was returning correct distance to the moving object mixed with distance to the wall behind the person. Also, NewPing beautifully fixed pulseIn() lags
    – Itzie
    Dec 2, 2016 at 8:13
  • Yes, it may be that the sensor sometimes doesn't see the object, this may be of various reason, such as the sound not bouncing back into the "receiver". If the wall is at 200cm, you could filter out values that are below it, so that you automatically only sense when there is someone. But good that you've found out a method that works for your case :D
    – Paul
    Dec 2, 2016 at 9:03

In general the HC-SR04 is controlled using pulseIn().

When there is nothing within range for the sensor to detect it usually has to wait for pulseIn() to time out. That can take up to a second by default. While that is happening the rest of the sketch cannot do anything.

You can reduce the timeout in the pulseIn() function, but it's still not going to be perfect - you'll still get a delay which will interrupt your LED sequences.

The ideal way will be to create a "free running" distance sensor system - use a timer to periodically start a ping, and use the Input Capture module of the ATMega to measure the time between the start and end edges of the returning pulse. Everything will happen asynchronously to the rest of your sketch then.

I am not aware of any libraries for Arduino boards, but I have one for the PIC32 based chipKIT boards that I use. It can't ever work on AVR based boards, but you can use it to see the general concepts and how things fit together.

  • Good points, I had a hard time distilling what the problem was, since the question isn't that clear. But this could indeed also be a problem. One should always try to make his code non-blocking :) Using hardware timers directly, may make the project unportable to other Arduino devices. You could use millis() and code based on a statemachine.
    – Paul
    Dec 1, 2016 at 15:10
  • @paul You could, though you would be hard pressed to get the timing resolution you need for ultrasound work with that - you're working with microseconds, not milliseconds.
    – Majenko
    Dec 1, 2016 at 15:11
  • Ah, indeed, I was thinking for planning the periodical scanning. 'micros()' is also a thing, but I'd rather not?
    – Paul
    Dec 1, 2016 at 15:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.