HC-SR04 behaves erratically - Page 1
Forum section: electronics / beginners

author: TopGun
author_rank: Contributor
timestamp: August 08, 2020, 05:46:27 am
content: Hi.I have an ultrasonic sensor (HC-SR04) connected to an Arduino. I'm trying to measure the amount of liquid in a container about 2m high. The sensor jumps around and never gives accurate measurements. But, on the bench, the sensor gives accurate readings up to about 1m away, after which, the readings become erratic. I have tried getting a new sensor, a new Arduino, new power supply, non of which had any effect.Considering that the sparkfun pagehttps://www.sparkfun.com/products/15569of the sensor promises upto 4.5m of range, I don't know what I'm missing. It also supposedly has "additional control circuitry that can prevent inconsistent "bouncy" data depending on the application."I'm using a library with the provided example code to run the sensor. Link:https://www.arduinolibraries.info/libraries/hcsr04Please help. TiA

author: Dabbot
author_rank: Regular Contributor
timestamp: August 08, 2020, 05:53:16 am
content: It might be as simple as averaging the incoming data.Can you post some logs of this erratic data for various distances?

author: TopGun
author_rank: Contributor
timestamp: August 08, 2020, 07:56:42 am
content: Can an Arduino store enough data to run some averaging algorithms? I will post the sample data when I get home.Follow up question... Can liquid be measured with an ultrasonic sensor? Would the liquid affect the measurement?

author: Siwastaja
author_rank: Super Contributor
timestamp: August 08, 2020, 08:48:43 am
content: If the values jump all over the place, the problem isn't noise and can't be solved by averaging. This would be the case if you get results accurate to a few cm at shorter distances, then suddenly have jumps of many tens of cm at further distances. Clearly either the sensor, the library, or your code is malfunctioning, and it's impossible to say why without jumping in to all details.On the other hand, if you see the noise gradually increase with the distance, say your readings jump +/- 1 cm at close distances, then maybe +/- 5cm at longer distances,thenit's possible to say it could be just noise which can be solved by averaging.The processing power of Arduino is just fine for averaging. You could even simply store, say, 16 latest values in an array and each time you have a new one, calculate the average by summing the 16 values then dividing by 16. Inefficient for longer arrays, though.For long-time averages with very low memory footprint, take a look at "cumulative moving average" algorithm. Say if you have 16-bit signed input numbers, and want to use filter length = 256, you can use:Code:int16_t latest_value = read_from_sensor(...);static int32_t cma = 0;cma = (((int32_t)latest_value<<8) + 255*cma)>>8;int16_t averaged_value = cma>>8;What this code, in essence, does is:1) Shift the input values left by 8 bits, equal to multiplying by 256. This is done to increase resolution so that intermediate values stored do not lose accuracy.2) With each new value, calculate a weighed average of the new input sample, and the current stored filtered value. Take 1/256 parts of the new input, and 255/256 parts of the existing filter value. So now as you can see the filter mostly uses the old filter value, and only takes a tiny bit of the new input.3) As the last step, the output of the filter is shifted right 8 bits, dividing by 256 again, to compensate for step 1.This algorithm creates an IIR type filter response, but doesn't need a lot of memory. If you use very high filter length, you may need to up the stored filter value to a 64-bit integer type, but even that is quite OK in even the slowest and smallest 8-bitters, just 8 bytes of memory and some dozen instructions per cycle.

author: TopGun
author_rank: Contributor
timestamp: August 08, 2020, 09:43:15 am
content: Thanks for the reply.Its quite peculiar really.. Up to about the one meter mark, the values are rock solid (they are precise, but not accurate) After the one meter mark, the values eratically jump all over the place, with no semblance to the real value.

author: janoc
author_rank: Super Contributor
timestamp: August 08, 2020, 10:27:53 am
content: Quote from: TopGun on August 08, 2020, 09:43:15 amThat's totally normal for an ultrasonic sensor of that type. Some may "reach" longer but you will be hard pressed to find one that works reliably beyond a meter or two. The 400cm upper range I have seen mentioned is wildly optimistic, IMO. It is simply due to the fact that the transducer isn't driven with high enough power, so the reflected ultrasonic echo gets too weak to detect.The receiver sensitivity/gain can't be cranked up because then it will "hear" ambient noise too - these devices are "dumb", they don't do any advanced DSP processing on board to match the echo with the emitted ping (signal correlation on a modulated "chirp" like sonar does), so they will pick up stuff like clinking of keys or high pitched noises as well.The other thing that may affect the range is what material are you bouncing the sound waves off - material that is more "compliant"/"softer" and thus absorbs the energy of the waves will shorten the detection distance drastically.I made my own ultrasonic tracker using these transducers back in the 1998 or so, the longest distance that it worked at (with my own driving electronics and amplifiers) was about 1.5-2m when driven from 5V TTL logic signal - which is about the same as what your sensor module does.The longest range ultrasonic sensor I have seen was on the SoundBeam midi controller - that one worked up to about 6 meters. However, that transducer is much larger (about the size of a shower head) and driven really hard, you can hear audible "clicks" when it is operating. The other problem is the higher the power, the higher are the chances of delayed echoes from previous "pings" hitting the receiver and messing the measurement up. The sound wave keeps "bouncing" around the room decaying in power - with sufficient emitted power you could still detect even the second or third echoes.So if you need to measure a longer distance you may want to consider a different measurement method (or build a sensor yourself).

author: Siwastaja
author_rank: Super Contributor
timestamp: August 08, 2020, 12:37:17 pm
content: Because that HC-SR04 thing (I have used them) has a simple pulse output, if you have an oscillosscope available, you can look at the pulse length with the scope. This helps you verify if the problem is with Arduino/your code, or if the HC-SR04 module is actually producing crap data.In the case it produces crap data, there's very little you can do. What itshoulddo is to not outputanythingfor signals too weak, but that's done internally (they use some cheap microcontroller IIRC) and you can't help that. It's possible they were too optimistic and detect any noise, giving false pulses.Note the HC-SR04, at least the ones I used, do not drive the transducer with 5V; they actually use MAX232 as a charge pump to generate somewhat higher bipolar supply.I don't remember exactly but think I got over one meter, maybe up to about two, but being clones of clones of clones, your mileage may vary.Being "true" time-of-flight (easy with the slow speed of sound), not phase amplification/cancellation based, multiple reflections wouldn't be a big issue, a properly designed sensor could detect and output the fact that there were multiple pings exceeding a certain threshold, and all would be at quite accurate positions. These modules obviously can't do that.

author: TopGun
author_rank: Contributor
timestamp: August 08, 2020, 07:54:58 pm
content: Unfortunately, I do not have access to an oscilloscope. I have a multimeter only. I have tried many types of code written by different people. I have also tried the code that sparkfun provided. Doesn't seem to work.I'm bouncing the waves off of a water-like liquid, stored in a HDPE tank (Not sure if it is considered as compliant/soft as janoc said). The cylindrical tank is approximately 2m wide and 1.5m high. I need a reliable method to find the volume of liquid in the tank with about +- 5l accuracy. Is there any other method, given that these sensors do not seem to be good?

author: janoc
author_rank: Super Contributor
timestamp: August 08, 2020, 09:24:34 pm
content: Quote from: TopGun on August 08, 2020, 07:54:58 pmEither get an ultrasonic sensor made for this task (there are some industrial sensors) or go with a simpler solution - e.g. a float moving up and down and some capacitive sensor, it may be even possible to sense the liquid directly using a capacitive sensor (depends on whether or not it is conductive), etc.See e.g. here:https://www.omega.co.uk/prodinfo/level-measurement.htmlThe sensor you have tried to use is a hack meant for educational use and some toy robotics, repurposing transducers originally meant for car alarms (movement detection inside the cab). It probably wouldn't last in the tank long neither, given that it is completely open to elements, fumes, whatever.

author: aurel9x1
author_rank: Contributor
timestamp: August 08, 2020, 09:43:08 pm
content: The liquid might not reflect the ultrasounds well. In order to test this, you can try to float a small piece of wood 20cmx20cm on the surface of the liquid. If the sensor measures the distance to the to that piece of wood, it means the surface of the liquid does not reflect ultrasounds well.Other cause I'm thinking is that inside the tank, echo might be created and this might disturb the sensor. If this is the case, you can try to work around by putting a resistor in series with it.If it works outside the tank but it doesn't inside the tank, it means the sound is not reflected as it should inside the tank.Anyway, more than 1m won't be able to measure.Other type of sensors are:1. Something like this, but in practice I don't know how long will work before oxidating:https://osoyoo.com/2017/09/27/arduino-lesson-water-sensor/2. If you only want to know when the tank reached a specific level, but you are not interested to know the water level at any moment, you can try to implement a level-switch using a floating device (glass jar, pet bottle) and a tilt sensor. When the water level drops almost to the bottom, the floating 'thing' changes position to horizontal and the tilt sensor detect:https://www.directindustry.com/prod/electro-sensors/product-12082-406524.htmlhttp://radix.co.in/system/photos/images/000/001/275/resized/CFS-cable-float-rod-multi.png?1473140679https://www.indiamart.com/proddetail/tilt-type-level-switch-11497259548.htmlOf course, don't put high voltage in the switch in order not to electrocute somebody in case the box leaks.

author: aurel9x1
author_rank: Contributor
timestamp: August 08, 2020, 09:46:11 pm
content: If you don't have an oscilloscope, a simple solution to see what's happening on the wire is to connect an LED+resistor to that wire. If the frequency is not high, the LED shows you what's happening on the line. Sometimes you can use this trick (example: to diagnose when a LCD pin is set high and when goes down).

author: Siwastaja
author_rank: Super Contributor
timestamp: August 09, 2020, 06:04:50 am
content: Quote from: aurel9x1 on August 08, 2020, 09:46:11 pmHC-SR04 outputs pulses directly related to the time it takes to get the echo back. No way you can eyeball it in a range of a few meters, you need approx. millisecond precision.

author: TopGun
author_rank: Contributor
timestamp: August 09, 2020, 07:50:58 am
content: I need to know the liquid level at any given time, not just at some preset positions. The tank contains water mixed with some non corrosive fertilizers.I have tried putting a large plastic floater to reflect the ultrasound better. It doesn't work. Also, the sensor has the same behaviour outside the tank, so I'm not sure what effect that will have...

author: TopGun
author_rank: Contributor
timestamp: August 09, 2020, 07:54:29 am
content: Would a pressure sensor work? If I knew the head pressure and density, I can calculate the level with reasonable accuracy?

author: rhodges
author_rank: Frequent Contributor
timestamp: August 09, 2020, 12:40:18 pm
content: Here is one of my projects using the HC-SR04 (wiki):https://github.com/unfrozen/tank_mon/wikiPictures:https://github.com/unfrozen/tank_mon/wiki/Water-tank-picturesIt uses a cheap STM8S103 board and a TM1638 display and keypad module.Feel free to contact me if you have questions.

author: MosherIV
author_rank: Super Contributor
timestamp: August 09, 2020, 12:49:42 pm
content: You might be getting interference from echos from the container sides.Although the sensor has output and input transducers, the output is not a simple straight beam, it form a cone going out from the output transducer. When this cone gets wide enough to hit the sides of container, it will reflect around the inside of container until reflections diminish or they reach thr input transducer.That is why your bench experiment works perfectly but does not work in your container.

author: TopGun
author_rank: Contributor
timestamp: August 09, 2020, 06:59:31 pm
content: Hey mosherIV, as I said in a previous post, the sensor behaves similarly on the bench too, so it doesn't appear to be an echo issue. But, I figured out today that in my 18 years of existence, I never learned to read. The datasheet for the sensor says that it's supposed to have a VCC of 5V, which I provided. But my sensor specifically has 3.3V in silk screen written next to the TRIG pin. So apparently it has a 3.3V logic level (?) So I tried connecting it to a Pro Micro with the same code. It works very accurately now. Thanks for all your suggestions.