Most smart home motion sensors are "blind." They only tell you one thing: Occupied or Clear.
But what if your sensor could tell you how fast a person is moving? Which direction they are walking? And even the signal energy of their presence—whether they are walking or sitting completely still?
This isn't sci-fi. It's the full data stream hidden inside the DFRobot C4002 mmWave Radar Module. While consumer sensors (like Aqara or Hue) hide this raw data behind a simple app interface, the C4002 gives developers full access via UART.
Here is how you can unlock this advanced data to build automations that PIR sensors can only dream of.
Why choose a DIY module over a finished product? It comes down to Data Granularity vs. Convenience.
| Feature | PIR Sensor ($10+) | Consumer mmWave ($60 - $80) | DFRobot C4002 ($8.90 + ESP32) |
| Core Tech | Infrared (Heat) | 24Gz~60GHz Radar | 24GHz Radar |
| Output | High / Low | Zone Presence (App Encrypted) | Speed, Energy, Direction, Distance (UART Open) |
| Static Detection | No | Yes | Yes (Up to 10m) |
| Data Access | None | Closed Ecosystem | Full Raw Access |
| Total Cost | ~$15 | $60 ~ $80 | ~$15 - $20 (Module + ESP32) |
According to the official DFRobot Wiki, the C4002 outputs a rich structure of data. Let's look at the actual code (getAllResults.ino) to see what's possible.
Most sensors can't tell the difference between a leisurely walk and a sprint. The C4002 can.
The Code Evidence:
The "God Mode" Automation:
// Source: DFRobot_C4002 Library
Serial.print("Motion speed: ");
Serial.print(motionTarget.speed);
Serial.println(" m/s");The "God Mode" Automation:
Safety Monitoring: If speed > 1.5 m/s inside an elderly person's room, it might indicate a fall or an emergency. Trigger an alert immediately.
Lighting Logic: If speed < 0.5 m/s (slow walking), fade the lights on slowly. If speed > 1.0 m/s (fast walking), snap the lights on instantly to prevent accidents.
(*Note: The speed threshold should be calibrated based on the actual environment. You can use the Serial Monitor to observe the speed values during normal walking and use them as a baseline.)
Knowing where someone is going is the holy grail of automation. The C4002 classifies motion into three states: Approaching, Away, and No Direction.
The Code Evidence:
// Source: DFRobot_C4002 Library
if (motionTarget.direction == eAway) {
Serial.println("Away!");
} else if (motionTarget.direction == eApproaching) {
Serial.println("Approaching!");
}The "God Mode" Automation:
The "Welcome Home" Effect: If the sensor detects Approaching near the entryway, brighten the lights before the person even fully enters the room.
Smart Energy Saving: If the sensor detects Away (walking towards the exit), start a short countdown to turn off the HVAC, rather than waiting for a standard 5-minute timeout.
PIR sensors stop working when you sit still. The C4002 tracks TWO separate energy levels: one for large movements (walking) and one for micro-movements (such as subtle body motion during rest).
The Code Evidence:
Serial.print("Motion energy: ");
Serial.println(motionTarget.energy);The "God Mode" Automation:
True Sleep/Reading Detection: If "Motion Energy" drops to 0, but "Presence Energy" stays active (e.g., Energy = 5), the system knows the room isn't empty—you are just reading a book or sleeping. No more waving your arms to turn the lights back on.
Installation Debugging: Unlike PIR sensors where you guess the coverage, the live energy numbers help you find the perfect mounting spot. Check the Presence energy from the edge of your bed to ensure it accurately detects your breathing. It turns installation into a science.
How does this data get to your Home Assistant?
[ C4002 Module ] --(UART)--> [ FireBeetle ESP32 ] --(WiFi/ESPHome)--> [ Home Assistant ]
| | |
Sensors Raw Data Parses Data Automations
(Speed/Dir/Energy) (Text/Number Sensors) (Lights/Alerts)
For Home Assistant users, you don't even need to write C++ code. The C4002 has native ESPHome support via UART. Here is a simplified configuration snippet to get you started:
# UART Configuration
uart:
id: uart_bus
tx_pin: GPIO25
rx_pin: GPIO26
baud_rate: 115200
# External components
external_components:
- source:
type: git # Source
url: https://github.com/cdjq/esphome.git # Must be the root directory
ref: dev # Branch
components:
dfrobot_c4002 # Component
# C4002 Component Configuration
dfrobot_c4002:
id: my_c4002
# Sensor Configuration Section
sensor:
- platform: dfrobot_c4002
c4002_id: my_c4002
movement_distance:
name: "Motion Distance"
id: movement_distance_sensor # Motion distance
existing_distance:
name: "Presence Distance"
id: existing_distance_sensor # Presence distance
movement_speed:
name: "Motion Speed"
id: movement_speed_sensor
movement_direction:
name: "Motion Direction"
id: movement_direction_sensor # Motion direction
internal: true
target_status:
name: "Target Status"
id: target_status_sensor
internal: true
text_sensor:
- platform: template
name: "Movement Direction"
id: movement_direction_text
icon: "mdi:directions"
lambda: |-
int d = id(movement_direction_sensor).state;
if (d == 0) return {"Approaching"};
else if (d == 1) return {"No Direction"};
else if (d == 2) return {"Away"};
else return {"Unknown"};
update_interval: 1s
- platform: template
name: "Target Status"
id: target_status_text
icon: "mdi:human-greeting"
lambda: |-
int d = id(target_status_sensor).state;
if (d == 0) return {"No Target"};
else if (d == 1) return {"Static Presence"};
else if (d == 2) return {"Motion"};
else return {"Unknown"};
update_interval: 0.5s
- platform: dfrobot_c4002
c4002_id: my_c4002
c4002_text_sensor:
name: "C4002 log"
icon: "mdi:message-text-outline"
# Switch Configuration Section
switch:
- platform: dfrobot_c4002
switch_out_led:
name: "Out LED Switch"
switch_run_led:
name: "Run LED Switch"
switch_factory_reset:
name: "Factory Reset"
switch_environmental_calibration:
name: "Sensor Calibration"
# Select Configuration Section
select:
- platform: dfrobot_c4002
c4002_id: my_c4002
operating_mode:
name: "OUT Mode"
options:
- "Mode_1"
- "Mode_2"
- "Mode_3"
# Minimum and Maximum Detection Range Configuration
number:
- platform: dfrobot_c4002
max_range:
name: "Max detection distance"
min_range:
name: "Min detection distance"
light_threshold:
name: "Light Threshold"
target_disappeard_delay_time:
name: "Target Disappear Delay Time"
While the C4002 offers powerful data, it is a 24GHz radar, not a magic wand. Here are the physical limitations you should know before buying:
This module is built for Makers, not passive consumers. It requires a microcontroller to interpret the data.
Project Cost Breakdown:
Software Setup:
You don't need to reverse engineer the protocol. DFRobot provides a ready-to-use library.
Download the DFRobot_C4002 Library from GitHub.
Open the getAllResults.ino example.
Flash it to your ESP32.
Open the Serial Monitor and watch the "Matrix" of real-time data flow in.
If you just want a light to turn on, buy a $5 PIR sensor.
But if you want your smart home to understand context—speed, direction, and signal strength—you need raw data.
The C4002 offers a rare combination of long-range static detection (10m) and open data access at a DIY-friendly price point. It demands some coding skills, but the control it offers is worth every line of code.