LD2420 based presence sensor suddenly unstable

I’ve had a LD2420 based presence sensor that has been rock solid stable for months if not a year. Suddenly it seems to be very unreliable, almost loses config or something then basically requires a hard reset (pulling power, simply rebooting the esp32 via software doesn’t work)

Any ideas here? I have the hardware to simply replace everything but I’d like to get to the bottom of it and understand what’s going on. The yaml is full “stock” as listed in the general guide from esphome pages. Is there a way to pull any kind of logs to troubleshoot?

Appreciate it!

Are you running ESPHome builder? If so, click on the logs button.

I never found the sample code to be that stable. If your requirement is simple motion detection, use the sample code to set the parameters, then remove everything except the binary sensor for motion on the presence signal pin.

I didn’t see anything obvious in the logs at all. The best way I can describe it is that it’s almost as if it’s configuration just “goes away”. Hard reboot (pull power) brings it back - then after several hours it just happens again… This is pre-reboot after it’s stopped working:


and log output (pre-reboot) as you can see it’s “lost” all data about the LD2420 just as displayed in the UI:

[13:17:34][C][wifi:434]:   Local MAC: [redacted]
[13:17:34][C][wifi:439]:   SSID: [redacted]
[13:17:34][C][wifi:442]:   IP Address: 192.168.2.253
[13:17:34][C][wifi:446]:   BSSID: [redacted]
[13:17:34][C][wifi:446]:   Hostname: 'esphome-web-ecb2a7'
[13:17:34][C][wifi:446]:   Signal strength: -52 dB ▂▄▆█
[13:17:34][C][wifi:455]:   Channel: 11
[13:17:34][C][wifi:455]:   Subnet: 255.255.255.0
[13:17:34][C][wifi:455]:   Gateway: 192.168.2.1
[13:17:34][C][wifi:455]:   DNS1: 192.168.2.1
[13:17:34][C][wifi:455]:   DNS2: 0.0.0.0
[13:17:34][C][logger:246]: Logger:
[13:17:34][C][logger:246]:   Max Level: DEBUG
[13:17:34][C][logger:246]:   Initial Level: DEBUG
[13:17:34][C][logger:252]:   Log Baud Rate: 0
[13:17:34][C][logger:252]:   Hardware UART: UART0
[13:17:34][C][uart.arduino_esp8266:118]: UART Bus:
[13:17:34][C][uart.arduino_esp8266:119]:   TX Pin: GPIO1
[13:17:34][C][uart.arduino_esp8266:120]:   RX Pin: GPIO3
[13:17:34][C][uart.arduino_esp8266:122]:   RX Buffer Size: 256
[13:17:34][C][uart.arduino_esp8266:124]:   Baud Rate: 115200 baud
[13:17:34][C][uart.arduino_esp8266:124]:   Data Bits: 8
[13:17:34][C][uart.arduino_esp8266:124]:   Parity: NONE
[13:17:34][C][uart.arduino_esp8266:124]:   Stop bits: 1
[13:17:34][C][uart.arduino_esp8266:131]:   Using hardware serial interface.
[13:17:34][C][ld2420:187]: LD2420:
[13:17:34][C][ld2420:187]:   Firmware version:  v0.0.0
[13:17:34][C][ld2420:192]: Number:
[13:17:34][C][ld2420:193]:   Gate Timeout: 'Detection Presence Timeout'
[13:17:34][C][ld2420:193]:     Icon: 'mdi:timelapse'
[13:17:34][C][ld2420:193]:     Unit of Measurement: 's'
[13:17:34][C][ld2420:194]:   Gate Max Distance: 'Detection Gate Maximum'
[13:17:34][C][ld2420:194]:     Icon: 'mdi:motion-sensor'
[13:17:34][C][ld2420:194]:     Device Class: 'distance'
[13:17:34][C][ld2420:195]:   Gate Min Distance: 'Detection Gate Minimum'
[13:17:34][C][ld2420:195]:     Icon: 'mdi:motion-sensor'
[13:17:34][C][ld2420:195]:     Device Class: 'distance'
[13:17:34][C][ld2420:196]:   Gate Select: 'Select Gate to Set'
[13:17:34][C][ld2420:196]:     Icon: 'mdi:motion-sensor'
[13:17:34][C][ld2420:196]:     Device Class: 'distance'
[13:17:34][C][ld2420:198]:   Gate Move Threshold: 'Set Move Threshold Value'
[13:17:34][C][ld2420:198]:     Icon: 'mdi:motion-sensor'
[13:17:34][C][ld2420:199]:   Gate Still Threshold:: 'Set Still Threshold Value'
[13:17:34][C][ld2420:199]:     Icon: 'mdi:motion-sensor'
[13:17:34][C][ld2420:203]:   Apply Config: 'Apply Config'
[13:17:34][C][ld2420:203]:     Icon: 'mdi:restart-alert'
[13:17:34][C][ld2420:204]:   Revert Edits: 'Undo Edits'
[13:17:34][C][ld2420:204]:     Icon: 'mdi:restart'
[13:17:34][C][ld2420:205]:   Factory Reset: 'Factory Reset'
[13:17:34][C][ld2420:205]:     Icon: 'mdi:database'
[13:17:34][C][ld2420:206]:   Restart Module: 'Restart Module'
[13:17:34][C][ld2420.sensor:011]: Sensor:
[13:17:34][C][ld2420.sensor:012]:   Distance 'Moving Distance'
[13:17:34][C][ld2420.sensor:012]:     State Class: ''
[13:17:34][C][ld2420.sensor:012]:     Unit of Measurement: 'cm'
[13:17:34][C][ld2420.sensor:012]:     Accuracy Decimals: 0
[13:17:34][C][ld2420.sensor:012]:     Device Class: 'distance'
[13:17:34][C][ld2420.binary_sensor:011]: Binary Sensor:
[13:17:34][C][ld2420.binary_sensor:012]:   Presence 'Presence'
[13:17:34][C][ld2420.binary_sensor:012]:     Device Class: 'occupancy'
[13:17:34][C][restart:079]: Restart Switch 'Restart ESPHome Node'
[13:17:34][C][restart:079]:   Restore Mode: always OFF
[13:17:34][C][restart:087]:   Icon: 'mdi:restart'
[13:17:34][C][captive_portal:099]: Captive Portal:
[13:17:34][C][web_server:310]: Web Server:
[13:17:34][C][web_server:310]:   Address: esphome-web-ecb2a7.local:80
[13:17:34][C][esphome.ota:073]: Over-The-Air updates:
[13:17:34][C][esphome.ota:073]:   Address: esphome-web-ecb2a7.local:8266
[13:17:34][C][esphome.ota:073]:   Version: 2
[13:17:34][C][safe_mode:018]: Safe Mode:
[13:17:34][C][safe_mode:019]:   Boot considered successful after 60 seconds
[13:17:34][C][safe_mode:019]:   Invoke after 10 boot attempts
[13:17:34][C][safe_mode:019]:   Remain for 300 seconds
[13:17:34][C][web_server.ota:224]: Web Server OTA
[13:17:34][C][api:207]: API Server:
[13:17:34][C][api:207]:   Address: esphome-web-ecb2a7.local:6053
[13:17:34][C][api:217]:   Using noise encryption: NO
[13:17:34][C][mdns:122]: mDNS:
[13:17:34][C][mdns:122]:   Hostname: esphome-web-ecb2a7

This is post hard reboot and it’s working again:


of course the logs reflect normal operation again as well.

The YAML I’m using in ESPHome Builder is:

substitutions:
  name: esphome-web-ecb2a7
  friendly_name: Office Presence

esphome:
  name: ${name}
  friendly_name: ${friendly_name}
  min_version: 2024.6.0
  name_add_mac_suffix: false
  project:
    name: esphome.web
    version: dev

esp8266:
  board: d1_mini_lite

# Enable logging
logger:
  baud_rate: 0

# Enable Home Assistant API
api:

# Allow Over-The-Air updates
ota:
- platform: esphome

# Allow provisioning Wi-Fi via serial
#improv_serial:

wifi:
  # Set up a wifi access point
  ap: {}

# In combination with the `ap` this allows the user
# to provision wifi credentials to the device via WiFi AP.
captive_portal:

dashboard_import:
  package_import_url: github://esphome/example-configs/esphome-web/esp8266.yaml@main
  import_full_config: true

# To have a "next url" for improv serial
web_server:

# UART required to talk to LD2420 Presence sensor    
uart:
  tx_pin: GPIO01
  rx_pin: GPIO03
  #baud_rate: 256000
  baud_rate: 115200
  parity: NONE
  stop_bits: 1

ld2420: 

text_sensor:
  - platform: ld2420
    fw_version:
      name: LD2420 Firmware

sensor:
  - platform: ld2420
    moving_distance:
      name : Moving Distance

binary_sensor:
  - platform: ld2420
    has_target:
      name: Presence

switch:
  - platform: restart
    name: Restart ESPHome Node

select:
  - platform: ld2420
    operating_mode:
      name: Operating Mode

number:
  - platform: ld2420
    presence_timeout:
      name: Detection Presence Timeout
    min_gate_distance:
      name: Detection Gate Minimum
    max_gate_distance:
      name: Detection Gate Maximum
    gate_select:
      name: Select Gate to Set
    still_threshold:
      name: Set Still Threshold Value
    move_threshold:
      name: Set Move Threshold Value
button:
  - platform: ld2420
    apply_config:
      name: Apply Config
    factory_reset:
      name: Factory Reset
    restart_module:
      name: Restart Module
    revert_config:
      name: Undo Edits

Any thoughts here? Would also love to see any other YAML that you’ve found to be more stable.

less than 8 hours go by before it goes into what I’m calling the “lost config” state - trying to narrow down the timeline further but today that’s what I’ve been able to determine.

It’s possibly a memory leak somewhere - you are using a lower end chip and then adding web server to the mix.

Web server is handy if you are tuning your sensor, but if you don’t need it after that remove it as it its memory hungry.

Thx - disabled the webserver - let’s see how that does. Kinda odd though because the YAML hasn’t changed since I deployed it really - the instability just came out of no where.

Disabling the webserver bought me like 48 hours as opposed to ~8 which is great but something is clearly still amiss, any other ideas or sample simplified code? I guess I could also just throw a beafier ESP32 at it but I’d still love to figure out why something that went from rock solid is suddenly not anymore

My only suggestion is to roll back to a previous version, if that works.

I have one device that runs on 2024.11, that was because there were issues with temperature sensors introduced then that I couldn’t be bothered fixing. I have a large project that is still on 2025.5 because the next update changed how http_request: was handled and it broke badly.

I use the “Legacy ESPHome versions repository” which means I can have previous versions of the builder running in parallel to the current one.

BTW there were changes to the Arduino framework that main affected ESP32s (considerable increase in size) that happened with 2025/7. Possibly caused memory issues with ESP8266? There’s nothing in the release notes though.

I am experimenting with ESPHome and the LD2420 and I have the exact same issue: it works well for a few hours, then it just freezes and becomes unusable requiring a complete hardware reset.

Any update on this?

(p.s. will submit this as an issue on Github if no one else did…)

UPDATE: I have updated ESPHome to 2025.8.4 recently and since then I get a lot more mileage with my prototype LD2420 based presence sensor module. Hopefully (fingers crossed) the issue was fixed for good…

I’ll wait a while longer though before calling it conclusive…

Good news: I can say now that it works without fail, so this is a non-issue now. Thanks to whoever fixed it in ESPhome… :+1: