I was able to source the empty enclosures and rebuild an ESP32 with nothing more than:

  • PIR Enclosure
  • ESP32(xx)
  • LD2410
  • 10cm jumper cables
  • Drill (3mm and 5mm)
  • Glue gun
  • Adhesive spacers
  • USB cables

I have been able to build variations on this with parts laying around. ESP32 D1 mini, and the ESP32-S2 with HLK-LD2410B+BLE or the HLK-LD2410C.

For the USB cables I used the magnetic variant, with interchangeable USB ends I can keep the cable in place and easily swap between USB-C / MicroUSB depending on the ESP.


What I liked about this, they are extremely simple to make, less than 30mins, (re-)built, coded, installed and working.

Tools and components

Drill holes for MCU and cable

Like any hack, some changes need to be made to the original.

Fitting MCU and other inners

Using the spacer in reverse to attach the MCU to the enclosure helps to secure it and also easy to remove / replace if needed/


A dab of hot glue to secure it.
I used the magnetic USB cable as I can replace the board and just replace the connector (USB-C / MircoUSB), not the complete cable.

Tada!

Coding

The next step will be to upload your ESPHome yaml. Have a look on how to program your ESP32 as the UART and LED pins in the sample config may differ. The example is based on the ESP32-S2. I have not fiddled with the configs so they are as vanilla as from the ESPHome site.

## motion sensor
substitutions:
  device: esp32s2
  name: '20230806-01'

esphome:
  name: ${device}-${name}
  friendly_name: ${device}-${name}
  platformio_options:
    board_build.extra_flags:
      - "-DARDUINO_USB_CDC_ON_BOOT=0"  

esp32:
  board: lolin_s2_mini
  framework:
    type: arduino


# Enable Home Assistant API
api:
  encryption:
    key: "<yours>"

ota:
  password: "<yours>"


# Enable logging
logger:
  # baud_rate: 0

<<: !include wifi-and-ap.yaml


web_server:


# motion sensor
uart:
  id: uart_1
  tx_pin: GPIO39
  rx_pin: GPIO37
  baud_rate: 256000
  parity: NONE
  stop_bits: 1


ld2410:
  timeout: 5s
  max_move_distance : 5.25m
  max_still_distance: 4.5m
  g0_move_threshold: 50
  g0_still_threshold: 20
  g1_move_threshold: 50
  g1_still_threshold: 20
  g2_move_threshold: 40
  g2_still_threshold: 40
  g3_move_threshold: 30
  g3_still_threshold: 40
  g4_move_threshold: 20
  g4_still_threshold: 30
  g5_move_threshold: 15
  g5_still_threshold: 30
  g6_move_threshold: 15
  g6_still_threshold: 20
  g7_move_threshold: 15
  g7_still_threshold: 20
  g8_move_threshold: 15
  g8_still_threshold: 20

sensor:
  - platform: ld2410
    moving_distance:
      name: "${device}_${name}_moving_distance"
    still_distance:
      name: "${device}_${name}_still_distance"
    moving_energy:
      name: "${device}_${name}_moving_energy"
    still_energy:
      name: "${device}_${name}_still_energy"
    detection_distance:
      name: "${device}_${name}_detection_distance"

binary_sensor:
  - platform: ld2410
    has_target:
      name: "${device}_${name}_has_target"
    has_moving_target:
      name: "${device}_${name}_has_moving_target"
    has_still_target:
      name: "${device}_${name}_has_still_target"


light:
  - platform: status_led
    name: "Blue LED"
    pin: LED

In the wild

Under the kitchen counter

Plugged into a router as it supports USB


It works well behind curtains


Used double sided type it fix it to an old charger - still have doubts about this one.


Fixed one to the coat rack at the one entrance