19 for (
int j = 3; j >= 0; j--)
22 if (buffer[iMax] != pattern[j]) {
33 if (addZero && (bStr.length() == 1))
44bool LD2410Async::readFramePayloadSize(
byte b, ReadFrameState nextReadFrameState) {
45 receiveBuffer[receiveBufferIndex++] = b;
46 if (receiveBufferIndex >= 2) {
47 payloadSize = receiveBuffer[0] | (receiveBuffer[1] << 8);
48 if (payloadSize <= 0 || payloadSize >
sizeof(receiveBuffer) - 4) {
53 readFrameState = ReadFrameState::WAITING_FOR_HEADER;
56 receiveBufferIndex = 0;
57 readFrameState = nextReadFrameState;
64LD2410Async::FrameReadResponse LD2410Async::readFramePayload(
byte b,
const byte* tailPattern, LD2410Async::FrameReadResponse successResponseType) {
65 receiveBuffer[receiveBufferIndex++] = b;
68 if (receiveBufferIndex >= payloadSize + 4) {
70 readFrameState = ReadFrameState::WAITING_FOR_HEADER;
72 if (
bufferEndsWith(receiveBuffer, receiveBufferIndex, tailPattern)) {
73 return successResponseType;
85LD2410Async::FrameReadResponse LD2410Async::readFrame()
87 while (sensor->available()) {
88 byte b = sensor->read();
90 switch (readFrameState) {
91 case WAITING_FOR_HEADER:
93 readFrameHeaderIndex = 1;
94 readFrameState = DATA_HEADER;
98 readFrameHeaderIndex = 1;
99 readFrameState = ACK_HEADER;
106 readFrameHeaderIndex++;
109 receiveBufferIndex = 0;
110 readFrameState = READ_DATA_SIZE;
116 readFrameHeaderIndex = 1;
122 readFrameHeaderIndex = 1;
123 readFrameState = ACK_HEADER;
128 readFrameState = WAITING_FOR_HEADER;
129 readFrameHeaderIndex = 0;
136 readFrameHeaderIndex++;
139 receiveBufferIndex = 0;
140 readFrameState = READ_ACK_SIZE;
144 readFrameHeaderIndex = 1;
150 readFrameHeaderIndex = 1;
151 readFrameState = DATA_HEADER;
155 readFrameState = WAITING_FOR_HEADER;
156 readFrameHeaderIndex = 0;
163 readFramePayloadSize(b, READ_ACK_PAYLOAD);
167 readFramePayloadSize(b, READ_DATA_PAYLOAD);
170 case READ_ACK_PAYLOAD:
173 case READ_DATA_PAYLOAD:
177 readFrameState = WAITING_FOR_HEADER;
178 readFrameHeaderIndex = 0;
191 detectionDataCallback = callback;
195 configUpdateReceivedReceivedCallback = callback;
199 configChangedCallback = callback;
204void LD2410Async::executeConfigUpdateReceivedCallback() {
206 if (configUpdateReceivedReceivedCallback) {
207 configUpdateReceivedReceivedCallback(
this);
212void LD2410Async::executeConfigChangedCallback() {
214 if (configChangedCallback) {
215 configChangedCallback(
this);
221bool LD2410Async::processAck()
228 byte command = receiveBuffer[0];
229 byte success = receiveBuffer[1];
256 executeConfigChangedCallback();
261 DEBUG_PRINTLN(
"ACK for engineeringModeEnableComand received");
266 DEBUG_PRINTLN(
"ACK for engineeringModeDisableComand received");
274 DEBUG_PRINTLN(
"ACK for restoreFactorySettingsAsyncCommand received");
275 executeConfigChangedCallback();
290 DEBUG_PRINTLN(
"ACK for getBluetoothPermissionsCommand received");
294 DEBUG_PRINTLN(
"ACK for setBluetoothPasswordCommand received");
298 DEBUG_PRINTLN(
"ACK for setDistanceResolutionCommand received");
299 executeConfigChangedCallback();
304 DEBUG_PRINTLN(
"ACK for requestDistanceResolutionCommand received");
305 executeConfigUpdateReceivedCallback();
309 DEBUG_PRINTLN(
"ACK for setAuxControlSettingsCommand received");
310 executeConfigChangedCallback();
313 for (
int i = 0; i < 6; i++) {
319 "%02X:%02X:%02X:%02X:%02X:%02X",
323 DEBUG_PRINTLN(
"ACK for requestBluetoothMacAddressAsyncCommand received");
327 "%X.%02X.%02X%02X%02X%02X",
335 DEBUG_PRINTLN(
"ACK for requestFirmwareAsyncCommand received");
343 DEBUG_PRINTLN(
"ACK for requestAuxControlSettingsCommand received");
344 executeConfigUpdateReceivedCallback();
353 DEBUG_PRINTLN(
"ACK for requestAutoConfigStatusCommand received");
366 DEBUG_PRINTLN(
"ACK for requestGateParametersAsync received");
367 executeConfigUpdateReceivedCallback();
371 DEBUG_PRINTLN(
"ACK for distanceGateSensitivityConfigCommand received");
372 executeConfigChangedCallback();
376 DEBUG_PRINT(
"ACK for unknown command received. Command code: ");
389bool LD2410Async::processData()
396 if (((receiveBuffer[0] == 1) || (receiveBuffer[0] == 2)) && (receiveBuffer[1] == 0xAA))
450 if (index < payloadSize) {
452 if (index < payloadSize) {
465 if (rebootAsyncPending) {
469 if (detectionDataCallback !=
nullptr) {
487void LD2410Async::sendCommand(
const byte* command) {
488 byte size = command[0] + 2;
493 sensor->write(command, size);
502 if (sendCommandAsyncCommandPending && sendCommandAsyncCommandCode == commandCode) {
511 sendCommandAsyncCallback =
nullptr;
512 sendCommandAsyncStartMs = 0;
513 sendCommandAsyncCommandCode = 0;
514 sendCommandAsyncCommandPending =
false;
535void LD2410Async::sendCommandAsyncHandleTimeout() {
537 if (sendCommandAsyncCommandPending && sendCommandAsyncStartMs != 0) {
538 unsigned long elapsedTime = millis() - sendCommandAsyncStartMs;
539 if (elapsedTime > asyncCommandTimeoutMs) {
541 DEBUG_PRINT(
"Command timeout detected. Elapsed time: ");
545 if (sendCommandAsyncRetriesLeft > 0) {
548 sendCommandAsyncRetriesLeft--;
550 sendCommandAsyncStartMs = millis();
551 sendCommand(sendCommandAsyncCommandBuffer);
564void LD2410Async::sendCommandAsyncStoreDataForCallback(
const byte* command,
byte retries, AsyncCommandCallback callback) {
565 sendCommandAsyncCommandPending =
true;
566 sendCommandAsyncCallback = callback;
567 sendCommandAsyncCommandCode = command[2];
568 sendCommandAsyncRetriesLeft = retries;
570 memcpy(sendCommandAsyncCommandBuffer, command, command[0] + 2);
574bool LD2410Async::sendCommandAsync(
const byte* command,
byte retries, AsyncCommandCallback callback)
579 if (!sendCommandAsyncCommandPending) {
583 sendCommandAsyncStoreDataForCallback(command, retries, callback);
586 sendCommandAsyncStartMs = millis();
587 sendCommand(command);
598 DEBUG_PRINT(
"Error! Async command is pending. Did not send async command ");
611 return sendCommandAsyncCommandPending || executeCommandSequencePending || configureAllConfigSettingsAsyncConfigActive || rebootAsyncPending;
619bool LD2410Async::sendConfigCommandAsync(
const byte* command, AsyncCommandCallback callback) {
621 if (sendCommandAsyncCommandPending || executeCommandSequencePending)
return false;
624 if (!resetCommandSequence())
return false;;
627 if (!addCommandToSequence(command))
return false;
630 return executeCommandSequenceAsync(callback);
637 if (executeCommandSequencePending) {
645 executeCommandSequenceCallback =
nullptr;
646 executeCommandSequencePending =
false;
663 DEBUG_PRINTLN(
"Warning: Disabling config mode after command sequence failed. Result: ");
665 sequenceResult = result;
667 sender->executeCommandSequenceAsyncExecuteCallback(sequenceResult);
671 if (!executeCommandSequenceInitialConfigModeState) {
672 executeCommandSequenceResultToReport = result;
673 if (!disableConfigModeInternalAsync(executeCommandSequenceAsyncDisableConfigModeCallback)) {
678 executeCommandSequenceAsyncExecuteCallback(result);
688 DEBUG_PRINT(
"Error: Command sequence aborted due to command failure. Result: ");
690 sender->executeCommandSequenceAsyncFinalize(result);
696 sender->executeCommandSequenceIndex++;
698 if (sender->executeCommandSequenceIndex < sender->commandSequenceBufferCount) {
700 sender->sendCommandAsync(sender->commandSequenceBuffer[sender->executeCommandSequenceIndex], executeCommandSequenceAsyncCommandCallback);
711bool LD2410Async::executeCommandSequenceAsync(AsyncCommandCallback callback) {
712 if (sendCommandAsyncCommandPending || executeCommandSequencePending)
return false;
713 if (commandSequenceBufferCount == 0)
return true;
716 DEBUG_PRINT(
"Starting command sequence execution. Number of commands: ");
719 executeCommandSequencePending =
true;
720 executeCommandSequenceCallback = callback;
722 executeCommandSequenceStartMs = millis();
724 if (commandSequenceBufferCount == 0) {
726 executeCommandSequenceOnceTicker.once_ms(1, [
this]() {
736 executeCommandSequenceIndex = -1;
742 executeCommandSequenceIndex = 0;
743 return sendCommandAsync(commandSequenceBuffer[executeCommandSequenceIndex], executeCommandSequenceAsyncCommandCallback);
748bool LD2410Async::addCommandToSequence(
const byte* command) {
749 if (sendCommandAsyncCommandPending || executeCommandSequencePending)
return false;
751 if (commandSequenceBufferCount >= MAX_COMMAND_SEQUENCE_LENGTH) {
757 uint8_t len = command[0];
758 uint8_t totalLen = len + 2;
762 DEBUG_PRINTLN(
"Error: Command too long for command sequence buffer.");
765 memcpy(commandSequenceBuffer[commandSequenceBufferCount],
769 commandSequenceBufferCount++;
778bool LD2410Async::resetCommandSequence() {
779 if (sendCommandAsyncCommandPending || executeCommandSequencePending)
return false;
781 commandSequenceBufferCount = 0;
796bool LD2410Async::enableConfigModeInternalAsync(
bool force, AsyncCommandCallback callback) {
807 configModeOnceTicker.once_ms(1, [
this]() {
816 return enableConfigModeInternalAsync(force, callback);
819bool LD2410Async::disableConfigModeInternalAsync(
bool force, AsyncCommandCallback callback) {
830 configModeOnceTicker.once_ms(1, [
this]() {
839 return disableConfigModeInternalAsync(force, callback);
849 unsigned short noOneTimeout,
850 AsyncCommandCallback callback)
859 return sendConfigCommandAsync(cmd, callback);
887 const byte stationaryThresholds[9],
888 AsyncCommandCallback callback)
891 DEBUG_PRINTLN(
"Set Distance Gate Sensitivities (all gates)");
895 if (!resetCommandSequence())
return false;
897 for (
byte gate = 0; gate < 9; gate++) {
900 if (!addCommandToSequence(cmd))
return false;
903 return executeCommandSequenceAsync(callback);
909 byte stationaryThreshold,
910 AsyncCommandCallback callback)
920 return sendConfigCommandAsync(cmd, callback);
936 AsyncCommandCallback callback)
943 if ((baudRateSetting < 1) || (baudRateSetting > 8))
949 return sendConfigCommandAsync(cmd, callback);
996 AsyncCommandCallback callback)
1005 return sendConfigCommandAsync(cmd, callback);
1031 AsyncCommandCallback callback)
1040 return sendConfigCommandAsync(cmd, callback);
1059 AsyncCommandCallback callback)
1068 return sendConfigCommandAsync(cmd, callback);
1115 if (!resetCommandSequence())
return false;
1120 return executeCommandSequenceAsync(callback);
1131 if (!resetCommandSequence())
return false;
1137 return executeCommandSequenceAsync(callback);
1149 configureAllConfigSettingsAsyncConfigCallback =
nullptr;
1150 configureAllConfigSettingsAsyncConfigActive =
false;
1153 DEBUG_PRINT(
"configureAllConfigSettingsAsync complete. Result: ");
1165 DEBUG_PRINTLN(
"Warning: Disabling config mode after configureAllConfigSettingsAsync failed. Result: ");
1167 sender->configureAllConfigSettingsAsyncExecuteCallback(result);
1174 sender->configureAllConfigSettingsAsyncExecuteCallback(sender->configureAllConfigSettingsAsyncResultToReport);
1180 if (!configureAllConfigSettingsAsyncConfigInitialConfigMode) {
1182 DEBUG_PRINTLN(
"Config mode was not enabled initially, disable it.");
1183 configureAllConfigSettingsAsyncResultToReport = resultToReport;
1185 if (!disableConfigModeInternalAsync(configureAllConfigSettingsAsyncConfigModeDisabledCallback)) {
1187 DEBUG_PRINTLN(
"Error: Disabling config mode after configureAllConfigSettingsAsync failed.");
1193 DEBUG_PRINTLN(
"Config mode was enabled initially, no need to disable it, just execute the callback.");
1195 configureAllConfigSettingsAsyncExecuteCallback(resultToReport);
1203 DEBUG_PRINTLN(
"Error: Writing config data to sensor failed.");
1206 sender->configureAllConfigSettingsAsyncFinalize(result);
1210bool LD2410Async::configureAllConfigSettingsAsyncBuildSaveChangesCommandSequence() {
1214 if (!resetCommandSequence()) {
1220 if (configureAllConfigSettingsAsyncWriteFullConfig
1228 configureAllConfigSettingsAsyncConfigDataToWrite.
noOneTimeout)) {
1233 if (!addCommandToSequence(cmd)) {
1235 DEBUG_PRINTLN(
"Error: Adding max gate command to sequence failed.");
1242 for (
byte gate = 0; gate < 9; gate++) {
1243 if (configureAllConfigSettingsAsyncWriteFullConfig
1251 DEBUG_PRINT(
"Error: Error building gate sensitivity command for gate ");
1256 if (!addCommandToSequence(cmd)) {
1258 DEBUG_PRINT(
"Error: Adding gate sensitivity command for gate ");
1265 DEBUG_PRINT(
"Gate sensitivity command for gate ");
1272 if (configureAllConfigSettingsAsyncWriteFullConfig
1277 DEBUG_PRINTLN(
"Error: Building distance resolution command failed.");
1280 if (!addCommandToSequence(cmd)) {
1282 DEBUG_PRINTLN(
"Error: Adding distance resolution command to sequence failed.");
1286 DEBUG_PRINTLN(
"Distance resolution command added to sequence.");
1290 if (configureAllConfigSettingsAsyncWriteFullConfig
1296 configureAllConfigSettingsAsyncConfigDataToWrite.
lightControl,
1298 configureAllConfigSettingsAsyncConfigDataToWrite.
outputControl)) {
1300 DEBUG_PRINTLN(
"Error: Building aux control command failed.");
1303 if (!addCommandToSequence(cmd)) {
1305 DEBUG_PRINTLN(
"Error: Adding aux control command to sequence failed.");
1314bool LD2410Async::configureAllConfigSettingsAsyncWriteConfig() {
1316 if (!configureAllConfigSettingsAsyncBuildSaveChangesCommandSequence()) {
1319 DEBUG_PRINTLN(
"Could not build the command sequence to save the config data");
1323 if (commandSequenceBufferCount == 0) {
1325 DEBUG_PRINTLN(
"No config changes detected, no need to write anything");
1328 if (!executeCommandSequenceAsync(configureAllConfigSettingsAsyncWriteConfigCallback)) {
1330 DEBUG_PRINTLN(
"Error: Starting command sequence to write config data failed.");
1341 DEBUG_PRINTLN(
"Error: Requesting current config data failed. Result: ");
1343 sender->configureAllConfigSettingsAsyncFinalize(result);
1350 if (!sender->configureAllConfigSettingsAsyncWriteConfig()) {
1352 DEBUG_PRINTLN(
"Error: Starting to save config data changes failed.");
1357bool LD2410Async::configureAllConfigSettingsAsyncRequestAllConfigData() {
1358 if (resetCommandSequence()
1363 if (executeCommandSequenceAsync(configureAllConfigSettingsAsyncRequestAllConfigDataCallback)) {
1370 DEBUG_PRINTLN(
"Error: Starting command sequence to request current config data failed.");
1380 DEBUG_PRINTLN(
"Error: Enabling config mode failed. Result: ");
1382 sender->configureAllConfigSettingsAsyncFinalize(result);
1391 if (sender->configureAllConfigSettingsAsyncWriteFullConfig) {
1395 ret = sender->configureAllConfigSettingsAsyncWriteConfig();
1401 ret = sender->configureAllConfigSettingsAsyncRequestAllConfigData();
1405 DEBUG_PRINTLN(
"Error: Starting config data write or request of current config data failed.");
1421 if (!configToWrite.
isValid()) {
1427 configureAllConfigSettingsAsyncConfigActive =
true;
1428 configureAllConfigSettingsAsyncConfigDataToWrite = configToWrite;
1429 configureAllConfigSettingsAsyncWriteFullConfig = writeAllConfigData;
1430 configureAllConfigSettingsAsyncConfigCallback = callback;
1433 if (!configureAllConfigSettingsAsyncConfigInitialConfigMode) {
1436 return enableConfigModeInternalAsync(configureAllConfigSettingsAsyncConfigModeEnabledCallback);
1439 if (configureAllConfigSettingsAsyncWriteFullConfig) {
1442 DEBUG_PRINTLN(
"Saving all data is forced and config mode is enabled -> save directly");
1443 return configureAllConfigSettingsAsyncWriteConfig();
1447 DEBUG_PRINTLN(
"Config mode is already enabled, just request all config data");
1448 return configureAllConfigSettingsAsyncRequestAllConfigData();
1463 if (rebootAsyncPending) {
1464 rebootAsyncPending =
false;
1465 executeCommandSequenceOnceTicker.detach();
1468 executeCommandSequenceAsyncExecuteCallback(result);
1482 if (sender->rebootAsyncDontWaitForNormalOperationAfterReboot || sender->rebootAsyncWaitTimeoutMs == 0) {
1484 DEBUG_PRINTLN(
"Triggering the reboot callback directly since the parameters of the method want us not to wait until normal operation resumes.");
1485 sender->rebootAsyncFinialize(result);
1488 if (sender->rebootAsyncPending) {
1493 sender->executeCommandSequenceOnceTicker.once_ms(sender->rebootAsyncWaitTimeoutMs, [sender]() {
1495 DEBUG_PRINTLN(
"Timeout period while waiting for normal operation to resume has elapsed.");
1496 sender->rebootAsyncFinialize(LD2410Async::AsyncCommandResult::TIMEOUT);
1501 DEBUG_PRINTLN(
"It seems that reboot has already been finalized (maybe the callback from processData has already been triggered)");
1507 DEBUG_PRINT(
"Error! Could not initiate reboot. Result: ");
1509 sender->rebootAsyncFinialize(result);
1525 DEBUG_PRINTLN(
"Error! Could not enabled config mode before reboot");
1526 sender->rebootAsyncFinialize(result);
1540 executeCommandSequencePending =
true;
1541 executeCommandSequenceCallback = callback;
1543 executeCommandSequenceStartMs = millis();
1544 rebootAsyncDontWaitForNormalOperationAfterReboot = dontWaitForNormalOperationAfterReboot;
1547 rebootAsyncPending = enableConfigModeInternalAsync(
true, rebootAsyncEnableConfigModeCallback);
1549 return rebootAsyncPending;
1580#if (LD2410ASYNC_DEBUG_LEVEL > 0)
1587 DEBUG_PRINT(
"Error!! Could not initiate LD2410 reboot. Result: ");
1598#if (LD2410ASYNC_DEBUG_LEVEL > 0)
1605 DEBUG_PRINT(
"Error!! Disabling config mode after inactivity failed. Result: ");
1615void LD2410Async::handleInactivity() {
1617 if (inactivityHandlingEnabled && inactivityHandlingTimeoutMs > 0) {
1618 unsigned long timeoutToUse = inactivityHandlingTimeoutMs;
1619 if (timeoutToUse < asyncCommandTimeoutMs + 1000) {
1620 timeoutToUse = asyncCommandTimeoutMs + 1000;
1622 unsigned long currentTime = millis();
1623 unsigned long inactiveDurationMs = currentTime - lastSensorActivityTimestamp;
1624 if (lastSensorActivityTimestamp != 0 && inactiveDurationMs > timeoutToUse) {
1625 if (inactivityHandlingStep == 0 || currentTime - lastInactivityHandlingTimestamp > asyncCommandTimeoutMs + 1000) {
1626 lastInactivityHandlingTimestamp = currentTime;
1628 switch (inactivityHandlingStep++) {
1631 DEBUG_PRINTLN(
"Inactivity handling cancels pending async operations");
1636 DEBUG_PRINTLN(
"Inactivity handling tries to force disable config mode");
1638 disableConfigModeInternalAsync(
true,
nullptr);
1649 DEBUG_PRINTLN(
"Inactivity handling could not revert sensor to normal operation. Reset the inactivity timeout and try again after the configured inactivity period.");
1651 inactivityHandlingStep = 0;
1658 inactivityHandlingStep = 0;
1663void LD2410Async::heartbeat() {
1664 lastSensorActivityTimestamp = millis();
1668 inactivityHandlingEnabled = enable;
1674void LD2410Async::processReceivedData()
1676 FrameReadResponse type = readFrame();
1696void LD2410Async::taskLoop() {
1701 processReceivedData();
1702 sendCommandAsyncHandleTimeout();
1704 vTaskDelay(10 / portTICK_PERIOD_MS);
1724 if (taskHandle == NULL) {
1729 BaseType_t result = xTaskCreate(
1743 if (result == pdPASS) {
1759 if (taskHandle != NULL) {
1765 for (
int i = 0; i < 20; i++) {
1766 if (taskHandle == NULL) {
1771 vTaskDelay(1 / portTICK_PERIOD_MS);
1777 vTaskDelete(taskHandle);
String byte2hex(byte b, bool addZero=true)
bool bufferEndsWith(const byte *buffer, int iMax, const byte *pattern)
Checks whether the last 4 bytes of a buffer match the value supplied in pattern.
#define DEBUG_PRINTBUF_DATA(...)
#define DEBUG_PRINT_MILLIS
#define DEBUG_PRINTLN_DATA(...)
#define DEBUG_PRINTBUF(...)
#define DEBUG_PRINTLN(...)
Asynchronous driver class for the LD2410 human presence radar sensor.
bool configureAuxControlSettingsAsync(LD2410Types::LightControl light_control, byte light_threshold, LD2410Types::OutputControl output_control, AsyncCommandCallback callback)
Configures the auxiliary control parameters (light and output pin).
bool requestGateParametersAsync(AsyncCommandCallback callback)
Requests the current gate parameters from the sensor.
void asyncCancel()
Cancels any pending asynchronous command or sequence.
bool configureDistanceResolutionAsync(LD2410Types::DistanceResolution distanceResolution, AsyncCommandCallback callback)
Configures the distance resolution of the radar.
bool rebootAsync(AsyncCommandCallback callback)
Reboots the sensor.
LD2410Types::StaticData staticData
Static data of the radar.
bool begin()
Starts the background task that continuously reads data from the sensor.
AsyncCommandResult
Result of an asynchronous command execution.
@ TIMEOUT
No ACK received within the expected time window.
@ FAILED
Command failed (sensor responded with negative ACK).
@ SUCCESS
Command completed successfully and ACK was received.
@ CANCELED
Command was canceled by the user before completion.
bool configureMaxGateAndNoOneTimeoutAsync(byte maxMovingGate, byte maxStationaryGate, unsigned short noOneTimeout, AsyncCommandCallback callback)
Configures the maximum detection gates and "no-one" timeout on the sensor.
bool requestAllStaticDataAsync(AsyncCommandCallback callback)
Requests all static information from the sensor.
bool restoreFactorySettingsAsync(AsyncCommandCallback callback)
Restores factory settings of the sensor.
bool disableConfigModeAsync(AsyncCommandCallback callback)
Disables config mode on the radar.
bool isConfigModeEnabled() const
Detects if config mode is enabled.
void(*) AsyncCommandCallback(LD2410Async *sender, AsyncCommandResult result)
Callback signature for asynchronous command completion.
bool configureAllConfigSettingsAsync(const LD2410Types::ConfigData &configToWrite, bool writeAllConfigData, AsyncCommandCallback callback)
Applies a full ConfigData struct to the LD2410.
bool enableConfigModeAsync(AsyncCommandCallback callback)
Enables config mode on the radar.
bool disableBluetoothAsync(AsyncCommandCallback callback)
Disables Bluetooth.
void setInactivityHandling(bool enable)
Enables or disables automatic inactivity handling of the sensor.
void onConfigDataReceived(GenericCallback callback)
Registers a callback for configuration data updates.
LD2410Types::ConfigData getConfigData() const
Returns a clone of the current configuration data of the radar.
LD2410Types::DetectionData getDetectionData() const
Returns a clone of the latest detection data from the radar.
bool configureDistanceResolution75cmAsync(AsyncCommandCallback callback)
Configures the distance resolution explicitly to 75 cm per gate.
LD2410Types::ConfigData configData
Current configuration parameters of the radar.
bool requestDistanceResolutionAsync(AsyncCommandCallback callback)
Requests the current distance resolution setting from the sensor.
bool asyncIsBusy()
Checks if an asynchronous command is currently pending.
bool configModeEnabled
True if the sensor is currently in config mode.
bool configureBluetoothPasswordAsync(const char *password, AsyncCommandCallback callback)
Sets the password for Bluetooth access to the sensor.
void onConfigChanged(GenericCallback callback)
Registers a callback that is invoked whenever the sensor's configuration has been changed successfull...
bool requestFirmwareAsync(AsyncCommandCallback callback)
Requests the firmware version of the sensor.
bool requestBluetoothMacAddressAsync(AsyncCommandCallback callback)
Requests the Bluetooth MAC address.
LD2410Types::DetectionData detectionData
Latest detection results from the radar.
LD2410Types::AutoConfigStatus autoConfigStatus
Current status of the auto-configuration routine.
bool requestAllConfigSettingsAsync(AsyncCommandCallback callback)
Requests all configuration settings from the sensor.
bool engineeringModeEnabled
True if the sensor is currently in engineering mode.
bool configureDefaultBluetoothPasswordAsync(AsyncCommandCallback callback)
Resets the password for Bluetooth access to the default value (HiLink)
bool configureDistanceGateSensitivityAsync(const byte movingThresholds[9], const byte stationaryThresholds[9], AsyncCommandCallback callback)
Configures sensitivity thresholds for all gates at once.
LD2410Async(Stream &serial)
Constructs a new LD2410Async instance bound to a given serial stream.
bool beginAutoConfigAsync(AsyncCommandCallback callback)
Starts the automatic configuration (auto-config) routine on the sensor.
bool requestAuxControlSettingsAsync(AsyncCommandCallback callback)
Requests the current auxiliary control settings.
void onDetectionDataReceived(DetectionDataCallback callback)
Registers a callback for new detection data.
bool enableEngineeringModeAsync(AsyncCommandCallback callback)
Enables engineering mode.
bool disableEngineeringModeAsync(AsyncCommandCallback callback)
Disables engineering mode.
bool configureBaudRateAsync(byte baudRateSetting, AsyncCommandCallback callback)
Configures the UART baud rate of the sensor.
bool requestAutoConfigStatusAsync(AsyncCommandCallback callback)
Requests the current status of the auto-config routine.
bool end()
Stops the background task started by begin().
bool configuresDistanceResolution20cmAsync(AsyncCommandCallback callback)
Configures the distance resolution explicitly to 20 cm per gate.
bool enableBluetoothAsync(AsyncCommandCallback callback)
Enables Bluetooth.
bool buildMaxGateCommand(byte *out, byte maxMotionGate, byte maxStationaryGate, unsigned short noOneTimeout)
bool buildDistanceResolutionCommand(byte *out, LD2410Types::DistanceResolution resolution)
bool buildAuxControlCommand(byte *out, LD2410Types::LightControl lightControl, byte lightThreshold, LD2410Types::OutputControl outputControl)
bool buildGateSensitivityCommand(byte *out, byte gate, byte movingThreshold, byte stationaryThreshold)
bool buildBluetoothPasswordCommand(byte *out, const char *password)
bool buildBaudRateCommand(byte *out, byte baudRateSetting)
constexpr byte requestAutoConfigStatusCommandData[4]
constexpr byte setAuxControlSettingCommandData[8]
constexpr byte configDisableCommand
constexpr byte requestDistanceResolutionCommandData[4]
constexpr byte setDistanceResolutionCommand
constexpr byte configEnableCommandData[6]
constexpr byte engineeringModeDisableComand
constexpr byte requestMacAddressCommandData[6]
constexpr byte setAuxControlSettingsCommand
constexpr byte distanceGateSensitivityConfigCommand
constexpr byte bluetoothSettingsCommand
constexpr byte restoreFactorSettingsCommandData[4]
constexpr byte requestAuxControlSettingsCommandData[4]
constexpr byte distanceGateSensitivityConfigCommandData[0x16]
constexpr byte setBluetoothPasswordCommandData[10]
constexpr byte setDistanceResolution20cmCommandData[6]
constexpr byte maxGateCommandData[0x16]
constexpr byte setBaudRateCommand
constexpr byte tailConfig[4]
constexpr byte headConfig[4]
constexpr byte setBluetoothPasswordCommand
constexpr byte requestAutoConfigStatusCommand
constexpr byte engineeringModeDisableCommandData[4]
constexpr byte rebootCommandData[4]
constexpr byte requestAuxControlSettingsCommand
constexpr byte setBaudRateCommandData[6]
constexpr byte restoreFactorySettingsAsyncCommand
constexpr byte bluetoothSettingsOnCommandData[6]
constexpr byte requestParamsCommand
constexpr byte requestMacAddressCommand
constexpr byte headData[4]
constexpr byte setDistanceResolution75cmCommandData[6]
constexpr byte rebootCommand
constexpr byte requestFirmwareCommand
constexpr byte beginAutoConfigCommandData[6]
constexpr size_t LD2410_Buffer_Size
constexpr byte maxGateCommand
constexpr byte beginAutoConfigCommand
constexpr byte configDisableCommandData[4]
constexpr byte getBluetoothPermissionsCommand
constexpr byte configEnableCommand
constexpr byte tailData[4]
constexpr byte requestFirmwareCommandData[4]
constexpr byte engineeringModeEnableCommandData[4]
constexpr byte engineeringModeEnableComand
constexpr byte requestDistanceResolutionCommand
constexpr byte requestParamsCommandData[4]
OutputControl
Logic level behavior of the auxiliary output pin.
DistanceResolution
Distance resolution per gate for detection.
@ MOVING_AND_STATIONARY_TARGET
Both moving and stationary targets detected.
@ STATIONARY_TARGET
A stationary target has been detected.
@ MOVING_TARGET
A moving target has been detected.
LightControl
Light-dependent control status of the auxiliary output.
byte distanceGateStationarySensitivity[9]
Stationary sensitivity values per gate (0-100).
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.
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.
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.