LD2410Async
Asynchronous Arduino ESP32 library for the LD2410 mmWave radar sensor
Loading...
Searching...
No Matches
LD2410Types.h
Go to the documentation of this file.
1#pragma once
2
3
4#include <Arduino.h>
5
6/**
7 * @brief All enums, structs, and type helpers for LD2410Async.
8 */
9namespace LD2410Types {
10 /**
11 * @brief Represents the current target detection state reported by the radar.
12 *
13 * Values can be combined internally by the sensor depending on its
14 * signal evaluation logic. The AUTO-CONFIG states are special values
15 * that are only reported while the sensor is running its
16 * self-calibration routine.
17 *
18 */
19
20 enum class TargetState {
21 NO_TARGET = 0, ///< No moving or stationary target detected.
22 MOVING_TARGET = 1, ///< A moving target has been detected.
23 STATIONARY_TARGET = 2, ///< A stationary target has been detected.
24 MOVING_AND_STATIONARY_TARGET = 3, ///< Both moving and stationary targets detected.
25 AUTOCONFIG_IN_PROGRESS = 4, ///< Auto-configuration routine is running.
26 AUTOCONFIG_SUCCESS = 5, ///< Auto-configuration completed successfully.
27 AUTOCONFIG_FAILED = 6 ///< Auto-configuration failed.
28 };
29
30 /**
31 * @brief Safely converts a numeric value to a TargetState enum.
32 *
33 * @param value Raw numeric value (0-6 expected).
34 * - 0 - NO_TARGET
35 * - 1 - MOVING_TARGET
36 * - 2 - STATIONARY_TARGET
37 * - 3 - MOVING_AND_STATIONARY_TARGET
38 * - 4 - AUTOCONFIG_IN_PROGRESS
39 * - 5 - AUTOCONFIG_SUCCESS
40 * - 6 - AUTOCONFIG_FAILED
41 * @returns The matching TargetState value, or NO_TARGET if invalid.
42 *
43 */
44 static TargetState toTargetState(int value) {
45 switch (value) {
46 case 0: return TargetState::NO_TARGET;
47 case 1: return TargetState::MOVING_TARGET;
48 case 2: return TargetState::STATIONARY_TARGET;
52 case 6: return TargetState::AUTOCONFIG_FAILED;
53 default: return TargetState::NO_TARGET; // safe fallback
54 }
55 }
56
57 /**
58 * @brief Converts a TargetState enum value to a human-readable String.
59 *
60 * Useful for printing detection results in logs or Serial Monitor.
61 *
62 * @param state TargetState enum value.
63 * @returns Human-readable string such as "No target", "Moving target", etc.
64 *
65 */
66 static String targetStateToString(TargetState state) {
67 switch (state) {
68 case TargetState::NO_TARGET: return "No target";
69 case TargetState::MOVING_TARGET: return "Moving target";
70 case TargetState::STATIONARY_TARGET: return "Stationary target";
71 case TargetState::MOVING_AND_STATIONARY_TARGET: return "Moving and stationary target";
72 case TargetState::AUTOCONFIG_IN_PROGRESS: return "Auto-config in progress";
73 case TargetState::AUTOCONFIG_SUCCESS: return "Auto-config success";
74 case TargetState::AUTOCONFIG_FAILED: return "Auto-config failed";
75 default: return "Unknown";
76 }
77 }
78
79
80
81
82
83
84 /**
85 * @brief Light-dependent control status of the auxiliary output.
86 *
87 * The radar sensor can control an external output based on ambient
88 * light level in combination with presence detection.
89 *
90 * Use NOT_SET only as a placeholder; it is not a valid configuration value.
91 *
92 */
93 enum class LightControl {
94 NOT_SET = -1, ///< Placeholder for the initial value. Do not use as a config value (it will cause the configuration command to abort).
95 NO_LIGHT_CONTROL = 0, ///< Output is not influenced by light levels.
96 LIGHT_BELOW_THRESHOLD = 1, ///< Condition: light < threshold.
97 LIGHT_ABOVE_THRESHOLD = 2 ///< Condition: light >= threshold.
98 };
99 /**
100 * @brief Safely converts a numeric value to a LightControl enum.
101 *
102 * @param value Raw numeric value (0-2 expected).
103 * - 0 - NO_LIGHT_CONTROL
104 * - 1 - LIGHT_BELOW_THRESHOLD
105 * - 2 - LIGHT_ABOVE_THRESHOLD
106 * @returns The matching LightControl value, or NOT_SET if invalid.
107 *
108 */
109 static LightControl toLightControl(int value) {
110 switch (value) {
111 case 0: return LightControl::NO_LIGHT_CONTROL;
114 default: return LightControl::NOT_SET;
115 }
116 }
117
118
119 /**
120 * @brief Logic level behavior of the auxiliary output pin.
121 *
122 * Determines whether the output pin is active-high or active-low
123 * in relation to presence detection.
124 *
125 * Use NOT_SET only as a placeholder; it is not a valid configuration value.
126 *
127 */
128 enum class OutputControl {
129 NOT_SET = -1, ///< Placeholder for the initial value. Do not use as a config value (it will cause the configuration command to abort).
130 DEFAULT_LOW_DETECTED_HIGH = 0, ///< Default low, goes HIGH when detection occurs.
131 DEFAULT_HIGH_DETECTED_LOW = 1 ///< Default high, goes LOW when detection occurs.
132 };
133
134 /**
135 * @brief Safely converts a numeric value to an OutputControl enum.
136 *
137 * @param value Raw numeric value (0-1 expected).
138 * - 0 - DEFAULT_LOW_DETECTED_HIGH
139 * - 1 - DEFAULT_HIGH_DETECTED_LOW
140 * @returns The matching OutputControl value, or NOT_SET if invalid.
141 *
142 */
143 static OutputControl toOutputControl(int value) {
144 switch (value) {
147 default: return OutputControl::NOT_SET;
148 }
149 }
150
151 /**
152 * @brief State of the automatic threshold configuration routine.
153 *
154 * Auto-config adjusts the sensitivity thresholds for optimal detection
155 * in the current environment. This process may take several seconds.
156 *
157 * Use NOT_SET only as a placeholder; it is not a valid configuration value.
158 *
159 */
160 enum class AutoConfigStatus {
161 NOT_SET = -1, ///< Status not yet retrieved.
162 NOT_IN_PROGRESS, ///< Auto-configuration not running.
163 IN_PROGRESS, ///< Auto-configuration is currently running.
164 COMPLETED ///< Auto-configuration finished (success or failure).
165 };
166
167 /**
168 * @brief Safely converts a numeric value to an AutoConfigStatus enum.
169 *
170 * @param value Raw numeric value (0-2 expected).
171 * - 0 - NOT_IN_PROGRESS
172 * - 1 - IN_PROGRESS
173 * - 2 - COMPLETED
174 * @returns The matching AutoConfigStatus value, or NOT_SET if invalid.
175 *
176 */
177 static AutoConfigStatus toAutoConfigStatus(int value) {
178 switch (value) {
180 case 1: return AutoConfigStatus::IN_PROGRESS;
181 case 2: return AutoConfigStatus::COMPLETED;
182 default: return AutoConfigStatus::NOT_SET;
183 }
184 }
185
186
187 /**
188 * @brief Supported baud rates for the sensor's UART interface.
189 *
190 * These values correspond to the configuration commands accepted
191 * by the LD2410. After changing the baud rate, a sensor reboot
192 * is required, and the ESP32's UART must be reconfigured to match.
193 *
194 */
195 enum class Baudrate {
196 BAUDRATE_9600 = 1, ///< 9600 baud.
197 BAUDRATE_19200 = 2, ///< 19200 baud.
198 BAUDRATE_38400 = 3, ///< 38400 baud.
199 BAUDRATE_57600 = 4, ///< 57600 baud.
200 BAUDRATE_115200 = 5, ///< 115200 baud.
201 BAUDRATE_230500 = 6, ///< 230400 baud.
202 BAUDRATE_256000 = 7, ///< 256000 baud (factory default).
203 BAUDRATE_460800 = 8 ///< 460800 baud (high-speed).
204 };
205
206 /**
207 * @brief Distance resolution per gate for detection.
208 *
209 * The resolution defines how fine-grained the distance measurement is:
210 * - RESOLUTION_75CM: Coarser, maximum range up to about 6 m, each gate approximately 0.75 m wide.
211 * - RESOLUTION_20CM: Finer, maximum range up to about 1.8 m, each gate approximately 0.20 m wide.
212 *
213 * Use NOT_SET only as a placeholder; it is not a valid configuration value.
214 *
215 */
217 NOT_SET = -1, ///< Placeholder for the initial value. Do not use as a config value (it will cause the configuration command to abort).
218 RESOLUTION_75CM = 0, ///< Each gate is about 0.75 m, max range about 6 m.
219 RESOLUTION_20CM = 1 ///< Each gate is about 0.20 m, max range about 1.8 m.
220 };
221 /**
222 * @brief Safely converts a numeric value to a DistanceResolution enum.
223 *
224 * @param value Raw numeric value (typically from a sensor response).
225 * Expected values:
226 * - 0 - RESOLUTION_75CM
227 * - 1 - RESOLUTION_20CM
228 * @returns The matching DistanceResolution value, or NOT_SET if invalid.
229 *
230 */
231 static DistanceResolution toDistanceResolution(int value) {
232 switch (value) {
235 default: return DistanceResolution::NOT_SET;
236 }
237 }
238
239 /**
240 * @brief Holds the most recent detection data reported by the radar.
241 *
242 * This structure is continuously updated as new frames arrive.
243 * Values reflect either the basic presence information or, if
244 * engineering mode is enabled, per-gate signal details.
245 *
246 */
248 {
249 unsigned long timestamp = 0; ///< Timestamp (ms since boot) when this data was received.
250
251 // === Basic detection results ===
252
253 bool engineeringMode = false; ///< True if engineering mode data was received.
254
255 bool presenceDetected = false; ///< True if any target is detected.
256 bool movingPresenceDetected = false; ///< True if a moving target is detected.
257 bool stationaryPresenceDetected = false; ///< True if a stationary target is detected.
258
259 TargetState targetState = TargetState::NO_TARGET; ///< Current detection state.
260 unsigned int movingTargetDistance = 0; ///< Distance (cm) to the nearest moving target.
261 byte movingTargetSignal = 0; ///< Signal strength (0-100) of the moving target.
262 unsigned int stationaryTargetDistance = 0; ///< Distance (cm) to the nearest stationary target.
263 byte stationaryTargetSignal = 0; ///< Signal strength (0-100) of the stationary target.
264 unsigned int detectedDistance = 0; ///< General detection distance (cm).
265
266 // === Engineering mode data ===
267 byte movingTargetGateSignalCount = 0; ///< Number of gates with moving target signals.
268 byte movingTargetGateSignals[9] = { 0 }; ///< Per-gate signal strengths for moving targets.
269
270 byte stationaryTargetGateSignalCount = 0; ///< Number of gates with stationary target signals.
271 byte stationaryTargetGateSignals[9] = { 0 }; ///< Per-gate signal strengths for stationary targets.
272
273 byte lightLevel = 0; ///< Reported ambient light level (0-255).
274 bool outPinStatus = 0; ///< Current status of the OUT pin (true = high, false = low).
275
276
277 /**
278 * @brief Debug helper: print detection data contents to Serial.
279 */
280 void print() const {
281 Serial.println("=== DetectionData ===");
282
283 Serial.print(" Timestamp: ");
284 Serial.println(timestamp);
285
286 Serial.print(" Engineering Mode: ");
287 Serial.println(engineeringMode ? "Yes" : "No");
288
289 Serial.print(" Target State: ");
290 Serial.println(static_cast<int>(targetState));
291
292 Serial.print(" Moving Target Distance (cm): ");
293 Serial.println(movingTargetDistance);
294
295 Serial.print(" Moving Target Signal: ");
296 Serial.println(movingTargetSignal);
297
298 Serial.print(" Stationary Target Distance (cm): ");
299 Serial.println(stationaryTargetDistance);
300
301 Serial.print(" Stationary Target Signal: ");
302 Serial.println(stationaryTargetSignal);
303
304 Serial.print(" Detected Distance (cm): ");
305 Serial.println(detectedDistance);
306
307 Serial.print(" Light Level: ");
308 Serial.println(lightLevel);
309
310 Serial.print(" OUT Pin Status: ");
311 Serial.println(outPinStatus ? "High" : "Low");
312
313 // --- Engineering mode fields ---
314 if (engineeringMode) {
315 Serial.println(" --- Engineering Mode Data ---");
316
317 Serial.print(" Moving Target Gate Signal Count: ");
318 Serial.println(movingTargetGateSignalCount);
319
320 Serial.print(" Moving Target Gate Signals: ");
321 for (int i = 0; i < movingTargetGateSignalCount; i++) {
322 Serial.print(movingTargetGateSignals[i]);
323 if (i < movingTargetGateSignalCount - 1) Serial.print(",");
324 }
325 Serial.println();
326
327 Serial.print(" Stationary Target Gate Signal Count: ");
328 Serial.println(stationaryTargetGateSignalCount);
329
330 Serial.print(" Stationary Target Gate Signals: ");
331 for (int i = 0; i < stationaryTargetGateSignalCount; i++) {
332 Serial.print(stationaryTargetGateSignals[i]);
333 if (i < stationaryTargetGateSignalCount - 1) Serial.print(",");
334 }
335 Serial.println();
336 }
337
338 Serial.println("======================");
339 }
340
341 };
342
343 /**
344 * @brief Stores the sensor's configuration parameters.
345 *
346 * This structure represents both static capabilities
347 * (e.g. number of gates) and configurable settings
348 * (e.g. sensitivities, timeouts, resolution).
349 *
350 * The values are typically filled by request commands
351 * such as requestAllConfigSettingsAsync() or requestGateParametersAsync() or
352 * requestAuxControlSettingsAsync() or requestDistanceResolutioncmAsync().
353 *
354 */
355 struct ConfigData {
356 // === Radar capabilities ===
357 byte numberOfGates = 0; ///< Number of distance gates (2-8). This member is read-only; changing its value will not influence the radar setting when configureAllConfigSettingsAsync() is called. It is not entirely clear what this value represents, but it seems to indicate the number of gates on the sensor.
358
359 // === Max distance gate settings ===
360 byte maxMotionDistanceGate = 0; ///< Furthest gate used for motion detection.
361 byte maxStationaryDistanceGate = 0; ///< Furthest gate used for stationary detection.
362
363 // === Per-gate sensitivity settings ===
364 byte distanceGateMotionSensitivity[9] = { 0 }; ///< Motion sensitivity values per gate (0-100).
365 byte distanceGateStationarySensitivity[9] = { 0 }; ///< Stationary sensitivity values per gate (0-100).
366
367 // === Timeout parameters ===
368 unsigned short noOneTimeout = 0; ///< Timeout (seconds) until "no presence" is declared.
369
370 // === Distance resolution ===
371 DistanceResolution distanceResolution = DistanceResolution::NOT_SET; ///< Current distance resolution. A reboot is required to activate changes after configureAllConfigSettingsAsync() is called.
372
373 // === Auxiliary controls ===
374 byte lightThreshold = 0; ///< Threshold for auxiliary light control (0-255).
375 LightControl lightControl = LightControl::NOT_SET; ///< Light-dependent auxiliary control mode.
376 OutputControl outputControl = OutputControl::NOT_SET; ///< Logic configuration of the OUT pin.
377
378
379
380 /**
381 * @brief Validates the configuration data for correctness.
382 *
383 * Ensures that enum values are set and values are within valid ranges.
384 * This method is called internally before applying a config
385 * via configureAllConfigSettingsAsync().
386 *
387 * @returns True if the configuration is valid, false otherwise.
388 */
389 bool isValid() const {
390 // Validate enum settings
392 if (lightControl == LightControl::NOT_SET) return false;
393 if (outputControl == OutputControl::NOT_SET) return false;
394
395 // Validate max distance gates
398
399 // Validate sensitivities
400 for (int i = 0; i < 9; i++) {
401 if (distanceGateMotionSensitivity[i] > 100) return false;
402 if (distanceGateStationarySensitivity[i] > 100) return false;
403 }
404
405 return true;
406 }
407
408 /**
409 * @brief Compares this ConfigData with another for equality.
410 *
411 * @param other The other ConfigData instance to compare against.
412 * @returns True if all fields are equal, false otherwise.
413 */
414 bool equals(const ConfigData& other) const {
415 if (numberOfGates != other.numberOfGates) return false;
416 if (maxMotionDistanceGate != other.maxMotionDistanceGate) return false;
417 if (maxStationaryDistanceGate != other.maxStationaryDistanceGate) return false;
418 if (noOneTimeout != other.noOneTimeout) return false;
419 if (distanceResolution != other.distanceResolution) return false;
420 if (lightThreshold != other.lightThreshold) return false;
421 if (lightControl != other.lightControl) return false;
422 if (outputControl != other.outputControl) return false;
423
424 for (int i = 0; i < 9; i++) {
425 if (distanceGateMotionSensitivity[i] != other.distanceGateMotionSensitivity[i]) return false;
427 }
428 return true;
429 }
430
431 /**
432 * @brief Debug helper: print configuration contents to Serial.
433 */
434 void print() const {
435 Serial.println("=== ConfigData ===");
436
437 Serial.print(" Number of Gates: ");
438 Serial.println(numberOfGates);
439
440 Serial.print(" Max Motion Distance Gate: ");
441 Serial.println(maxMotionDistanceGate);
442
443 Serial.print(" Max Stationary Distance Gate: ");
444 Serial.println(maxStationaryDistanceGate);
445
446 Serial.print(" Motion Sensitivity: ");
447 for (int i = 0; i < 9; i++) {
448 Serial.print(distanceGateMotionSensitivity[i]);
449 if (i < 8) Serial.print(",");
450 }
451 Serial.println();
452
453 Serial.print(" Stationary Sensitivity: ");
454 for (int i = 0; i < 9; i++) {
455 Serial.print(distanceGateStationarySensitivity[i]);
456 if (i < 8) Serial.print(",");
457 }
458 Serial.println();
459
460 Serial.print(" No One Timeout: ");
461 Serial.println(noOneTimeout);
462
463 Serial.print(" Distance Resolution: ");
464 Serial.println(static_cast<int>(distanceResolution));
465
466 Serial.print(" Light Threshold: ");
467 Serial.println(lightThreshold);
468
469 Serial.print(" Light Control: ");
470 Serial.println(static_cast<int>(lightControl));
471
472 Serial.print(" Output Control: ");
473 Serial.println(static_cast<int>(outputControl));
474
475 Serial.println("===================");
476 }
477 };
478
479 struct StaticData {
480 /**
481 * @brief Protocol version reported by the radar.
482 *
483 * This value is set when entering config mode. It can be useful
484 * for compatibility checks between firmware and library.
485 *
486 */
487 uint16_t protocolVersion = 0;
488
489 /**
490 * @brief Buffer size reported by the radar protocol.
491 *
492 * Set when entering config mode. Typically not required by users
493 * unless debugging low-level protocol behavior.
494 *
495 */
496 uint16_t bufferSize = 0;
497
498
499 /**
500 * @brief Firmware version string of the radar.
501 *
502 * Populated by requestFirmwareAsync(). Format is usually
503 * "major.minor.build".
504 *
505 */
506 char firmwareText[16] = { 0 };
507
508 /**
509 * @brief MAC address of the radar's Bluetooth module (if available).
510 *
511 * Populated by requestBluetoothMacAddressAsync().
512 *
513 */
515
516 /**
517 * @brief MAC address as a human-readable string (e.g. "AA:BB:CC:DD:EE:FF").
518 *
519 * Populated by requestBluetoothMacAddressAsync().
520 *
521 */
522 char bluetoothMacText[18] = { 0 };
523
524 };
525
526}
All enums, structs, and type helpers for LD2410Async.
Definition LD2410Types.h:9
AutoConfigStatus
State of the automatic threshold configuration routine.
@ NOT_SET
Status not yet retrieved.
@ COMPLETED
Auto-configuration finished (success or failure).
@ IN_PROGRESS
Auto-configuration is currently running.
@ NOT_IN_PROGRESS
Auto-configuration not running.
OutputControl
Logic level behavior of the auxiliary output pin.
@ NOT_SET
Placeholder for the initial value. Do not use as a config value (it will cause the configuration comm...
@ DEFAULT_HIGH_DETECTED_LOW
Default high, goes LOW when detection occurs.
@ DEFAULT_LOW_DETECTED_HIGH
Default low, goes HIGH when detection occurs.
@ BAUDRATE_57600
57600 baud.
@ BAUDRATE_38400
38400 baud.
@ BAUDRATE_230500
230400 baud.
@ BAUDRATE_115200
115200 baud.
@ BAUDRATE_256000
256000 baud (factory default).
@ BAUDRATE_19200
19200 baud.
@ BAUDRATE_9600
9600 baud.
@ BAUDRATE_460800
460800 baud (high-speed).
DistanceResolution
Distance resolution per gate for detection.
@ NOT_SET
Placeholder for the initial value. Do not use as a config value (it will cause the configuration comm...
@ RESOLUTION_20CM
Each gate is about 0.20 m, max range about 1.8 m.
@ RESOLUTION_75CM
Each gate is about 0.75 m, max range about 6 m.
TargetState
Represents the current target detection state reported by the radar.
Definition LD2410Types.h:20
@ MOVING_AND_STATIONARY_TARGET
Both moving and stationary targets detected.
@ NO_TARGET
No moving or stationary target detected.
@ AUTOCONFIG_IN_PROGRESS
Auto-configuration routine is running.
@ AUTOCONFIG_FAILED
Auto-configuration failed.
@ STATIONARY_TARGET
A stationary target has been detected.
@ MOVING_TARGET
A moving target has been detected.
@ AUTOCONFIG_SUCCESS
Auto-configuration completed successfully.
LightControl
Light-dependent control status of the auxiliary output.
Definition LD2410Types.h:93
@ NOT_SET
Placeholder for the initial value. Do not use as a config value (it will cause the configuration comm...
@ LIGHT_BELOW_THRESHOLD
Condition: light < threshold.
@ LIGHT_ABOVE_THRESHOLD
Condition: light >= threshold.
@ NO_LIGHT_CONTROL
Output is not influenced by light levels.
byte distanceGateStationarySensitivity[9]
Stationary sensitivity values per gate (0-100).
void print() const
Debug helper: print configuration contents to Serial.
byte distanceGateMotionSensitivity[9]
Motion sensitivity values per gate (0-100).
byte maxMotionDistanceGate
Furthest gate used for motion detection.
OutputControl outputControl
Logic configuration of the OUT pin.
bool equals(const ConfigData &other) const
Compares this ConfigData with another for equality.
byte lightThreshold
Threshold for auxiliary light control (0-255).
bool isValid() const
Validates the configuration data for correctness.
LightControl lightControl
Light-dependent auxiliary control mode.
byte maxStationaryDistanceGate
Furthest gate used for stationary detection.
byte numberOfGates
Number of distance gates (2-8). This member is read-only; changing its value will not influence the r...
DistanceResolution distanceResolution
Current distance resolution. A reboot is required to activate changes after configureAllConfigSetting...
unsigned short noOneTimeout
Timeout (seconds) until "no presence" is declared.
Holds the most recent detection data reported by the radar.
void print() const
Debug helper: print detection data contents to Serial.
byte stationaryTargetGateSignals[9]
Per-gate signal strengths for stationary targets.
bool engineeringMode
True if engineering mode data was received.
bool stationaryPresenceDetected
True if a stationary target is detected.
byte stationaryTargetSignal
Signal strength (0-100) of the stationary target.
byte lightLevel
Reported ambient light level (0-255).
unsigned int detectedDistance
General detection distance (cm).
byte movingTargetGateSignalCount
Number of gates with moving target signals.
TargetState targetState
Current detection state.
byte movingTargetGateSignals[9]
Per-gate signal strengths for moving targets.
byte stationaryTargetGateSignalCount
Number of gates with stationary target signals.
bool presenceDetected
True if any target is detected.
byte movingTargetSignal
Signal strength (0-100) of the moving target.
bool outPinStatus
Current status of the OUT pin (true = high, false = low).
unsigned long timestamp
Timestamp (ms since boot) when this data was received.
bool movingPresenceDetected
True if a moving target is detected.
unsigned int movingTargetDistance
Distance (cm) to the nearest moving target.
unsigned int stationaryTargetDistance
Distance (cm) to the nearest stationary target.
char bluetoothMacText[18]
MAC address as a human-readable string (e.g. "AA:BB:CC:DD:EE:FF").
uint16_t protocolVersion
Protocol version reported by the radar.
char firmwareText[16]
Firmware version string of the radar.
uint16_t bufferSize
Buffer size reported by the radar protocol.