Build a smaller human body radar sensor using ESP32-S2 and LD2410C

After building a radar with esp32-c3 and ld2410b, we feel the power of esphome and the fun of creating the sensor by ourselves.
Through a series of selection, we chose wemos s2 mini to build a s2-based radar. Wemos created the famous d1 mini series. After our tests, the overall effect is quite good. The wifi signal will be much better than d1-mini.





As with the challenges encountered on esp32-c3, the main problem comes from the fact that esphome will have some restrictions on the support of these new esp32 series chips, mainly if they do not use serial chips. If you want to keep the serial port log and use the serial port to communicate with the radar module ld2410b(c) series, some additional tricks will be required.
Fortunately, the latest kernel of arduino solves this problem, but there is still a little problem with the uart library from esphome.

Similarly, we were lucky enough to read the daylight sensor of ld2410c, which is not very sensitive to night light, which is a bit of a pity.

The yaml source code we use:

esphome:
  name: screek-humen-dectet-1u
  comment: Screek Human Presence Sensor 24GHz PS-HPS 1U
  friendly_name: Screek Human Presence Sensor 1U
  name_add_mac_suffix: True
  platformio_options:
    board_build.flash_mode: dio
  platformio_options:
    board_build.flash_mode: dio
    board_build.extra_flags:
      - "-DARDUINO_USB_CDC_ON_BOOT=0" 
  project: 
    name: Screek.Human_Presence_Sensor
    version: 1U

external_components:
  - source: screek-mod-components
  
esp32:
  board: lolin_s2_mini
  framework:
    type: arduino
    version: 2.0.7
    platform_version: 6.0.1

improv_serial:
  
logger:
  # hardware_uart: uart0

api:


ota:
  password: "YOUR_OTA_PASSWORD"

wifi:
  # ssid: !secret wifi_ssid
  # password: !secret wifi_password
  # fast_connect: True

  power_save_mode: NONE
  ap:
    ssid: "SCREEK HUMAN-SENSOR"

captive_portal:

web_server:
  port: 80

binary_sensor:
  - platform: status
    name: Online
    id: ink_ha_connected
  - platform: ld2410
    has_target:
      name: Presence
    has_moving_target:
      name: Moving Target
    has_still_target:
      name: Still Target

sensor:
  - platform: template
    id: sys_esp_temperature
    name: ESP Temperature
    lambda: return temperatureRead();
    unit_of_measurement: °C
    device_class: TEMPERATURE
    update_interval: 30s
    entity_category: "diagnostic"
  - platform: uptime
    name: Uptime
    id: sys_uptime
    update_interval: 10s
  - platform: wifi_signal 
    name: RSSI
    id: wifi_signal_db
    update_interval: 1s
    entity_category: "diagnostic"
  - platform: template
    id: esp_memory
    icon: mdi:memory
    name: ESP Free Memory
    lambda: return heap_caps_get_free_size(MALLOC_CAP_INTERNAL) / 1024;
    unit_of_measurement: 'kB'
    state_class: measurement
    entity_category: "diagnostic"
  - platform: ld2410
    moving_distance:
      name : Moving Distance
      id: moving_distance
    still_distance:
      name: Still Distance
      id: still_distance
    moving_energy:
      name: Move Energy
    still_energy:
      name: Still Energy
    detection_distance:
      name: Detection Distance
    light:
      name: Sun Light

light:
  - platform: status_led
    name: sys_status
    pin: GPIO15
    internal: True
    restore_mode: ALWAYS_OFF

time:
  - platform: sntp
    id: time_now
    servers: 
      - ntp.aliyun.com      

uart:
  id: uart1
  tx_pin: GPIO18
  rx_pin: GPIO33
  baud_rate: 256000
  parity: NONE
  stop_bits: 1

ld2410:
  timeout: 150s
  id: ld2410_radar

button:
  - platform: template
    name: "Enable LD2410 BLE"
    entity_category: "config"
    icon: mdi:bluetooth
    on_press:
      lambda: |-
        id(ld2410_radar) -> ble_control(true);
  - platform: template
    name: "Disable LD2410 BLE"
    entity_category: "config"
    icon: mdi:bluetooth-off
    on_press:
      lambda: |-
        id(ld2410_radar) -> ble_control(false);
  - platform: template
    name: "LD2410 Reboot"
    icon: mdi:radar
    entity_category: "config"
    on_press:
      lambda: |-
        // auto* radar = LD2410Component::get(ld2410); 
        // radar -> roboot();
        id(ld2410_radar) -> reboot();
  - platform: restart
    icon: mdi:power-cycle
    name: "ESP Reboot"
  - platform: factory_reset
    disabled_by_default: True
    name: Factory Reset
    id: factory_reset_all

It took a lot of effort to design a shell for it. csz used a wonderful way to combine the shell together. With the help of a friend (XiangYang) who owns a professional 3D printer, we got this very lightweight The case, it’s thick and doesn’t use too many screws.

Of course, for those who want to get started and get it quickly, we are also ready to share it with friends all over the world.

ebay link

6 Likes

Hello,
I was trying to test your ESPHome code but I’ve several errors as probably you included customized library (screek-mod-components) that are missing…
How can I fix this?

thanks!

use this code:)

thank you!

Hi.

Coudl this code work also on Womos D1 mini (ESP8266), with some code adaptation?

I am very sorry, I have not used d1 mini, I used nodemcu a long time ago, it is esp8266 chip, but because the signal becomes very weak after crossing the wall, I did not use it later.
Because the core of this code uses mainly an official ld2410c library, contributed by esphome enthusiasts, and we made minor adjustments on it. So I guess, yes, you can work just as well with it. Or you can use our modified library, if you need to read that light.

The official library also has a bug, it’s probably designed mainly for modules without Bluetooth, and there’s a probability that every time you restart the esp it will rewrite the default parameter configuration. This is something we have optimized in our modified library as well.

Hi
I’m a newbie to ESPHome and MCU…
How should I go about to get the LD2410C to work with my ESP32 WROOM 32D…?
I’d love to get over this initial “wtf”-code-construct part, so all help oss greatly appreciated!

Peace :dove::v:

Hi

According to the datasheet, the Wemos S2 Mini uses 3.3V, but the HLK-LD2410C has a range of 5-12V. So it is not clear to me how this can work for you.

Thank you for the explanation.

Since the s2 mini is ldo conversion voltage from usb to get 3.3v, it is enough to get 5v directly from the first stage.

You can start with our code as a reference, then specify the part of the development board you use, and modify some pins, and start this step by step.
It’s a fun but tedious process.

Hi.

You can’t use light in the sensor. Does it work for you?

 sensor.ld2410: [source /config/esphome/human-presenter-west.yaml:88]
   platform: ld2410
   moving_distance: 
     name: Moving Distance
     id: moving_distance
   still_distance: 
     name: Still Distance
     id: still_distance
   moving_energy: 
     name: Move Energy
   still_energy: 
     name: Still Energy
   detection_distance: 
     name: Detection Distance
   
   [light] is an invalid option for [sensor.ld2410]. Please check the indentation.
   light: 
     name: Sun Light

Didn’t work for me… ESP32 Wroom 32D

Hi All, I didn’t have great success myself, so kindof mashed a lot of bits together from this and other posts, to make something work. No credit to me, all credit goes to other posters that I read from :slight_smile: (apoloigies that I can’t specify everyone here)

My take on this is a combo device, with the mmwave sensor, as well as a PIR sensor, and a combined temperature/humidity sensor bundled in for good measure :slight_smile: You can easily hash out the bits you do not need of course :slight_smile:

This is based on the ESPhome and Home assistant versions as of 30/04/2023

Hope this helps anyone else out there who was struggling too!

infos:

ESPhome installed onto generic D1mini clone.

PIR sensor is AM312, power take off at 3.3v from D1 mini, and output pin goes to D6
mmwave sensor is LD2410C, power take off at 5v from D1 mini, output goes to D5, TX to RX between module and D1 mini.
temp/humid sensor is AHT10, power take off at 3.3v from D1 mini, SCL goes to D1, SDA goes to D2
WS2812B LED power take off at 5v from D1 mini, input comes from D7
---

esphome:
  name: pd01
  friendly_name: Presence Detector
  platform: ESP8266
  board: d1_mini

# Enable logging
logger:
  level: WARN
  baud_rate: 0

# Enable Home Assistant API
api:
  encryption:
    key: "some_secret_key_thing"

ota:
  password: "some_secret_password_thing"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: 10.10.10.2
    gateway: 10.10.10.1
    subnet: 255.255.255.0

uart:
  #id: uart1
  tx_pin: TX
  rx_pin: RX
  baud_rate: 256000
  parity: NONE
  stop_bits: 1

i2c:
  sda: D2
  scl: D1
  scan: true
  id: bus_a

ld2410:
  timeout: 150s
  max_move_distance : 6m
  max_still_distance: 0.75m
  g0_move_threshold: 10
  g0_still_threshold: 20
  g1_move_threshold: 10
  g1_still_threshold: 20
  g2_move_threshold: 20
  g2_still_threshold: 21
  g3_move_threshold: 30
  g3_still_threshold: 31
  g4_move_threshold: 40
  g4_still_threshold: 41
  g5_move_threshold: 50
  g5_still_threshold: 51
  g6_move_threshold: 60
  g6_still_threshold: 61
  g7_move_threshold: 70
  g7_still_threshold: 71
  g8_move_threshold: 80
  g8_still_threshold: 81

status_led:
  pin:
    number: GPIO2 #ESP8266 OnBroad LED
    inverted: false

binary_sensor:
  - platform: gpio
    pin: D6
    name: "PIR Motion"
    device_class: motion
  - platform: ld2410
    has_target:
      name: Presence
    has_moving_target:
      name: Moving Target
    has_still_target:
      name: Still Target
  - platform: gpio
    pin: D5
    name: "Sejour occupancy"
    id: sejour_occupancy
    device_class: occupancy
    on_press:
      then:
        - light.turn_on:
            id: led_presence_sejour
            brightness: 25%
            red: 100%
            green: 0%
            blue: 0%
    on_release:
      then:
        - light.turn_on:
            id: led_presence_sejour
            brightness: 25%
            red: 0%
            green: 100%
            blue: 0%

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
  - platform: aht10
    i2c_id: bus_a
    address: 0x38
    temperature:
      name: "PD01 Temperature"
    humidity:
      name: "PD01 Humidity"
    update_interval: 60s

light:
  - platform: neopixelbus
    type: GRB
    variant: WS2812x
    pin: D7
    num_leds: 1
    name: "Led Presence Sejour"
    id: led_presence_sejour
    effects:
      - strobe:
      - addressable_rainbow:
      - addressable_scan:
      - addressable_twinkle:
      - addressable_random_twinkle:
      - addressable_fireworks:
      - addressable_flicker:



1 Like

I have my sensors on a different LAN subnet, which is why I have a static IP address assigned. This is not needed if you are running ESPhome on the same subnet as your devices :slight_smile:

1 Like

You can use our modified version of the library, or you can use the official ld2410 library the original author submitted a pull that includes this functionality.
The current esphome integrated ld2410 library does not have a light component, which can be removed directly from this sensor.

Also support for this feature requires ensuring that the ld2410c firmware is at version 2.0 or higher.

please remove the line.
this onley if want keep cdc uart work with s2.and need extra change for the uart library.
ref: screek-human-sensor/1u/yaml at main · screek-workshop/screek-human-sensor · GitHub

Wow, there are a lot of interesting features in there that we would love to try. Thank you for sharing.
Especially like the rgb light part.

Hi. Which S2 version ( UART, no UART)should I use if complied with Esphome?

lolin_s2_mini will be fine.

Hi,
But which of two “1u” versions do I use? With UART or disabled UART?
I use ESPhome to compile.