With this part of the ESPHome .yaml code loaded into an ESP32-WROOM-32 for a JSN-SR04T-2.0 sensor (default settings / no resistor soldered into R27):
sensor:
- platform: ultrasonic
trigger_pin: GPIO5 # D5
echo_pin: GPIO18 # D18
name: "JSN-SR04T Distance"
update_interval: 5s
unit_of_measurement: "cm"
accuracy_decimals: 1
timeout: 2.0m
filters:
- lambda: |-
if (x < 0.1 || x > 4.5) {
return NAN; // Return NAN for out-of-range values
}
float value_in_cm = x * 100; // Convert meters to cm height above floor
return int(value_in_cm * 100 + 0.5) / 100.0; // Round to 2 decimal places
I’m wondering why I periodically see readings like this:
[21:40:45.775][D][ultrasonic.sensor:035]: 'JSN-SR04T Distance' - Distance measurement timed out!
[21:40:45.831][D][sensor:135]: 'JSN-SR04T Distance': Sending state 21474836.00000 cm with 1 decimals of accuracy
… and how to prevent them. I’m just getting started with ESPHome, but what is a return value of NAN actually supposed to accomplish when the reading is out of range?
It looks like the timeout products invalid value (either nan or infinite) that doesn’t get filtered out with your lambda.
Try something like this:
(not tested, if it doesn’t compile, comment out both filter_out: nan lines)
sensor:
- platform: ultrasonic
trigger_pin: GPIO5 # D5
echo_pin: GPIO18 # D18
name: "JSN-SR04T Distance"
update_interval: 5s
unit_of_measurement: "cm"
accuracy_decimals: 1
timeout: 2.0m
filters:
- filter_out: nan
- lambda: |-
if (!isfinite(x)) return NAN;
if (x < 0.22 || x > 4.5) return NAN;
return x * 100.0;
- filter_out: nan # to filter out nans fron lamda
But why you have such a small timeout value? 4.5m would be better to prevent timeouts in the first place.
Also, consider adding median filter (as last filter) to get rid of any outliers or spikes.
Karosm, thank you for your suggestions! I did find that I had to revise the first line of the lambda filter to:
if (!infinity) return NAN;
To answer your question - no good reason for the listed syntax, other than it was based on the first coding I found that would validate, compile and install! Everything else I’d tried beforehand had failed.
This sensor is watching the level in the basement sump hole, and when it rains, the level can rise rather quickly. Not sure if a long or short timeout is better in this particular application.
Code validated, compiled, downloaded! Currently watching the trend …
Next step - configuring SMS messaging to alert me of a high level.
Sensors have timeout filter.
Yours is not under filters, but parameter for ultrasonic sensor. " timeout (Optional, float): The number of meters for the timeout. Most sensors can only sense up to 2 meters. Defaults to 2 meters."
Just wondering if anyone else has experience with these kinds of readings and how they resolved the erratic issue. The sensor is mounted in a 2" cap on the end of a 2" ABS pipe drilled with holes to allow for water in/out flow and air movement. Checked the sensor head - no condensation / deposits. Wondering if the cold temperatures or humidity in the cold cellar may be affecting the sensor or DuPont connections …
ESPHome code:
esphome:
name: esphome-01
friendly_name: ESPHome-01
min_version: 2025.11.0
name_add_mac_suffix: false
esp32:
board: esp32dev
framework:
type: esp-idf
# Example configuration entry
sensor:
- platform: ultrasonic
trigger_pin: GPIO5 # D5
echo_pin: GPIO18 # D18
name: "JSN-SR04T Distance"
update_interval: 5s
unit_of_measurement: "cm"
accuracy_decimals: 1
timeout: 1.0m
filters:
- filter_out: nan
- round: 3
- lambda: |-
if (!infinity) return NAN;
if (x < 0.25 || x > 4.5) return NAN; // Return NAN for out-of-range values
return x * -100 +33; // Convert meters to -cm and compensate
- filter_out: nan # to filter out nan from lambda
- median: # to get rid of outliers and spikes (see Forum)
window_size: 5
send_every: 1
send_first_at: 1
# Enable logging
logger:
# Enable Home Assistant API
api:
port: 6053
batch_delay: 50ms # Reduce latency for real-time applications
listen_backlog: 2 # Allow 2 pending connections in queue
max_connections: 6 # Allow up to 6 simultaneous connections
max_send_queue: 10 # Maximum queued messages per connection before disconnect
encryption:
key: "+++"
reboot_timeout: 30min
# Allow Over-The-Air updates
ota:
- platform: esphome
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
It’s weird that the median filter didn’t filter out those spikes, maybe you should “zoom in” to see why. Also, those smaller spikes all arrive to your normal max line at around -25cm. Doesn’t look like random outliers…
So they are so consistent that they take over median filter. Interestingly the raw measured distance for your spikes is pretty close to half of the normal one. 0.3m vs 0.6m.