New: the AI firewall watches the whole platform and explains each incident in plain words. See how it works

JSN-SR04T waterproof ultrasonic on a Pi 3 gives 0 cm or timeouts for our hostel water tank

JSN-SR04T waterproof ultrasonic on a Pi 3 gives 0 cm or timeouts for our hostel water tank

Solved 9 7

Hi all, student, first real project. Our hostel’s overhead water tank runs dry every few days and the warden wants a warning. I have a Raspberry Pi 3 on the roof (in a box) and a JSN-SR04T v2.0 waterproof ultrasonic sensor looking down into the tank.

I used the standard HC-SR04 Python code with RPi.GPIO: 10 us trigger, then while loops waiting for echo high and low. Echo goes through a 1k/2k divider. Results: about half the readings are 0.0 cm, the rest are timeouts, very rarely a real number like 87 cm. With an HC-SR04 on the bench the same code works perfectly.

dist: 0.0
dist: timeout
dist: timeout
dist: 87.4
dist: 0.0

Once it works I want to send the level to Hermetry and get an alarm when it’s low.

♥ 0

Divider on echo, good. How far is the sensor from the water when the tank is full?

Ground loops are my cardio.
♥ 0

Tank is full now, maybe 15-20 cm?

♥ 0

Which board version is printed on yours? The v2 and v3 behave differently.

Timestamps in UTC or it didn't happen.
♥ 2

It says JSN-SR04T-2.0 on the back.

♥ 0

Maybe add a time.sleep(0.5) between readings? I read they need time to settle.

Measure twice, poll once.
♥ 0

My pool sensor did weird stuff when there was condensation on the face, worth wiping it.

♥ 0

The JSN has a blind zone of roughly 20-25 cm. Anything closer and it either returns nonsense or nothing. HC-SR04 goes down to 2 cm, that’s why the bench test lies to you.

Modbus is just registers until it isn't.
♥ 0

Jessica nailed the main issue: at 15-20 cm you’re inside the blind zone. Mount it higher, a short PVC pipe section as a stand-off works, so full tank is at least 30 cm away.

Second issue is the Python timing. Busy-wait loops on a Pi 3 miss edges whenever the scheduler steps in. Use gpiozero with the pigpio pin factory, it timestamps edges in the daemon:

from gpiozero import DistanceSensor
from gpiozero.pins.pigpio import PiGPIOFactory
import statistics, time

s = DistanceSensor(echo=24, trigger=23, max_distance=4.5,
                   pin_factory=PiGPIOFactory())

def level_cm():
    vals = []
    for _ in range(7):
        vals.append(s.distance * 100); time.sleep(0.1)
    return statistics.median(vals)

Median of 7 throws away the odd echo off the tank wall. Then send {"distance_cm": d, "level_pct": ...} as numbers and put an alarm rule on level_pct below 20 with a debounce of 3 readings, so one bad echo doesn’t wake the warden.

Accepted solution♥ 3

Raised it on a 20 cm pipe piece and switched to your gpiozero code. Now steady readings, 43-45 cm when full, no zeros. Alarm rule is set at level_pct < 20 with 3 readings. Warden got his first real warning yesterday at 6 am.

♥ 1
Viewing 10 posts – 1 through 10 (of 10 total)
  • You must be logged in to reply to this topic.

Join the conversation

Sign in to ask and answer, like helpful posts and mark the reply that solved your problem. Every contribution earns points and levels.

Share