VL53L0X on ESP8266: sending nan-values after some time

Good evening everyone,

I recently used my second ESP8266 ever to monitor the water level in my coffee machine (somehow duplicating the work already being discussed here and here, which I only found out now trying to solve my error message)…

The goal:
Use VL53L0X Time of flight-sensor to measure distance to water level in tank, do some first filtering/smooth the values sent to HA (where the conversion to % fill level is done); at the same time flash an LED if the water level drops below a certain level (i.e. the distance is greater than 0,22m), in order to notify me also “offline”.

The code currently used (please excuse the code quality, it’s only my no2^^):

substitutions:
  friendly_name: Espressomaschine Füllstand

esphome:
  name: esp8266-espressotank

esp8266:
  board: esp01_1m

# Enable logging
logger:
# Enable Home Assistant API
api:
# Enable OTA updater
ota:
  password: ******************
# Define WiFi credentials
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp8266-Espressotank"
    password: ******************
# Enable backup http web portal
captive_portal:


# Enable I²C bus
i2c:
  sda: 4
  scl: 5


text_sensor:
  # Send IP Address
  - platform: wifi_info
    ip_address:
      name: $friendly_name IP-Addresse
  # Send Uptime in raw seconds
  - platform: template
    name: $friendly_name Uptime
    id: uptime_human
    icon: mdi:clock-start


# Define LED as output
output:
  - platform: gpio
    pin: GPIO13
    id: gpio_d7


sensor:
  # Send WiFi signal strength & uptime to HA
  - platform: wifi_signal
    name: $friendly_name WLAN-Signal
    update_interval: 60s
  # Convert uptime into human readable string
  - platform: uptime
    name: $friendly_name Uptime
    id: uptime_sensor
    update_interval: 60s
    on_raw_value:
      then:
        - text_sensor.template.publish:
            id: uptime_human
            # Custom C++ code to generate the result
            state: !lambda |-
              int seconds = round(id(uptime_sensor).raw_state);
              int days = seconds / (24 * 3600);
              seconds = seconds % (24 * 3600);
              int hours = seconds / 3600;
              seconds = seconds % 3600;
              int minutes = seconds /  60;
              seconds = seconds % 60;
              return (
                (days ? to_string(days) + "d " : "") +
                (hours ? to_string(hours) + "h " : "") +
                (minutes ? to_string(minutes) + "m " : "") +
                (to_string(seconds) + "s")
              ).c_str();
  # Integrate VL53L0X Time Of Flight Distance Sensor
  - platform: vl53l0x
    name: $friendly_name Distanz
    update_interval: 3s
    unit_of_measurement: "m"
    icon: "mdi:waves-arrow-up"
    id: "distance_measurement"
    state_class: "measurement"
    timeout: 100ms
    accuracy_decimals: 3
    filters:
      - median:
          window_size: 11
          send_every: 1
          send_first_at: 1
    on_value:
      then:
      - if:
          condition:
            sensor.in_range:
              id: distance_measurement
              above: 0.22
          then:
          - output.turn_on: gpio_d7
          - delay: 500ms
          - output.turn_off: gpio_d7
          - delay: 500ms
          - output.turn_on: gpio_d7
          - delay: 500ms
          - output.turn_off: gpio_d7
          - delay: 500ms
          - output.turn_on: gpio_d7
          - delay: 500ms
          - output.turn_off: gpio_d7


switch:
  # Expose an ESP8266 restart button to HA
  - platform: restart
    name: "Neustart ESP8266 Espressotank"

The problem:
After some time (can be immediately after boot-up of ESP8266, can be after veeery long, can sometimes be triggered by moving the sensor around, i.e. creating wildly changing sensor readings), the proper sensor readings stop with error message

[01:05:04][D][sensor:124]: 'Espressomaschine Füllstand Distanz': Sending state nan m with 3 decimals of accuracy
[01:05:04][W][vl53l0x:264]: Espressomaschine Füllstand Distanz - update called before prior reading complete - initiated:0 waiting_for_interrupt:1

Full log of a typical runtime:

INFO Reading configuration /config/esphome/esp8266-espressotank.yaml...
INFO Starting log output from esp8266-espressotank.local using esphome API
INFO Successfully connected to esp8266-espressotank.local
[00:34:04][D][api.connection:861]: Home Assistant 2022.7.6 (###.###.###.###): Connected successfully
[00:34:04][I][app:102]: ESPHome version 2022.6.2 compiled on Jul 22 2022, 17:18:08
[00:34:04][C][wifi:491]: WiFi:
[00:34:04][C][wifi:353]:   Local MAC: ##:##:##:##:##:##
[00:34:04][C][wifi:354]:   SSID: 'secret_SSID'
[00:34:04][C][wifi:355]:   IP Address: ###.###.###.###
[00:34:04][C][wifi:356]:   BSSID: ##:##:##:##:##:##
[00:34:04][C][wifi:358]:   Hostname: 'esp8266-espressotank'
[00:34:04][C][wifi:360]:   Signal strength: -59 dB ▂▄▆█
[00:34:04][C][wifi:364]:   Channel: 1
[00:34:04][C][wifi:365]:   Subnet: ###.###.###.###
[00:34:04][C][wifi:366]:   Gateway: ###.###.###.###
[00:34:04][C][wifi:367]:   DNS1: ###.###.###.###
[00:34:04][C][wifi:368]:   DNS2: ###.###.###.###
[00:34:04][C][logger:275]: Logger:
[00:34:04][C][logger:276]:   Level: DEBUG
[00:34:04][C][logger:277]:   Log Baud Rate: 115200
[00:34:04][C][logger:278]:   Hardware UART: UART0
[00:34:04][C][i2c.arduino:038]: I2C Bus:
[00:34:04][C][i2c.arduino:039]:   SDA Pin: GPIO4
[00:34:04][C][i2c.arduino:040]:   SCL Pin: GPIO5
[00:34:04][C][i2c.arduino:041]:   Frequency: 50000 Hz
[00:34:04][C][i2c.arduino:044]:   Recovery: bus successfully recovered
[00:34:04][I][i2c.arduino:054]: Results from i2c bus scan:
[00:34:04][I][i2c.arduino:060]: Found i2c device at address 0x29
[00:34:04][C][template.text_sensor:021]: Template Sensor 'Espressomaschine Füllstand Uptime'
[00:34:04][C][template.text_sensor:021]:   Icon: 'mdi:clock-start'
[00:34:05][C][gpio.output:010]: GPIO Binary Output:
[00:34:05][C][gpio.output:011]:   Pin: GPIO13
[00:34:05][C][uptime.sensor:031]: Uptime Sensor 'Espressomaschine Füllstand Uptime'
[00:34:05][C][uptime.sensor:031]:   State Class: 'total_increasing'
[00:34:05][C][uptime.sensor:031]:   Unit of Measurement: 's'
[00:34:05][C][uptime.sensor:031]:   Accuracy Decimals: 0
[00:34:05][C][uptime.sensor:031]:   Icon: 'mdi:timer-outline'
[00:34:05][C][vl53l0x:024]: VL53L0X 'Espressomaschine Füllstand Distanz'
[00:34:05][C][vl53l0x:024]:   State Class: 'measurement'
[00:34:05][C][vl53l0x:024]:   Unit of Measurement: 'm'
[00:34:05][C][vl53l0x:024]:   Accuracy Decimals: 3
[00:34:05][C][vl53l0x:024]:   Icon: 'mdi:waves-arrow-up'
[00:34:05][C][vl53l0x:025]:   Update Interval: 3.0s
[00:34:05][C][vl53l0x:026]:   Address: 0x29
[00:34:05][C][vl53l0x:030]:   Timeout: 10000us
[00:34:05][C][restart:022]: Restart Switch 'Neustart ESP8266 Espressotank'
[00:34:05][C][restart:022]:   Icon: 'mdi:restart'
[00:34:05][C][captive_portal:088]: Captive Portal:
[00:34:05][C][mdns:084]: mDNS:
[00:34:05][C][mdns:085]:   Hostname: esp8266-espressotank
[00:34:05][C][ota:085]: Over-The-Air Updates:
[00:34:05][C][ota:086]:   Address: esp8266-espressotank.local:8266
[00:34:05][C][ota:089]:   Using Password.
[00:34:05][C][api:138]: API Server:
[00:34:05][C][api:139]:   Address: esp8266-espressotank.local:6053
[00:34:05][C][api:143]:   Using noise encryption: NO
[00:34:05][C][wifi_info:009]: WifiInfo IPAddress 'Espressomaschine Füllstand IP-Addresse'
[00:34:05][C][wifi_signal.sensor:009]: WiFi Signal 'Espressomaschine Füllstand WLAN-Signal'
[00:34:05][C][wifi_signal.sensor:009]:   Device Class: 'signal_strength'
[00:34:05][C][wifi_signal.sensor:009]:   State Class: 'measurement'
[00:34:05][C][wifi_signal.sensor:009]:   Unit of Measurement: 'dBm'
[00:34:05][C][wifi_signal.sensor:009]:   Accuracy Decimals: 0
[00:34:06][D][vl53l0x:264]: 'Espressomaschine Füllstand Distanz' - Got distance 0.104 m
[00:34:06][D][sensor:124]: 'Espressomaschine Füllstand Distanz': Sending state 0.10400 m with 3 decimals of accuracy
[00:34:09][D][vl53l0x:264]: 'Espressomaschine Füllstand Distanz' - Got distance 0.101 m
[00:34:09][D][sensor:124]: 'Espressomaschine Füllstand Distanz': Sending state 0.10100 m with 3 decimals of accuracy
[00:34:12][D][vl53l0x:264]: 'Espressomaschine Füllstand Distanz' - Got distance 0.097 m
[00:34:12][D][sensor:124]: 'Espressomaschine Füllstand Distanz': Sending state 0.09700 m with 3 decimals of accuracy
[00:34:15][D][vl53l0x:264]: 'Espressomaschine Füllstand Distanz' - Got distance 0.098 m
[00:34:15][D][sensor:124]: 'Espressomaschine Füllstand Distanz': Sending state 0.09800 m with 3 decimals of accuracy
[00:34:18][D][vl53l0x:264]: 'Espressomaschine Füllstand Distanz' - Got distance 0.098 m
[00:34:18][D][sensor:124]: 'Espressomaschine Füllstand Distanz': Sending state 0.09800 m with 3 decimals of accuracy
[00:34:21][D][vl53l0x:264]: 'Espressomaschine Füllstand Distanz' - Got distance 0.102 m
[00:34:21][D][sensor:124]: 'Espressomaschine Füllstand Distanz': Sending state 0.10200 m with 3 decimals of accuracy

[...]

[01:04:31][D][vl53l0x:308]: 'Espressomaschine Füllstand Distanz' - Got distance 0.100 m
[01:04:31][D][sensor:124]: 'Espressomaschine Füllstand Distanz': Sending state 0.10000 m with 3 decimals of accuracy
[01:04:34][D][vl53l0x:308]: 'Espressomaschine Füllstand Distanz' - Got distance 0.098 m
[01:04:34][D][sensor:124]: 'Espressomaschine Füllstand Distanz': Sending state 0.09800 m with 3 decimals of accuracy
[01:04:37][D][vl53l0x:308]: 'Espressomaschine Füllstand Distanz' - Got distance 0.099 m
[01:04:37][D][sensor:124]: 'Espressomaschine Füllstand Distanz': Sending state 0.09900 m with 3 decimals of accuracy
[01:04:40][D][vl53l0x:308]: 'Espressomaschine Füllstand Distanz' - Got distance 0.096 m
[01:04:40][D][sensor:124]: 'Espressomaschine Füllstand Distanz': Sending state 0.09600 m with 3 decimals of accuracy
[01:04:46][D][sensor:124]: 'Espressomaschine Füllstand Distanz': Sending state nan m with 3 decimals of accuracy
[01:04:46][W][vl53l0x:264]: Espressomaschine Füllstand Distanz - update called before prior reading complete - initiated:0 waiting_for_interrupt:1
[01:04:49][D][sensor:124]: 'Espressomaschine Füllstand Distanz': Sending state nan m with 3 decimals of accuracy
[01:04:49][W][vl53l0x:264]: Espressomaschine Füllstand Distanz - update called before prior reading complete - initiated:0 waiting_for_interrupt:1
[01:04:52][D][sensor:124]: 'Espressomaschine Füllstand Distanz': Sending state nan m with 3 decimals of accuracy
[01:04:52][W][vl53l0x:264]: Espressomaschine Füllstand Distanz - update called before prior reading complete - initiated:0 waiting_for_interrupt:1
[01:04:55][D][sensor:124]: 'Espressomaschine Füllstand Distanz': Sending state nan m with 3 decimals of accuracy
[01:04:55][W][vl53l0x:264]: Espressomaschine Füllstand Distanz - update called before prior reading complete - initiated:0 waiting_for_interrupt:1
[01:04:57][D][text_sensor:067]: 'Espressomaschine Füllstand Uptime': Sending state '26m 44s'
[01:04:57][D][sensor:124]: 'Espressomaschine Füllstand Uptime': Sending state 1603.89600 s with 0 decimals of accuracy
[01:04:58][D][sensor:124]: 'Espressomaschine Füllstand Distanz': Sending state nan m with 3 decimals of accuracy
[01:04:58][W][vl53l0x:264]: Espressomaschine Füllstand Distanz - update called before prior reading complete - initiated:0 waiting_for_interrupt:1
[01:05:01][D][sensor:124]: 'Espressomaschine Füllstand Distanz': Sending state nan m with 3 decimals of accuracy
[01:05:01][W][vl53l0x:264]: Espressomaschine Füllstand Distanz - update called before prior reading complete - initiated:0 waiting_for_interrupt:1
[01:05:04][D][sensor:124]: 'Espressomaschine Füllstand Distanz': Sending state nan m with 3 decimals of accuracy
[01:05:04][W][vl53l0x:264]: Espressomaschine Füllstand Distanz - update called before prior reading complete - initiated:0 waiting_for_interrupt:1

Any ideas, anyone?
I realize that there seems to be one dropped measurement (between time codes 01:04:40 and 01:04:46 in the log, usually only 3secs) - but honestly have neither a clue why, nor where to start digging.
I already experimented with the timeout-parameter (<> 100ms, disabled the filter, also disabled the LED-/GPIO-toggle…), with no success.
I also found this approach to convert nan-values here, which would be acceptable if my sensor would not give 100% nan-readings once it got off the rails…^^

(A bit off-topic, I’d also appreciate hints toward a more elegant way to implement the LED flashing if distance > threshold).

Thanks a lot in advance!

I would try increasing the update interval, I run mine at 15s. Also remove the timeout.

Hi Brad, thanks for the hints - implemented and tested both this afternoon, even played around with other update intervals that should avoid same-time-interference with the other sensors, but unfortunately didn’t see any improvement…
The widely varying duration while the sensor keeps logging correctly before “dying” made me think about something hardware-related, and as I read about the sensor’s sensitivity to bad wiring, I changed everything to new cables, now being soldered - but still the same.
Very confusing.

did you figure out what the problem was? i’m running into the exact same problem and can’t find a reliable fix

Some of my standard steps are:

  • Check all connections
  • Try different pins
  • Try a different sensor (I always buy a few spares)
  • Try a different board (again, I always have spares)
  • Try 3v3 or 5v if the device allows it.
  • Try another power source.
  • Try another usb cable.

Hey @meyerjh2001 I’ve encountered the same issue, and it drove me crazy, I’ve tested it with:

  • different cables
  • replace the VL53L0X sensors
  • used ESP32 instead of ESP8266
  • played with various ESPHOME settings

But nothing helped…

Today I discovered that it almost every time faults (sent nan-values) after I turn on my espresso machine.
So might be electromagnetic interference from the heating element/pump?

What I did as a workaround:

add a restart switch to the ESPHOME sensor config:

switch:
  - platform: restart
    name: "Restart Water Tank Sensor"

And create an automation to restart the sensor as soon as it gets unavailable:

- alias: Restart Water Tank Sensor
  trigger:
    - platform: state
      entity_id: sensor.coffee_water_tank_percent
      to: 'unavailable'
  action:
    - service: switch.turn_on
      entity_id: switch.restart_water_tank_sensor

hope this helps :slight_smile:

:grinning_face_with_smiling_eyes:
Thanks a lot for getting back to this somehow stale topic. Honestly, I didn’t test the impact of switched on/off espresso machine so far - will do that probably tomorrow… but yes, I also realized that it’s very different how long the sensor readings stay alive, thinking back the reason you point to seems plausible.
Will let you know!

And thanks even more for the suggested work around: I thought about this option too, but so far left it unimplemented because i) it seems a bit like brute force to me :upside_down_face: :stuck_out_tongue:, and ii) I wanted to hand over one or two of these tank level sensors (then with flashing LEDs as indicator, see my initial YAML above) to other espresso machine owners, who don’t run ESPhome/HomeAssistant - so this restart-route would not be an option for them…

Anyways, after I emptied my tank again yesterday, sucking in air during a row of coffees and the sensor not updating/warning in between, I might re-consider this route :face_with_raised_eyebrow: :thinking:

Sorry @Steffen_Pohl , only read your post now - but see below, so far no news on that end…
Also referring to @Mahko_Mahko and his check list, I checked/did…

  • fix connections (even soldered the ones previously on jumper cables)
  • use other pins
  • mix-and-match other boards and sensors (both same type, but different pieces - so I sticked to “my” ESP8266, where @reentec was more diligent when also switching over to ESP32)
  • replace replace the power source (significantly stronger ones, cheap + expensive cables, long & short)

The only thing I didn’t test was to go from 5v to 3,3v, simply because I don’t have an appropriate power source for almost-always-on available.

But a new lead might actually be this electromagnetic interference… will see!

Thank you for the reply.
I actually got it working by switching the boards. Exactly the same code, but instead of using an M5Stack ATOM Lite ESP32, I installed it on a no-brand esp32 from aliexpress, and so far it’s working flawlessly.
So it was definitely a hardwareproblem on my end.

Hopefully this helps someone else (not just switching boards, but actually using another type of board). Sorry this didn’t work for you.

1 Like

Interesting - mine are AZDelivery NodeMCU Amica Modul V2 ESP8266 ESP-12F, and I can confirm that they do NOT withstand the espresso machine running)

Could you be more specific on your no-name versions? I might be willing to use wintertime for another attempt and migration into ESP32 :wink:

sorry for the late reply, I checked and it was actually not from aliexpress, but also from AZ-Delivery:

These ones

They’re Esp 32 though, not 8266 like yours, so maybe there’s a difference?

Also, this is the code that works for me:

> i2c:
>   sda: GPIO32
>   scl: GPIO33
>   scan: true
>   id: bus_a    
> sensor:
>   - platform: vl53l0x
>     name: "Distance2"
>     address: 0x29
>     update_interval: 200ms
>     id: distance2
>     accuracy_decimals: 2
>     filters:
>       - delta: 0.002