ESP8266 and JSN-SR04T-2.0 inconsistent results

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
Post Reply
greg_the_aussie
Posts: 5
Joined: Wed Jul 03, 2019 8:32 pm

ESP8266 and JSN-SR04T-2.0 inconsistent results

Post by greg_the_aussie » Mon Sep 14, 2020 11:40 am

Hello folks

I have a concrete, in-ground water tank for my domestic water storage. There's no easy way to monitor the water level so I have started to put together an ultrasonic depth sensor with the intention of viewing a graph of the depth across a couple of months, measured once each day. I plan to drill through the top of the tank and mo9un t the sensor vertically pointing straight down at the water surface. Someone has previously done this using an Arduino but I wanted to use the ESP8266.
I have the ESP8266 powered from my laptop (usb) but communicating across wifi - webrepl. I have jumper wires from the ESP8266 to a breadboard and from there to the four pins of the JSN-SR04T-2.0 board. The sensor is pointing at a plaster wall 112cm away.
With all the hardware static and as few connections as possible I get readings from 77cm to 108cm.
I'm hoping for insights about possible causes for the inaccuracy. My code is pretty primitive as I'm very green

Code: Select all

import machine

#Nominate a trigger pin on ESP8266 and declare it as an output pin
trigger = machine.Pin((14), machine.Pin.OUT)

#Nominate an echo pin and declare it as an input pin
echo = machine.Pin((12), machine.Pin.IN)

#Set the trigger high for 10 microseconds
import utime
trigger.value(0)
utime.sleep_us(10)
trigger.value(1)

#Set a timer to monitor the echo pin for a couple of seconds
pulse = machine.time_pulse_us(echo,1)

#Return the duration of the echo pulse
print ('Echo duration:', pulse)

#Calculate the distance to the surface based on the speed of sound.
distance = (pulse/1000000)*34000/2
print('Distance:', distance,'cm')

#Write the distance to the surface to a file
water_level = open("water_level.txt","a")
print('Distance:', distance,'cm', file = water_level)
water_level.close()
Might the problem be with my hardware or connections if my code is OK? It's pretty basic stuff so I'm bewildered by the variance in the returned distances.

Thanks for any help you can offer.

kevinkk525
Posts: 765
Joined: Sat Feb 03, 2018 7:02 pm

Re: ESP8266 and JSN-SR04T-2.0 inconsistent results

Post by kevinkk525 » Mon Sep 14, 2020 12:57 pm

I wrote a module for the hcsr04 which is rather simila to the JSN-SR04T so the same problems probably apply.
I found that a single measurement is often not accurate enough or results in a reading error or way to long/short distance.
So I take multiple measurements (configureable), discard the extreme values, discard "impossible" values (longer than the distance to e.g. the bottom of your tank, shorter than the minimum reading length) and if enough values are left, the average of those is being used.
Additionally if a temperature sensor is available, the measurement will be corrected by the current temperature.

This way I am able to get a fairly accurate measurement. However, I didn't get to actually deploying it in my tank so it is just sitting on my desk measuring the distance to the next wall..
But maybe it'll help you get better results: https://github.com/kevinkk525/pysmartno ... /hcsr04.py
Kevin Köck
Micropython Smarthome Firmware (with Home-Assistant integration): https://github.com/kevinkk525/pysmartnode

greg_the_aussie
Posts: 5
Joined: Wed Jul 03, 2019 8:32 pm

Re: ESP8266 and JSN-SR04T-2.0 inconsistent results

Post by greg_the_aussie » Wed Sep 16, 2020 11:40 am

Big step in the right direction.

I found a hint in another arduino forum about using this sensor. The hint was to explicitly set the trigger low and let it settle before setting it high to initiate the trigger. The result is that the distance measurements are tolerably accurate for a water tank and more importantly the deviations have become trivial to a few millimetres.

I'm not sure whether explicitly setting and holding the trigger low before setting it high is an improvement to the code, or helps to stabilise the hardware. Either way, the result is very good.

Maybe you electronics engineers and coding ninjas can advise whether my code was inadequate and the addition of these couple of lines filled a void. Alternatively might the nodemcu pin have been 'floating' before I explicitly set it low, meaning the beginning of the trigger pulse was not controlled. The next reader might appreciate your input in the same way someone else's advice helped me out.

Thank you to those who took the time to read my question and give it some thought. I'm very appreciative of the questions and advice posted on this forum.

Code: Select all

#Set and hold the trigger low.
import utime
trigger.value(1)
utime.sleep(2)
#Set the trigger high for 15 microseconds
trigger.value(0)
utime.sleep_us(15)
trigger.value(1)

Post Reply