LD2410 esphome tips

I believe the LD2410 was primarily designed for indoor use so I’m not sure how well it will be able to handle not detecting rain.
I would enable Engineering Mode and look at the move and still energy % for each gate (0 to 8) while it is raining with no other movement outside and then adjust all the Move and Still Thresholds to above those for each gate.
I’m also not sure how will handle windy days causing other movements that may get detected.

The ‘Failed to obtain the firmware:-1’ error only appears in the Play store version of the HLKRadarTool app (v1.1.32).

When using v1.1.22 of the app, the available firmwares load and display fine.

Just for info.
Latest HLKRadar update from Play store fixes update fw issue.

1 Like

Thanks. You are correct. The Playstore version has been updated to v1.1.37 and has corrected the firmware issue.

Is it possible to use more than one ld2410 sensor on an esp32?

Scott

1 Like

I have 2 LD2410 via UART, same device (ESP32dev).
The first has more load (2 reed switches, 8x relay board, hall sensor and LD2410) goes sweet.

Have another with same config for LD2410, plus 2 relay, same TX/Rx Pins, give one time this error starting the log:

[E][ld2410:336]: Error with last command : incorrect Header

But works well. The config is from the docs.

Wanted to cross-post this to help folks with getting their sensitivity dialed in:

can you share the yaml? I haven’t been able to get it working.

thx!

Here is the esphome config:



substitutions:
  board_platform: ESP32
  board_type: esp32dev
  devicename: DeViceName
  hostname: DeViceName
  calling_pin: GPIO18
  pedestrian_pin: GPIO21
  #ld2410 uart
  ld_tx_pin: GPIO17
  ld_rx_pin: GPIO16



esphome:
  name: $devicename
  friendly_name: $devicename
  platform: ESP32
  board: esp32dev
 
external_components:
  - source: github://esphome/esphome@dev
    components: [ ld2410 ]
 
# Enable logging
logger:
  level: DEBUG
 
# Enable Home Assistant API
api:
  encryption:
    key: !secret encryption_key
 
ota:
  password: !secret ota_password
  
 
wifi:
  #use_address: 192.168.3.121
  power_save_mode: none
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  
uart:
  id: uart01
  tx_pin: $ld_tx_pin
  rx_pin: $ld_rx_pin
  baud_rate: 256000
  parity: NONE
  stop_bits: 1
 
ld2410:

sensor:
#system
  - platform: wifi_signal
    name: WiFi Signal
    update_interval: 600s
  - platform:  internal_temperature
    name: Temperatura interna
    update_interval: 600s
#LD2410
  - platform: ld2410
    moving_distance:
      name : Distanza movimento
    still_distance:
      name: Distanza da fermo
    moving_energy:
      name: Energia movimento
    still_energy:             
      name: Energia fermo
    detection_distance:
      name: Distanza oggetto
    light:
      name: Luce
    g0:
      move_energy:
        name: g0 move energy
      still_energy:
        name: g0 still energy
    g1:
      move_energy:
        name: g1 move energy
      still_energy:
        name: g1 still energy
    g2:
      move_energy:
        name: g2 move energy
      still_energy:
        name: g2 still energy
    g3:
      move_energy:
        name: g3 move energy
      still_energy:
        name: g3 still energy
    g4:
      move_energy:
        name: g4 move energy
      still_energy:
        name: g4 still energy
    g5:
      move_energy:
        name: g5 move energy
      still_energy:
        name: g5 still energy
    g6:
      move_energy:
        name: g6 move energy
      still_energy:
        name: g6 still energy
    g7:
      move_energy:
        name: g7 move energy
      still_energy:
        name: g7 still energy
    g8:
      move_energy:
        name: g8 move energy
      still_energy:
        name: g8 still energy

binary_sensor:
#LD2410
  - platform: ld2410
    has_target:
      name: Persona
    has_moving_target:
      name: Persona in movimento
    has_still_target:
      name: Persona ferma
    out_pin_presence_status:
      name: out pin presence status
#system
  - platform: status
    name: Stato
  

switch: 
#system     
  - platform: restart
    name: Restart
    id: restart_switch
#LD2410
  - platform: ld2410
    engineering_mode:
      name: "engineering mode"
    bluetooth:
      name: "control bluetooth"

number:
  - platform: ld2410
    timeout:
      name: timeout
    light_threshold:
      name: light threshold
    max_move_distance_gate:
      name: max move distance gate
    max_still_distance_gate:
      name: max still distance gate
    g0:
      move_threshold:
        name: g0 move threshold
      still_threshold:
        name: g0 still threshold
    g1:
      move_threshold:
        name: g1 move threshold
      still_threshold:
        name: g1 still threshold
    g2:
      move_threshold:
        name: g2 move threshold
      still_threshold:
        name: g2 still threshold
    g3:
      move_threshold:
        name: g3 move threshold
      still_threshold:
        name: g3 still threshold
    g4:
      move_threshold:
        name: g4 move threshold
      still_threshold:
        name: g4 still threshold
    g5:
      move_threshold:
        name: g5 move threshold
      still_threshold:
        name: g5 still threshold
    g6:
      move_threshold:
        name: g6 move threshold
      still_threshold:
        name: g6 still threshold
    g7:
      move_threshold:
        name: g7 move threshold
      still_threshold:
        name: g7 still threshold
    g8:
      move_threshold:
        name: g8 move threshold
      still_threshold:
        name: g8 still threshold


button:
  - platform: ld2410
    factory_reset:
      name: "factory reset"
    restart:
      name: "restart"
    query_params:
      name: query params

text_sensor:
  - platform: ld2410
    version:
      name: "firmware version"
    mac_address:
      name: "mac address"

select:
  - platform: ld2410
    distance_resolution:
      name: "distance resolution"
    baud_rate:
      name: "baud rate"
    light_function:
      name: light function
    out_pin_level:
      name: out pin level

And here the lovelace card (note that 4-5 entities has been translated to italian)

type: vertical-stack
cards:
  - type: horizontal-stack
    cards:
      - type: entities
        entities:
          - entity: switch.DeviceName_engineering_mode
            name: engineering mode
  - type: vertical-stack
    cards:
      - type: entities
        entities:
          - entity: number.DeviceName_timeout
            name: timeout
          - entity: number.DeviceName_max_move_distance_gate
            name: Dist.max rilev. movimento
          - entity: number.DeviceName_max_still_distance_gate
            name: Dist.max rilev. fermo gate
          - entity: select.DeviceName_light_function
            name: Funzione con luce
          - entity: number.DeviceName_light_threshold
            name: Threshold luce
      - type: horizontal-stack
        cards:
          - type: entity
            entity: sensor.DeviceName_distanza_oggetto
            name: Distanza
          - type: entity
            entity: sensor.DeviceName_distanza_movimento
            name: Movimento
          - type: entity
            entity: sensor.DeviceName_distanza_da_fermo
            name: Fermo
  - type: horizontal-stack
    cards:
      - type: entity
        entity: sensor.DeviceName_move_energy
        name: Energia movimento
      - type: entity
        entity: sensor.DeviceName_still_energy
        name: Energia fermo
  - type: horizontal-stack
    cards:
      - type: entity
        entity: binary_sensor.DeviceName_out_pin_presence_status
        name: GPIO pr
        state_color: true
      - type: entity
        entity: binary_sensor.DeviceName_persona
        name: Presenza
        state_color: true
      - type: entity
        entity: binary_sensor.DeviceName_persona_in_movimento
        name: Movimento
        state_color: true
      - type: entity
        entity: binary_sensor.DeviceName_persona_ferma
        name: Fermo
        state_color: true
  - type: conditional
    conditions:
      - entity: switch.DeviceName_engineering_mode
        state: 'on'
    card:
      type: vertical-stack
      cards:
        - type: horizontal-stack
          cards:
            - type: entity
              entity: sensor.DeviceName_light
              name: Intensità luce
            - type: entity
              entity: binary_sensor.DeviceName_out_pin_presence_status
              name: Presenza pin est.
              state_color: true
        - type: horizontal-stack
          cards:
            - type: entity
              entity: sensor.DeviceName_g0_move_energy
              name: g0
            - type: entity
              entity: number.DeviceName_g0_move_threshold
              name: ' '
            - type: entity
              entity: sensor.DeviceName_g0_still_energy
              name: ' '
            - type: entity
              entity: number.DeviceName_g0_still_threshold
              name: ' '
        - type: horizontal-stack
          cards:
            - type: entity
              entity: sensor.DeviceName_g1_move_energy
              name: g1
              icon: ' '
            - type: entity
              entity: number.DeviceName_g1_move_threshold
              name: ' '
              icon: ' '
            - type: entity
              entity: sensor.DeviceName_g1_still_energy
              name: ' '
              icon: ' '
            - type: entity
              entity: number.DeviceName_g1_still_threshold
              name: ' '
              icon: ' '
        - type: horizontal-stack
          cards:
            - type: entity
              entity: sensor.DeviceName_g2_move_energy
              name: g2
              icon: ' '
            - type: entity
              entity: number.DeviceName_g2_move_threshold
              name: ' '
              icon: ' '
            - type: entity
              entity: sensor.DeviceName_g2_still_energy
              name: ' '
              icon: ' '
            - type: entity
              entity: number.DeviceName_g2_still_threshold
              name: ' '
              icon: ' '
        - type: horizontal-stack
          cards:
            - type: entity
              entity: sensor.DeviceName_g3_move_energy
              name: g3
              icon: ' '
            - type: entity
              entity: number.DeviceName_g3_move_threshold
              name: ' '
              icon: ' '
            - type: entity
              entity: sensor.DeviceName_g3_still_energy
              name: ' '
              icon: ' '
            - type: entity
              entity: number.DeviceName_g3_still_threshold
              name: ' '
              icon: ' '
        - type: horizontal-stack
          cards:
            - type: entity
              entity: sensor.DeviceName_g4_move_energy
              name: g4
              icon: ' '
            - type: entity
              entity: number.DeviceName_g4_move_threshold
              name: ' '
              icon: ' '
            - type: entity
              entity: sensor.DeviceName_g4_still_energy
              name: ' '
              icon: ' '
            - type: entity
              entity: number.DeviceName_g4_still_threshold
              name: ' '
              icon: ' '
        - type: horizontal-stack
          cards:
            - type: entity
              entity: sensor.DeviceName_g5_move_energy
              name: g5
              icon: ' '
            - type: entity
              entity: number.DeviceName_g5_move_threshold
              name: ' '
              icon: ' '
            - type: entity
              entity: sensor.DeviceName_g5_still_energy
              name: ' '
              icon: ' '
            - type: entity
              entity: number.DeviceName_g5_still_threshold
              name: ' '
              icon: ' '
        - type: horizontal-stack
          cards:
            - type: entity
              entity: sensor.DeviceName_g6_move_energy
              name: g6
              icon: ' '
            - type: entity
              entity: number.DeviceName_g6_move_threshold
              name: ' '
              icon: ' '
            - type: entity
              entity: sensor.DeviceName_g6_still_energy
              name: ' '
              icon: ' '
            - type: entity
              entity: number.DeviceName_g6_still_threshold
              name: ' '
              icon: ' '
        - type: horizontal-stack
          cards:
            - type: entity
              entity: sensor.DeviceName_g7_move_energy
              name: g7
              icon: ' '
            - type: entity
              entity: number.DeviceName_g7_move_threshold
              name: ' '
              icon: ' '
            - type: entity
              entity: sensor.DeviceName_g7_still_energy
              name: ' '
              icon: ' '
            - type: entity
              entity: number.DeviceName_g7_still_threshold
              name: ' '
              icon: ' '
        - type: horizontal-stack
          cards:
            - type: entity
              entity: sensor.DeviceName_g8_move_energy
              name: g8
              icon: ' '
            - type: entity
              entity: number.DeviceName_g8_move_threshold
              name: ' '
              icon: ' '
            - type: entity
              entity: sensor.DeviceName_g8_still_energy
              name: ' '
              icon: ' '
            - type: entity
              entity: number.DeviceName_g8_still_threshold
              name: ' '
              icon: ' '


you have to change DeviceName in substitution (esphome config), and rename it into the lovelace card (DeviceName)

1 Like

Not sure what skizzo’s talking about since I only see one uart being configured, but I did manage to figure it out myself, though there is one anomaly in the output. I would have expected that ld2410_id would serve to impart separate sensor names in HA, this proved not to be the case, maybe I’m missing something that would make this happen or maybe it’s a bug. In any case here is my working code, though I’ve only got two uart’s available on my ESP32-S2 mini.

esphome:
  name: esp32s2-238
  friendly_name: esp32-238

esp32:
  board: esp32-s2-saola-1
  framework:
    type: arduino

# Enable logging
logger:
  level: debug
  baud_rate: 0

# Enable Home Assistant API
api:
  encryption:
    key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
ota:
  password: "xxxxxxxxxxxxxxxxxxxxxxx"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  power_save_mode: none  


#  manual_ip:
    # Set this to the IP of the ESP
#    static_ip: 192.168.0.238
    # Set this to the IP address of the router. Often ends with .1
#    gateway: 192.168.0.1
    # The subnet of the network. 255.255.255.0 works for most home networks.
#    subnet: 255.255.255.0    

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp32-238 Fallback Hotspot"
    password: "IpZ1k35K0fhs"

captive_portal:

web_server:
  port: 80  

uart:
  - id: uart_0
    tx_pin: GPIO16
    rx_pin: GPIO17
    baud_rate: 256000
    parity: NONE
    stop_bits: 1

  - id: uart_1
    tx_pin: GPIO18
    rx_pin: GPIO21
    baud_rate: 256000
    parity: NONE
    stop_bits: 1

#  - id: uart_2
#    tx_pin: GPIO33
#    rx_pin: GPIO34
#    baud_rate: 256000
#    parity: NONE
#    stop_bits: 1        


ld2410:
  - id: ld2410_0
    uart_id: uart_0

  - id: ld2410_1
    uart_id: uart_1

#  - id: ld2410_2
#   uart_id: uart_2
  
binary_sensor:
  - platform: ld2410
    has_target:
      name: Presence
    has_moving_target:
      name: Moving Target
    has_still_target:
      name: Still Target
    ld2410_id: ld2410_0

  - platform: ld2410
    has_target:
      name: Presence1
    has_moving_target:
      name: Moving Target1
    has_still_target:
      name: Still Target1

    ld2410_id: ld2410_1

#  - platform: ld2410
#   has_target:
#      name: Presence
#    has_moving_target:
#      name: Moving Target
#    has_still_target:
#      name: Still Target
#    ld2410_id: ld2410_2        

sensor:
  - platform: ld2410
    moving_distance:
      name : Moving Distance
    still_distance:
      name: Still Distance
    moving_energy:
      name: Move Energy
    still_energy:
      name: Still Energy
    detection_distance:
      name: Detection Distance
    ld2410_id: ld2410_0

  - platform: ld2410
    moving_distance:
      name : Moving Distance1
    still_distance:
      name: Still Distance1
    moving_energy:
      name: Move Energy1
    still_energy:
      name: Still Energy1
    detection_distance:
      name: Detection Distance1
    ld2410_id: ld2410_1

#  - platform: ld2410
#    moving_distance:
#      name : Moving Distance
#    still_distance:
#      name: Still Distance
#    moving_energy:
#      name: Move Energy
#    still_energy:
#      name: Still Energy
#    detection_distance:
#      name: Detection Distance
#    ld2410_id: ld2410_2    
    
type or paste code here

I thought I almost finish almost 3 day calibration with trial and error in bathroom where washing machine and the dryer is installed. And then, wife turned on the washing machine and the dryer… it detects around 40-50% of presence… any ideas how to ignore these peaks?

If you monitor the machines you would be able to filter this false positive.

And in certain situations we must associate a PIR.

I have put together some graphs similar to the HLKRadarTool app using Apex Charts (installed from HACS).
The following code is based on the work done by patrick3399:

Add the following to configuration.yaml

template:
  - sensor:
      - name: "chart-MovementThresholds"
        state: |
              {{ now() }}
        attributes:
            Heights: |
                  {% set entities=["number.g0_move_threshold","number.g1_move_threshold","number.g2_move_threshold","number.g3_move_threshold","number.g4_move_threshold","number.g5_move_threshold","number.g6_move_threshold","number.g7_move_threshold","number.g8_move_threshold"] %}
                  {{ entities | map('states') | list }}

      - name: "chart-MovementEnergy"
        state: |
              {{ now() }}
        attributes:
            Heights: |
                  {% set entities=["sensor.g0_move_energy","sensor.g1_move_energy","sensor.g2_move_energy","sensor.g3_move_energy","sensor.g4_move_energy","sensor.g5_move_energy","sensor.g6_move_energy","sensor.g7_move_energy","sensor.g8_move_energy"] %}
                  {{ entities | map('states') | list }}

      - name: "chart-StillThresholds"
        state: |
              {{ now() }}
        attributes:
            Heights: |
                  {% set entities=["number.g0_still_threshold","number.g1_still_threshold","number.g2_still_threshold","number.g3_still_threshold","number.g4_still_threshold","number.g5_still_threshold","number.g6_still_threshold","number.g7_still_threshold","number.g8_still_threshold"] %}
                  {{ entities | map('states') | list }}
                  
      - name: "chart-StillEnergy"
        state: |
              {{ now() }}
        attributes:
            Heights: |
                  {% set entities=["sensor.g0_still_energy","sensor.g1_still_energy","sensor.g2_still_energy","sensor.g3_still_energy","sensor.g4_still_energy","sensor.g5_still_energy","sensor.g6_still_energy","sensor.g7_still_energy","sensor.g8_still_energy"] %}
                  {{ entities | map('states') | list }}

And the following cards for your dashboard.
Movement Chart:

type: custom:apexcharts-card
header:
  show: true
  title: Movement Energy
  show_states: false
  colorize_states: false
graph_span: 8d
update_interval: 15ms
series:
  - entity: sensor.chart_movementthresholds
    data_generator: |
      return entity.attributes.Heights.map((peak, index) => {
        return [moment().add(-(8-index), 'd'),  entity.attributes.Heights[index]];
      });
    opacity: 1
    color: FB239F
    stroke_width: 2
    show:
      legend_value: false
  - entity: sensor.chart_movementenergy
    data_generator: |
      return entity.attributes.Heights.map((peak, index) => {
        return [moment().add(-(8-index), 'd'),  entity.attributes.Heights[index]];
      });
    opacity: 1
    color: 0000FF
    stroke_width: 2
    show:
      legend_value: false
apex_config:
  xaxis:
    type: categories
    labels:
      rotate: 0
    title:
      text: Gates
      offsetX: 0
      offsetY: -10
      style:
        fontWeight: 600
    overwriteCategories:
      - 0
      - 1
      - 2
      - 3
      - 4
      - 5
      - 6
      - 7
      - 8
    update_delay: 1ms
    update_interval: 15ms
    dataLabels:
      enabled: false
      dropShadow:
        enabled: false
    stroke:
      curve: straight
    tooltip:
      enabled: false
  legend:
    show: true
    legend_values: false
  chart:
    height: 300px
  yaxis:
    min: 0
    max: 100

Still Chart:

type: custom:apexcharts-card
header:
  show: true
  title: Still Energy
  show_states: false
  colorize_states: false
graph_span: 8d
update_interval: 15ms
series:
  - entity: sensor.chart_stillthresholds
    data_generator: |
      return entity.attributes.Heights.map((peak, index) => {
        return [moment().add(-(8-index), 'd'),  entity.attributes.Heights[index]];
      });
    opacity: 1
    color: FB239F
    stroke_width: 2
    show:
      legend_value: false
  - entity: sensor.chart_stillenergy
    data_generator: |
      return entity.attributes.Heights.map((peak, index) => {
        return [moment().add(-(8-index), 'd'),  entity.attributes.Heights[index]];
      });
    opacity: 1
    color: 0000FF
    stroke_width: 2
    show:
      legend_value: false
apex_config:
  xaxis:
    type: categories
    labels:
      rotate: 0
    title:
      text: Gates
      offsetX: 0
      offsetY: -10
      style:
        fontWeight: 600
    overwriteCategories:
      - 0
      - 1
      - 2
      - 3
      - 4
      - 5
      - 6
      - 7
      - 8
    update_delay: 1ms
    update_interval: 15ms
    dataLabels:
      enabled: false
      dropShadow:
        enabled: false
    stroke:
      curve: straight
    tooltip:
      enabled: false
  legend:
    show: true
    legend_values: false
  chart:
    height: 300px
  yaxis:
    min: 0
    max: 100

10 Likes

I have installed ld2410b in my stairs. Also I have set up an alarm that i activate whenever i am away. Where I live there are house geckos. It’s impossible to set gates value to a position where it can ignore geckos and still turn on light from first steps of stairs. In my opinion ignoring flies can be done but geckos and maybe mice seems difficult without compromising on light triggering time upon human presence.

Edit: I have noticed that after the last esphome update that included ld2410, sensors seems to have a bit more delay. Maybe it’s just in my mind that they seems a little slow.

You can set it:

ld2410:
 # Time in milliseconds to control the rate of data updates. Defaults to 1000ms.
   throttle: 1500ms
1 Like

Yes but I found there’s some slight interference in between them when looking at the movement and still energy

Have you guys tried the OUT PIN in the PCB to see if it’s quicker than getting the presence status from the UART port?

BTW I’ve some custom configurations using bar charts (based on another config I found on Github) and it’s really easy to calibrate it this way because you can see the current value vs the target in a very visual way. Attaching a screenshot and video! Let me know if it’s interesting I can share my config

Video → Screen Recording 2023-09-10 at 12.50.08.mov - Droplr


4 Likes

Is this the same ‘Out Pin’ as the ‘Out pin Presence Status’ from diagnostics? If it is then for me it is always alternating between Home and Away without any presence.

Throttle seems to be working in most situations i.e. in my kitchen, entrance etc. But in stairs as the sensor is at top of stairs looking down from above it is still laggy. I have even tried lowering G6, G7 and G8. Still after i get into its line of site and stay there at first step from bottom it takes a bit of time to see me(values go up gradually). I will try changing it’s angle more downwards towards the stairs. Right now i have stuck it on the wall with hot glue facing downwards a little.

2 Likes