mmWave sensor with wifi for $8 (work in progress)

I’m making a bunch of mmWave sensors using ESP32-C and LD2410C. I directly soldered the pins to the ESP32-C since VCC, GRD, PIn 9, and 10 as RX and TX. This makes it easier to build. I desoldered the central PIN of the LD2410C.

Testing 3 of them and it’s working great after adjusting 8 zones of power. The ESP32-C cost $4.99 (Seeed Studio store) and the LD2410C $2.50 (Aliexpress).

The LD2410C has Bluetooth that you can use out of the box with HomeAssistant if you have a Bluetooth receiver but I prepare WIFI based for the range. I only use Bluetooth to adjust the settings of LD2410C like power zones.

I’m working now on designing my own 3D-printed case.

Here’s the location of the custom components for ESPHome.

7 Likes

Hi,

thank you very much for sharing your project.

Could you please provide a link for the esp32 and the mmwave module?

And did you connect the uart port?

Another question, did you have to connect the LD2410C via Bluetooth to set it up or is uart all you need to get it working?

For ESP32-C3

You just need to connect RX and TX for LD2410C to PINs 9 and 10 of the ESP32-C.

Once you setup it up to the HomeAssistant, there will be a button that you can use to enable and disable the Bluetooth.

When I want to tune the power settings of the LD2410c, I enable the bluetooth and use the mobile app to connect to it to make the adjustment.

1 Like

Perfekt, thank you. What exactly is the Bluetooth APP for?

It’s for adjusting the power sensitivity of the mmWave for different distances both for motion and static objects.

There is a long thread with more details on the LD2410 chip if anyone is interested in more details of setting up and using the low cost mmWave sensor.

I tried to install your libraries today, but esphome is showing errors when compiling.

/data/cache/platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld: /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/ld2410.cpp.o: in function `esphome::ld2410::LD2410Component::send_command_(unsigned char, unsigned char*, int)':
/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/ld2410.cpp:70: multiple definition of `esphome::ld2410::LD2410Component::send_command_(unsigned char, unsigned char*, int)'; /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp.o:/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp:70: first defined here
/data/cache/platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld: /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/ld2410.cpp.o: in function `esphome::ld2410::map(long, long, long, long, long)':
/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/ld2410.cpp:98: multiple definition of `esphome::ld2410::map(long, long, long, long, long)'; /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp.o:/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp:98: first defined here
/data/cache/platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld: /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/ld2410.cpp.o: in function `esphome::ld2410::LD2410Component::handle_ack_data_(unsigned char*, int)':
/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/ld2410.cpp:214: multiple definition of `esphome::ld2410::LD2410Component::handle_ack_data_(unsigned char*, int)'; /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp.o:/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp:214: first defined here
/data/cache/platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld: /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/ld2410.cpp.o: in function `esphome::ld2410::LD2410Component::set_config_mode_(bool)':
/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/ld2410.cpp:310: multiple definition of `esphome::ld2410::LD2410Component::set_config_mode_(bool)'; /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp.o:/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp:310: first defined here
/data/cache/platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld: /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/ld2410.cpp.o: in function `esphome::ld2410::LD2410Component::query_parameters_()':
/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/ld2410.cpp:316: multiple definition of `esphome::ld2410::LD2410Component::query_parameters_()'; /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp.o:/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp:316: first defined here
/data/cache/platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld: /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/ld2410.cpp.o: in function `esphome::ld2410::LD2410Component::get_version_()':
/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/ld2410.cpp:317: multiple definition of `esphome::ld2410::LD2410Component::get_version_()'; /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp.o:/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp:317: first defined here
/data/cache/platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld: /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/ld2410.cpp.o: in function `esphome::ld2410::LD2410Component::setup()':
/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/ld2410.cpp:34: multiple definition of `esphome::ld2410::LD2410Component::setup()'; /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp.o:/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp:34: first defined here
/data/cache/platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld: /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/ld2410.cpp.o: in function `esphome::ld2410::LD2410Component::dump_config()':
/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/ld2410.cpp:11: multiple definition of `esphome::ld2410::LD2410Component::dump_config()'; /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp.o:/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp:11: first defined here
/data/cache/platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld: /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/ld2410.cpp.o: in function `esphome::ld2410::LD2410Component::set_max_distances_timeout_(unsigned char, unsigned char, unsigned short)':
/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/ld2410.cpp:320: multiple definition of `esphome::ld2410::LD2410Component::set_max_distances_timeout_(unsigned char, unsigned char, unsigned short)'; /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp.o:/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp:320: first defined here
/data/cache/platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld: /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/ld2410.cpp.o: in function `esphome::ld2410::LD2410Component::set_gate_threshold_(unsigned char, unsigned char, unsigned char)':
/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/ld2410.cpp:342: multiple definition of `esphome::ld2410::LD2410Component::set_gate_threshold_(unsigned char, unsigned char, unsigned char)'; /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp.o:/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp:342: first defined here
/data/cache/platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld: /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/ld2410.cpp.o: in function `esphome::ld2410::LD2410Component::factoryReset()':
/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/ld2410.cpp:359: multiple definition of `esphome::ld2410::LD2410Component::factoryReset()'; /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp.o:/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp:359: first defined here
/data/cache/platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld: /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/ld2410.cpp.o: in function `esphome::ld2410::LD2410Component::reboot()':
/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/ld2410.cpp:367: multiple definition of `esphome::ld2410::LD2410Component::reboot()'; /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp.o:/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp:367: first defined here
/data/cache/platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld: /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/ld2410.cpp.o: in function `esphome::ld2410::LD2410Component::ble_control(bool)':
/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/ld2410.cpp:377: multiple definition of `esphome::ld2410::LD2410Component::ble_control(bool)'; /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp.o:/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp:377: first defined here
/data/cache/platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld: /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/ld2410.cpp.o: in function `esphome::ld2410::LD2410Component::factory_mode(bool)':
/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/ld2410.cpp:401: multiple definition of `esphome::ld2410::LD2410Component::factory_mode(bool)'; /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp.o:/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp:401: first defined here
/data/cache/platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld: /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/ld2410.cpp.o: in function `esphome::ld2410::LD2410Component::handle_periodic_data_(unsigned char*, int)':
/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/ld2410.cpp:102: multiple definition of `esphome::ld2410::LD2410Component::handle_periodic_data_(unsigned char*, int)'; /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp.o:/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp:102: first defined here
/data/cache/platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld: /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/ld2410.cpp.o: in function `esphome::ld2410::LD2410Component::readline_(int, unsigned char*, int)':
/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/ld2410.cpp:285: multiple definition of `esphome::ld2410::LD2410Component::readline_(int, unsigned char*, int)'; /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp.o:/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp:285: first defined here
/data/cache/platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld: /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/ld2410.cpp.o: in function `esphome::ld2410::LD2410Component::loop()':
/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/ld2410.cpp:61: multiple definition of `esphome::ld2410::LD2410Component::loop()'; /data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp.o:/config/esphome/.esphome/build/esp32n-schlafzimmer-mmwave/src/esphome/components/ld2410/ld2410.cpp:61: first defined here
collect2: error: ld returned 1 exit status
*** [/data/esp32n-schlafzimmer-mmwave/.pioenvs/esp32n-schlafzimmer-mmwave/firmware.elf] Error 1
========================= [FAILED] Took 39.19 seconds =========================

Any idea what this is?

Edit: Never mind, there was some old data or something. I deleted all esphome files for this device and compiled again.

Somehow my esp32 will not connect to the ld2410. All created entities are unavailable. I don’t see anything in the log either. I did what you described in your github repo. I am able to connect via the bluetooth app to the ld2410 board.

Got it working with a different esp32 board on different pins. Thanks a lot. I especially like that you implemented the light sensor.

I have two problems though. The light sensor is jumping a lot within 20% at least.

And I see warnings in the log:

[15:03:58][W][component:204]: Component ld2410 took a long time for an operation (0.05 s).
[15:03:58][W][component:205]: Components should block for at most 20-30ms.

Is there something I can do about this?

If anyone is looking to set this up with an ESP32 S2 Mini, then I’ve created a case model along with a standoff to help with soldering. I did change the YAML from SCREEK to completely disable WiFi sleep as it was causing the sensors to disconnect momentarily every few hours.

https://www.printables.com/model/541368-case-for-esp32-s2-mini-and-ld2410c

Nice, thank you for sharing.

Got it working with the esp32 nano as well. But in my case the GPIO numbering is not correct. Here is the picture from seedstudio. If you use the GPIO name schema, use the grey numbers.

I have the problem, that the g0_still_threshold: and moving settings do nothing. If I change this values in the esphome config file and flash the new one, the still and moving targets are not recognised, though the corresponding energies are higher then the set threshold. But if I set the thresholds in via the app and bluetooth, it works.

Edit: With this driver, as many other, the configuration is only possible via bluetooth. But esphome is working on a way to make in configurable via esphome directly. Here is the pull request. With the config shown there, everything is configurable via esphome. @siganberg thank you for your work!

2 Likes

Thanks for sharing. Did you design your case?

I’ve mocked up another case using the ESP32 C3 Mini:

Here’s my design for the case that you can directly plug into the outlet. No visible wire but placement of the sensor is limited to the availability of the outlet.





2 Likes

This works great! Thank you very much for sharing!

I don’t suppose you have updated the code recently? I’m struggling to get the same thing working with the official libraries.