Skip to content

Instantly share code, notes, and snippets.

@peyanski
Last active May 1, 2024 16:21
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save peyanski/5d46c7323385b38c64235f88e43df8c4 to your computer and use it in GitHub Desktop.
Save peyanski/5d46c7323385b38c64235f88e43df8c4 to your computer and use it in GitHub Desktop.
Use this code to make your LD2410 sensor to work with ESP32 or ESP8266 board
esphome:
name: ld2410-esp32
friendly_name: ld2410-esp32
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "IArm3ZGuqL1HLZXXbu4/L0ciw1TDSagu6THKP8LnFdo="
ota:
password: "3373716c7967d461cf4bd0ce1ba42e9a"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Ld2410-Esp32 Fallback Hotspot"
password: "AhxmD317i7r1"
captive_portal:
light:
- platform: binary
name: "Blue Status Light"
output: light_output
id: led_light
restore_mode: ALWAYS_OFF
output:
- platform: gpio
pin: GPIO2
id: light_output
i2c:
sda: 21
scl: 22
scan: true
id: bus_a
uart:
id: ld2410_uart
tx_pin: RX
rx_pin: TX
baud_rate: 256000
parity: NONE
stop_bits: 1
ld2410:
uart_id: ld2410_uart
throttle: 1500ms
id: ld2410_comp
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
button:
- platform: ld2410
factory_reset:
name: "factory reset"
restart:
name: "restart"
query_params:
name: query params
number:
- platform: ld2410
timeout:
name: timeout
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
light_threshold:
name: light threshold
text_sensor:
- platform: ld2410
version:
name: "presenece sensor version"
mac_address:
name: "presenece sensor mac address"
switch:
- platform: ld2410
engineering_mode:
name: "engineering mode"
bluetooth:
name: control Bluetooth
sensor:
- platform: ld2410
moving_distance:
name: "Moving distance (cm)"
still_distance:
name: "Still Distance (cm)"
moving_energy:
name: "Move Energy (%)"
still_energy:
name: "Still Energy (%)"
detection_distance:
name: "Distance Detection (cm)"
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
light:
name: light
- platform: bh1750
name: "Illuminance"
address: 0x23
update_interval: 30s
binary_sensor:
- platform: ld2410
has_target:
name: Presence
has_moving_target:
name: Moving Target
has_still_target:
name: Still Target
@edgardmello
Copy link

I have a NodeMcu v3 CH340; unfortunately, this code doesn't work with it. It's heavy for the 8266 chip.

@diederik-maes
Copy link

It doesn't work for me either using a D1 Mini and the LD2410 without Bluetooth.
I also get "Found no i2c devices!" so disabled that already as well as "platform: bh1750" that wasn't detected either

@CTEBAvuk
Copy link

CTEBAvuk commented Nov 26, 2023

I have a NodeMcu v3 CH340; unfortunately, this code doesn't work with it. It's heavy for the 8266 chip.

Change in the code, what I mentioned below and the code works with ESP8266 D1mini!
In the file given here (attached), you need to change (or add) the following lines:

1.) THESE LINES:
esp32:
board: esp32dev
framework:
type: arduino
CHANGE WITH THIS:
esp8266:
board: d1_mini

2.) Add this line in the OUTPUT section:
inverted: True
After this line:
id: light_output

3.) THESE LINES in the UART section:
tx_pin: RX
rx_pin: TX
CHANGE WITH THIS:
tx_pin: GPIO1
rx_pin: GPIO3

OF COURSE: MUST connect Tx from ESP8266 to Rx from LD2410 sensor, and Rx from ESP8266 to Tx from LD2410 sensor!

With the modifications, the LD2410 sensor works great for me. An example in the attached photo..

Moving Target

@NiNo-213
Copy link

Hi,
is it possible to have the sepaat yaml file for esp8266 (d1_mini or similar), because it is not working for me somehow. thank you

@WhFrost
Copy link

WhFrost commented Nov 29, 2023

Hello! It doesn’t work for me either, all sensors are in the “Unknown” state, despite the fixes. Wemos D1 mini board.

@CTEBAvuk
Copy link

OK. Here is a link to the complete text from the YAML file at the bottom of my post.
You only need to change and enter the name of your WiFi SSID and your password in the text.
And as I mentioned, you need to connect the RX from the sensor to the TX of the ESP8266 and the TX from the sensor to the RX of the ESP8266. And of course, you have to power both devices with 5V (from USB).

YES! I am using ESP8266 Wemos D1 mini and it has been working for me for days, since I modified and posted here.

Download the .TXT file and everything in it, copy it to your YAML file from your ESP8266 that you inserted into ESP Home.

https://www.dropbox.com/scl/fi/g1h9n2jlky3nfjxye3m8p/Za_SLANJE-YAML-za-vezu-Rx-Tx-sa-ESP8266.txt?rlkey=0xxp7ayperw31gk6ehw0rkpgb&dl=0

...and an example of how it works Wemos D1 works for several days with the LD2410 sensor, without interruption.
Moving Target 2

I had problems with the ESP32 and it used to turn out to be unavailable, unknown, etc...

@icemul1900
Copy link

I found the fix for the ESP8266 from the esphome page about the Ic2: https://esphome.io/components/i2c.html
sda (Optional, Pin): The pin for the data line of the I²C bus. Defaults to the default of your board (usually GPIO21 for ESP32 and GPIO4 for ESP8266).

scl (Optional, Pin): The pin for the clock line of the I²C bus. Defaults to the default of your board (usually GPIO22 for ESP32 and GPIO5 for ESP8266).

So my fix was to do this:
i2c:
sda: GPIO4
scl: GPIO5
scan: true
id: bus_a

hope that helps someone

@DravenSA
Copy link

So I have read a lot about the LD2410C and The ESP8266, and i am by no means a coder, but i do manipulate code, so this is what i have found
Set up your ESP8266 inside ESPHome in Home Assistant as a straight forward new clean device.
Then go into edit and after the line captive_portal: leave a line space and paste the following code

How there will need to be some changes
tx_pin: 1
rx_pin: 3
change these setting to suit yourself (1 and 3 are where i put mine)
I also removed the part about "Illuminance" as i believe this is only needed if you have a bh1750, which i dont and to be honest, i think there is a few other lines that could be removed Like mac address, but i left them in , they dont seem to be an issue

So this should fix the sda: and scl:, the fact that the blue LED was off when on and on when off, and tx and rx pin.
as said earlier in this thread, but i will say it again

OF COURSE: MUST connect Tx from ESP8266 to Rx from LD2410C sensor, and Rx from ESP8266 to Tx from LD2410C sensor!

If anyone understands what the light threshold, and out pin level function means, i would appreciate that.

anyway, hope this helps/

light:
  - platform: binary
    name: "Blue Status Light"
    output: light_output
    id: led_light
    restore_mode: ALWAYS_OFF
 
output:
  - platform: gpio
    pin: GPIO2
    id: light_output
    inverted: True
 
i2c:
  sda: 4
  scl: 5
  scan: true
  id: bus_a
 
uart:
  id: ld2410_uart
  tx_pin: 1
  rx_pin: 3
  baud_rate: 256000
  parity: NONE
  stop_bits: 1
 
ld2410:
  uart_id: ld2410_uart
  throttle: 1500ms
  id: ld2410_comp
 
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
 
button:
  - platform: ld2410
    factory_reset:
      name: "factory reset"
    restart:
      name: "restart"
    query_params:
      name: query params
 
number:
  - platform: ld2410
    timeout:
      name: timeout
    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
    light_threshold:
      name: light threshold
 
text_sensor:
  - platform: ld2410
    version:
      name: "presenece sensor version"
    mac_address:
      name: "presenece sensor mac address"
 
switch:
  - platform: ld2410
    engineering_mode:
      name: "engineering mode"
    bluetooth:
      name: control Bluetooth
 
sensor:
  - platform: ld2410
    moving_distance:
      name: "Moving distance (cm)"
    still_distance:
      name: "Still Distance (cm)"
    moving_energy:
      name: "Move Energy (%)"
    still_energy:
      name: "Still Energy (%)"
    detection_distance:
      name: "Distance Detection (cm)"
    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
    light:
      name: light
 
binary_sensor:
  - platform: ld2410
    has_target:
      name: Presence
    has_moving_target:
      name: Moving Target
    has_still_target:
      name: Still Target
    
     

@edgardmello
Copy link

Hello folks!

This is the code I'm using and work's perfectly with esp8266. The inconvenient is that you don't have granular control on the distance gates. You set the same threshold value for all of them.

---
substitutions:
  board_platform: ESP32
  label: esp-20
  slug: esp-20
  name: Cozinha Occupancy
  description: 'D1 Mini - Sensor ld2410 (Cozinha) #ESP20'
  api_password: !secret esphome_api_password
  ota_password: !secret esphome_ota_password
  wifi_ssid: !secret wifi_ssid
  wifi_password: !secret wifi_password
  wifi_ap_password: !secret wifi_ap_password
  device_name: esp-20

esphome:
  name: "${slug}"
  comment: "${description}"
  build_path: "./.build/${slug}/"
  platform: ESP8266
  board: d1_mini
  includes:
    - uart_read_line_sensor_ld2410v3.h
  on_boot:
    priority: -100
    then:
      - script.execute: get_config

# Enable logging
logger:
  baud_rate: 0

# Enable Home Assistant API
api:
  encryption:
    key: !secret api_key

ota:
  password: !secret ota_password

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: ${slug} ap
    password: !secret wifi_ap_password

web_server:
  port: 80
  version: 2
  include_internal: true
  ota: false

captive_portal:

uart:
  id: uart_bus
  tx_pin: 
    number: GPIO1
  rx_pin: 
    number: GPIO3
  baud_rate: 256000
  parity: NONE
  stop_bits: 1

switch:
  - platform: safe_mode
    name: ${slug} use_safe_mode
    
  - platform: template
    name: ${slug} configmode
    id: configmode
    optimistic: true
    # assumed_state: false
    turn_on_action:
      # - switch.turn_off: engineering_mode
      - lambda: 'static_cast<LD2410 *>(ld2410)->setConfigMode(true);'
      - delay: 100ms
      - script.execute: clear_targets
    turn_off_action:
      - lambda: 'static_cast<LD2410 *>(ld2410)->setConfigMode(false);'

  - platform: template
    name: ${slug} show_target_stats
    id: show_stats
    optimistic: true
    internal: true
    turn_off_action:
      - script.execute: clear_targets

text_sensor:
  - platform: template
    name: ${slug} uptime_human_readable
    id: uptime_human_readable
    icon: mdi:clock-start
    update_interval: 60s

sensor:
  - platform: uptime
    name: ${slug} uptime_sensor
    id: uptime_sensor
    update_interval: 60s
    internal: true
    on_raw_value:
      then:
        - text_sensor.template.publish:
            id: uptime_human_readable
            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)+":" : "00:") +
                        (hours ? to_string(hours)+":" : "00:") +
                        (minutes ? to_string(minutes)+":" : "00:") +
                        (to_string(seconds))
                      ).c_str();

  - platform: custom # currently crashes ESP32
    lambda: |-
      auto uart_component = static_cast<LD2410 *>(ld2410);
      //return {uart_component->movingTargetDistance,uart_component->movingTargetEnergy,uart_component->stillTargetDistance,uart_component->stillTargetEnergy,uart_component->detectDistance};
      return {};
    sensors:
    
  - platform: template
    name: ${slug} movingTargetDistance
    id: movingTargetDistance
    unit_of_measurement: "cm"
    accuracy_decimals: 0
    internal: true
    
  - platform: template
    name: ${slug} movingTargetEnergy
    id: movingTargetEnergy
    unit_of_measurement: "%"
    accuracy_decimals: 0
    internal: true
    
  - platform: template
    name: ${slug} stillTargetDistance
    id: stillTargetDistance
    unit_of_measurement: "cm"
    accuracy_decimals: 0
    internal: true
    
  - platform: template
    name: ${slug} stillTargetEnergy
    id: stillTargetEnergy
    unit_of_measurement: "%"
    accuracy_decimals: 0
    internal: true
    
  - platform: template
    name: ${slug} detectDistance
    id: detectDistance
    unit_of_measurement: "cm"
    accuracy_decimals: 0
    internal: true

custom_component:
  - lambda: |-
      return {new LD2410(id(uart_bus))};
    components:
      - id: ld2410
      
binary_sensor:
  - platform: gpio
    name: ${slug} occupancy
    id: mmwave_presence_ld2410
    pin: D7
    device_class: motion
    on_state:
      then:
        - if: 
            condition: 
              - binary_sensor.is_off: mmwave_presence_ld2410
            then: 
              - delay: 150ms
              - script.execute: clear_targets

number:
  - platform: template
    name: ${slug} configMaxDistance
    id: maxconfigDistance
    unit_of_measurement: "M"
    min_value: 0.75
    max_value: 6
    step: 0.75
    update_interval: never
    optimistic: true
    set_action:
      - switch.turn_on: configmode
      - delay: 50ms
      - lambda: |-
          auto uart_component = static_cast<LD2410 *>(ld2410);
          uart_component->setMaxDistancesAndNoneDuration(x/0.75,x/0.75,id(noneDuration).state);
      - delay: 50ms
      - lambda: 'static_cast<LD2410 *>(ld2410)->queryParameters();'
      - delay: 50ms
      - switch.turn_off: configmode

  - platform: template
    name: "${slug} sensitivity_threshold_(%)"
    id: allSensitivity
    min_value: 10
    max_value: 100
    step: 5
    mode: box
    update_interval: never
    optimistic: true
    set_action:
      - switch.turn_on: configmode
      - delay: 50ms
      - lambda: |-
          auto uart_component = static_cast<LD2410 *>(ld2410);
          uart_component->setAllSensitivity(x);
      - delay: 50ms
      - lambda: 'static_cast<LD2410 *>(ld2410)->queryParameters();'
      - delay: 50ms
      - switch.turn_off: configmode
      
  - platform: template
    name: "${slug} motion_hold_(sec)"
    id: noneDuration
    min_value: 0
    max_value: 900
    step: 1
    mode: box
    update_interval: never
    optimistic: true
    set_action:
      - switch.turn_on: configmode
      - delay: 50ms
      - lambda: |-
          auto uart_component = static_cast<LD2410 *>(ld2410);
          uart_component->setMaxDistancesAndNoneDuration(id(maxconfigDistance).state, id(maxconfigDistance).state, x);
      - delay: 50ms
      - lambda: 'static_cast<LD2410 *>(ld2410)->queryParameters();'
      - delay: 50ms
      - switch.turn_off: configmode
button:
  - platform: restart
    name: "${slug} reset/restart_ESP/MCU"
    entity_category: diagnostic
    on_press:
      - switch.turn_on: configmode
      - delay: 50ms
      - lambda: 'static_cast<LD2410 *>(ld2410)->factoryReset();'
      - delay: 150ms
      - lambda: 'static_cast<LD2410 *>(ld2410)->reboot();'
      - delay: 150ms

script:
  - id: get_config
    then:
      - switch.turn_on: configmode
      - delay: 500ms
      - lambda: 'static_cast<LD2410 *>(ld2410)->queryParameters();'
      - delay: 500ms
      - switch.turn_off: configmode
      
  - id: clear_targets
    then:
      - lambda: |-
          //id(hasTarget).publish_state(0);
          //id(hasMovingTarget).publish_state(0);
          //id(hasStillTarget).publish_state(0);
          id(movingTargetDistance).publish_state(0);
          id(movingTargetEnergy).publish_state(0);
          id(stillTargetDistance).publish_state(0);
          id(stillTargetEnergy).publish_state(0);
          id(detectDistance).publish_state(0);

@calbu
Copy link

calbu commented Dec 28, 2023

Has anyone a working yaml file for NodeMMCU v3? Both of the above configs are not working for it.

@sixoremenos
Copy link

@CTEBAvuk Thank you very much! Your suggestions worked fine with my D1 mini.

@lylydang
Copy link

lylydang commented Jan 26, 2024

I still cannot be able to get my Esp Vroom32 to work, all configs came out Unknown for my sensor, anyone have the same issue :(?
Nvm swapped out the TX and RX pins, it works now.

@ashoktvm
Copy link

ashoktvm commented Feb 9, 2024

Can I get zone options in this?

@superaviator
Copy link

I still cannot be able to get my Esp Vroom32 to work, all configs came out Unknown for my sensor, anyone have the same issue :(? Nvm swapped out the TX and RX pins, it works now.

Swapped out in which way?

@giuseppe-93
Copy link

giuseppe-93 commented Apr 29, 2024

Hello. This Yaml code that you published is fine for D1 mini right?

@Jacks5000
Copy link

I've try different Yaml files and still getting Unknown I'm using D1 mini and LD2410c , I have confirmed my wiring is correct but no go

any ideas

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment