ESP32 LD2410 Human Presence Sensor
Overview
The LD2410 is a millimeter-wave radar sensor for human presence detection, supporting both stationary and moving target detection. It uses UART communication and is ideal for smart home automation systems.
About LD2410 Human Presence Sensor
The LD2410 is a 24GHz millimeter-wave radar sensor designed for detecting human presence, capable of identifying both stationary and moving targets. Unlike traditional PIR sensors, the LD2410 can detect micro-movements such as breathing, making it ideal for smart lighting, HVAC control, and security systems. It provides precise zone-based detection with configurable distance gates and supports UART communication for integration with ESP32 or Home Assistant via ESPHome.
Where to Buy
Prices are subject to change. We earn from qualifying purchases as an Amazon Associate.
Technical Specifications
Pinout Configuration
The VCC
pin is used to supply power to the sensor, and it typically requires 3.3V or 5V (refer to the datasheet for specific voltage requirements). The GND
pin is the ground connection and must be connected to the ground of your ESP32.
The LD2410 module features a set of pins that facilitate power supply, communication, and signal output:
VCC
– Power input pin; connect to a stable 5V source.GND
– Ground pin; must be connected to the system ground.TX
– UART transmit pin; sends data from the LD2410 to an external device. Connect to the RX pin on the ESP32.RX
– UART receive pin; receives data from an external device. Connect to the TX pin on the ESP32.OUT
– Optional digital output; goes high when presence is detected. Can be used to trigger logic events without UART.
Wiring with ESP32
The following wiring diagram shows how to connect the LD2410 radar presence sensor to an ESP32 board via UART:
VCC
(red wire) → 5V on ESP32GND
(black wire) → GND on ESP32TX
(green wire) → GPIO16 (RX on ESP32)RX
(blue wire) → GPIO17 (TX on ESP32)OUT
(optional, yellow wire) → GPIO18 (if using presence interrupt)
Ensure UART2 is used on the ESP32 and that all connections are secure to avoid communication issues.
Troubleshooting Guide
Common Issues
🚫 No Data Received
Issue: The ESP32 receives no data from the sensor.
Ensure correct wiring: swap TX and RX if needed, and confirm baud rate is set to 256000. Verify power is supplied at 5V.
❌ Presence Not Detected
Issue: The sensor does not detect presence even when someone is in range.
Check detection gates and sensitivity settings using the LD2410 configuration tool. Ensure ESPHome configuration matches sensor wiring.
⚠️ Intermittent Detection
Issue: Sensor intermittently detects presence or fails to maintain detection.
Adjust gate sensitivity or reposition sensor to minimize obstructions. Use HLK Radar Tool for fine-tuning detection zones.
🔌 UART Initialization Fails
Issue: UART component in ESPHome reports failure to initialize.
Verify UART pins are correct, baud rate is 256000, and no other component is using the same UART bus.
Debugging Tips
🔍 Serial Monitor
Use the Serial Monitor to check for error messages and verify the sensor's output. Add debug prints in your code to track the sensor's state.
⚡ Voltage Checks
Use a multimeter to verify voltage levels and check for continuity in your connections. Ensure the power supply is stable and within the sensor's requirements.
Additional Resources
Code Examples
Arduino Example
#if defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_AVR_LEONARDO)
//ARDUINO_SAMD_NANO_33_IOT RX_PIN is D1, TX_PIN is D0
//ARDUINO_AVR_LEONARDO RX_PIN(RXI) is D0, TX_PIN(TXO) is D1
#define sensorSerial Serial1
#elif defined(ARDUINO_XIAO_ESP32C3) || defined(ARDUINO_XIAO_ESP32C6)
//RX_PIN is D7, TX_PIN is D6
#define sensorSerial Serial0
#elif defined(ESP32)
//Other ESP32 device - choose available GPIO pins
#define sensorSerial Serial1
#if defined(ARDUINO_ESP32S3_DEV)
#define RX_PIN 18
#define TX_PIN 17
#else
#define RX_PIN 16
#define TX_PIN 17
#endif
#else
#error "This sketch only works on ESP32, Arduino Nano 33IoT, and Arduino Leonardo (Pro-Micro)"
#endif
// User defines
// #define DEBUG_MODE
#define ENHANCED_MODE
#define SERIAL_BAUD_RATE 115200
//Change the communication baud rate here, if necessary
//#define LD2410_BAUD_RATE 256000
#include "MyLD2410.h"
#ifdef DEBUG_MODE
MyLD2410 sensor(sensorSerial, true);
#else
MyLD2410 sensor(sensorSerial);
#endif
unsigned long nextPrint = 0, printEvery = 1000; // print every second
void printValue(const byte &val) {
Serial.print(' ');
Serial.print(val);
}
void printData() {
Serial.print(sensor.statusString());
if (sensor.presenceDetected()) {
Serial.print(", distance: ");
Serial.print(sensor.detectedDistance());
Serial.print("cm");
}
Serial.println();
if (sensor.movingTargetDetected()) {
Serial.print(" MOVING = ");
Serial.print(sensor.movingTargetSignal());
Serial.print("@");
Serial.print(sensor.movingTargetDistance());
Serial.print("cm ");
if (sensor.inEnhancedMode()) {
Serial.print("
signals->[");
sensor.getMovingSignals().forEach(printValue);
Serial.print(" ] thresholds:[");
sensor.getMovingThresholds().forEach(printValue);
Serial.print(" ]");
}
Serial.println();
}
if (sensor.stationaryTargetDetected()) {
Serial.print(" STATIONARY= ");
Serial.print(sensor.stationaryTargetSignal());
Serial.print("@");
Serial.print(sensor.stationaryTargetDistance());
Serial.print("cm ");
if (sensor.inEnhancedMode()) {
Serial.print("
signals->[");
sensor.getStationarySignals().forEach(printValue);
Serial.print(" ] thresholds:[");
sensor.getStationaryThresholds().forEach(printValue);
Serial.print(" ]");
}
Serial.println();
}
if (sensor.inEnhancedMode() && (sensor.getFirmwareMajor() > 1)) {
Serial.print("Light level: ");
Serial.println(sensor.getLightLevel());
Serial.print("Output level: ");
Serial.println((sensor.getOutLevel()) ? "HIGH" : "LOW");
}
Serial.println();
}
void setup() {
Serial.begin(SERIAL_BAUD_RATE);
#if defined(ARDUINO_XIAO_ESP32C3) || defined(ARDUINO_XIAO_ESP32C6) || defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_AVR_LEONARDO)
sensorSerial.begin(LD2410_BAUD_RATE);
#else
sensorSerial.begin(LD2410_BAUD_RATE, SERIAL_8N1, RX_PIN, TX_PIN);
#endif
delay(2000);
Serial.println(FILE);
if (!sensor.begin()) {
Serial.println("Failed to communicate with the sensor.");
while (true) {}
}
#ifdef ENHANCED_MODE
sensor.enhancedMode();
#else
sensor.enhancedMode(false);
#endif
delay(nextPrint);
}
void loop() {
if ((sensor.check() == MyLD2410::Response::DATA) && (millis() > nextPrint)) {
nextPrint = millis() + printEvery;
printData();
}
}
This Arduino example uses the MyLD2410
library to interface with the LD2410 radar sensor via UART. The code initializes the sensor on UART2 using GPIO16 (RX) and GPIO17 (TX), reads presence data continuously, and prints whether presence is detected to the Serial Monitor. The LD2410 supports detection of both moving and still targets, and this library abstracts the complex UART protocol into a simple interface. The library automatically handles packet parsing and offers methods like presenceDetected()
for easy integration. You can download the library or explore its source from the official GitHub repository: MyLD2410 on GitHub.
ESPHome Example
esphome:
name: ld2410_sensor
platform: ESP32
board: esp32dev
logger:
uart:
id: uart_bus
tx_pin: GPIO17
rx_pin: GPIO16
baud_rate: 256000
ld2410:
uart_id: uart_bus
binary_sensor:
- platform: ld2410
has_target:
name: "Presence Detected"
has_moving_target:
name: "Moving Target Detected"
has_still_target:
name: "Still Target Detected"
sensor:
- platform: ld2410
moving_distance:
name: "Moving Distance"
still_distance:
name: "Still Distance"
moving_energy:
name: "Moving Energy"
still_energy:
name: "Still Energy"
detection_distance:
name: "Detection Distance"
text_sensor:
- platform: ld2410
version:
name: "LD2410 Firmware Version"
mac_address:
name: "LD2410 MAC Address"
This ESPHome configuration integrates the LD2410 millimeter-wave presence sensor over UART. The uart
block sets up the UART bus on GPIO17 (TX) and GPIO16 (RX) with a baud rate of 256000, which is required by the LD2410 module. The ld2410
component is then bound to this UART interface. Binary sensors are declared to detect any presence (has_target
), moving targets (has_moving_target
), and still targets (has_still_target
). The sensor
entries allow access to distance and energy metrics from both moving and still targets, as well as the general detection distance. These values are useful for fine-tuning detection zones and behavior. This setup is fully compatible with Home Assistant and enables advanced presence-based automation. For more information, see the official documentation: ESPHome LD2410 Sensor Component.
PlatformIO Example
platformio.ini
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
lib_deps =
iavorvel/MyLD2410@^1.0.2
monitor_speed = 115200
PlatformIO Example Code
#include <MyLD2410.h>
MyLD2410 radar;
void setup() {
Serial.begin(115200);
Serial2.begin(256000, SERIAL_8N1, 16, 17); // RX=16, TX=17
if (!radar.begin(&Serial2)) {
Serial.println("Failed to initialize LD2410 sensor");
while (true) {}
}
Serial.println("LD2410 initialized successfully");
}
void loop() {
radar.read();
if (radar.presenceDetected()) {
Serial.println("Presence detected");
Serial.print("Still distance: ");
Serial.println(radar.stillDistance());
Serial.print("Moving distance: ");
Serial.println(radar.movingDistance());
} else {
Serial.println("No presence");
}
delay(1000);
}
This PlatformIO example uses the MyLD2410
library to interface with the LD2410 24GHz presence sensor via UART on an ESP32. The code initializes the sensor using Serial2
with GPIO16 as RX and GPIO17 as TX, and sets the baud rate to 256000 as required by the sensor. After successful initialization, it reads presence detection data in the main loop. The code reports whether presence is detected and prints both still and moving target distances to the Serial Monitor. The MyLD2410
library handles all packet parsing, error checking, and data structuring internally, making it easy to work with the radar's complex UART protocol. This library is actively maintained and officially hosted on the PlatformIO Registry. You can find it here: MyLD2410 PlatformIO Library.
MicroPython Example
from machine import UART
import time
# Initialize UART2: TX=17, RX=16, baud rate 256000
uart = UART(2, baudrate=256000, tx=17, rx=16)
# Function to read and print data from LD2410
def read_ld2410():
while True:
if uart.any():
data = uart.read()
if data:
print(data)
time.sleep(0.1)
read_ld2410()
This MicroPython script initializes UART2 on an ESP32 with TX on GPIO17 and RX on GPIO16 at a baud rate of 256000, which is required by the LD2410 sensor. It continuously reads data from the sensor and prints the raw bytes to the console. This setup allows for basic communication with the LD2410 sensor. For more advanced features and parsing of the sensor's data, refer to the MicroPython driver available at vjsyong/LD2410.
Conclusion
The ESP32 LD2410 Human Presence Sensor is a powerful Human Presence sensor that offers excellent performance and reliability. With support for multiple development platforms including Arduino, ESP-IDF, ESPHome, PlatformIO, and MicroPython, it's a versatile choice for your IoT projects.
For optimal performance, ensure proper wiring and follow the recommended configuration for your chosen development platform.
Always verify power supply requirements and pin connections before powering up your project to avoid potential damage.