upgrades and fixes for HLK-LD2402 driver (#23164)

Co-authored-by: Anthony Sepa <protectivedad@gmail.com>
This commit is contained in:
protectivedad 2025-03-22 06:28:15 -03:00 committed by GitHub
parent ddc1439edf
commit 38ceafe789
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -23,7 +23,6 @@
*/ */
#ifdef USE_LD2402 #ifdef USE_LD2402
/*********************************************************************************************\ /*********************************************************************************************\
* HLK-LD2402 24GHz smart wave motion sensor * HLK-LD2402 24GHz smart wave motion sensor
* *
@ -37,6 +36,7 @@
* LD2402_SetMotion n,n1..n16 - set motion threshold values (16) * LD2402_SetMotion n,n1..n16 - set motion threshold values (16)
* LD2402_SetMicro n,n1..n16 - set micro threshold values (16) * LD2402_SetMicro n,n1..n16 - set micro threshold values (16)
* LD2402_Mode 0/1 - set device output mode 0-normal, 1-engineering * LD2402_Mode 0/1 - set device output mode 0-normal, 1-engineering
* LD2402_Save - save the internal device motion/micro thresholds
* LD2402_AutoUpdate 3.0,2.0,3.0 - start autoupdate trigger,keep,micro magnification factor * LD2402_AutoUpdate 3.0,2.0,3.0 - start autoupdate trigger,keep,micro magnification factor
* LD2402_Follow 0/n - reports every n seconds * LD2402_Follow 0/n - reports every n seconds
* *
@ -367,13 +367,19 @@ void Ld2402SendCommand(uint8_t command, uint32_t val_len = 0);
void Ld2402SendCommand(uint8_t command, uint32_t val_len) { void Ld2402SendCommand(uint8_t command, uint32_t val_len) {
uint8_t buffer[20] = LD2402_config_header_a; uint8_t buffer[20] = LD2402_config_header_a;
buffer[4] = val_len + 2;
buffer[6] = command;
if (val_len) { if (val_len) {
memcpy(buffer+8,LD2402.cmnd_param,val_len); memcpy(buffer+8,LD2402.cmnd_param,val_len);
} else if (LD2402_CMND_START_CONFIGURATION == command) {
const uint8_t start_cmnd[2] = {0x01, 0x00};
memcpy(buffer+8, start_cmnd, 2);
val_len = 2;
} }
buffer[4] = val_len + 2;
buffer[6] = command;
memcpy(buffer+8+val_len, LD2402_config_footer_a, sizeof(LD2402_config_footer_a)); memcpy(buffer+8+val_len, LD2402_config_footer_a, sizeof(LD2402_config_footer_a));
DEBUG_SENSOR_LOG(PSTR(D_LD2402_LOG_PREFIX "Send %*_H"), val_len + 12, buffer);
LD2402.sent_ack = command; LD2402.sent_ack = command;
LD2402Serial->setReadChunkMode(1); // Enable chunk mode introducing possible Hardware Watchdogs LD2402Serial->setReadChunkMode(1); // Enable chunk mode introducing possible Hardware Watchdogs
LD2402Serial->flush(); LD2402Serial->flush();
@ -421,11 +427,11 @@ void Ld2402WriteThresholds(uint8_t *thresholds, uint32_t cmnd_param) {
} }
char strbuf[24]; char strbuf[24];
float param; float param;
uint32_t i = 0; uint32_t i = 0, val;
for (uint32_t j = 0; j < LD2402_NUM_GATES; j++) { for (uint32_t j = 0; j < LD2402_NUM_GATES; j++) {
ArgV(strbuf, j+1); ArgV(strbuf, j+1);
param = CharToFloat(strbuf); param = CharToFloat(strbuf) / 10.0f;
uint32_t val = exp10(param > 95.00f ? 95.00f : param); val = exp10(param > 9.5f ? 9.5f : param);
thresholds[i++] = val & 0x000000FF; thresholds[i++] = val & 0x000000FF;
thresholds[i++] = val >> 8 & 0x000000FF; thresholds[i++] = val >> 8 & 0x000000FF;
thresholds[i++] = val >> 16 & 0x000000FF; thresholds[i++] = val >> 16 & 0x000000FF;
@ -450,9 +456,9 @@ void Ld2402ResponseAppendGates(uint8_t *energies) {
void Ld2402ResponseAppendReport() { void Ld2402ResponseAppendReport() {
if (3 == LD2402.report_type) { if (3 == LD2402.report_type) {
ResponseAppend_P(PSTR("\"AutoUpdate\":\"%1d%%\"}"), LD2402.auto_upd_progress); ResponseAppend_P(PSTR("\"AutoUpdate\":\"%1d%%\""), LD2402.auto_upd_progress);
} else if (0 == LD2402.report_type) { } else if (0 == LD2402.report_type) {
ResponseAppend_P(PSTR("\"Error\":\"Disconnected\"}")); ResponseAppend_P(PSTR("\"Error\":\"Disconnected\""));
} else { } else {
ResponseAppend_P(PSTR("\"" D_JSON_DISTANCE "\":%d"), LD2402.detect_distance); ResponseAppend_P(PSTR("\"" D_JSON_DISTANCE "\":%d"), LD2402.detect_distance);
if (1 == LD2402.report_type) { if (1 == LD2402.report_type) {
@ -464,7 +470,7 @@ void Ld2402ResponseAppendReport() {
Ld2402ResponseAppendGates(LD2402.motion_energy); Ld2402ResponseAppendGates(LD2402.motion_energy);
ResponseAppend_P(PSTR("],\"MicroEnergies\":[")); ResponseAppend_P(PSTR("],\"MicroEnergies\":["));
Ld2402ResponseAppendGates(LD2402.micro_energy); Ld2402ResponseAppendGates(LD2402.micro_energy);
ResponseAppend_P(PSTR("]}")); ResponseAppend_P(PSTR("]"));
} }
} }
} }
@ -497,6 +503,7 @@ void Ld2402OnDemand(uint32_t ack_rcvd) {
return; return;
case LD2402_CMND_SAVE_PARAM>>4: case LD2402_CMND_SAVE_PARAM>>4:
LD2402.step = LD2402_CMND_END_CONFIGURATION;
return; return;
case LD2402_CMND_AUTO_THRESHOLD>>4: case LD2402_CMND_AUTO_THRESHOLD>>4:
@ -575,6 +582,7 @@ void Ld2402OnDemand(uint32_t ack_rcvd) {
LD2402.cmnd_param[0] = LD2402_CMND_PARAM_MOTION_START; LD2402.cmnd_param[0] = LD2402_CMND_PARAM_MOTION_START;
if (2 == LD2402.pwr_interf) { if (2 == LD2402.pwr_interf) {
LD2402.step = LD2402_CMND_AUTO_INTERFERENCE; LD2402.step = LD2402_CMND_AUTO_INTERFERENCE;
return;
} }
break; break;
@ -583,15 +591,7 @@ void Ld2402OnDemand(uint32_t ack_rcvd) {
break; break;
case LD2402_CMND_PARAM_MICRO_END: case LD2402_CMND_PARAM_MICRO_END:
if (LD2402.initializing) { LD2402.step = LD2402_CMND_END_CONFIGURATION;
// clear LD2402_CMND_READ_PARAM param
LD2402.cmnd_param[0] = 0x00;
LD2402.cmnd_param[2] = 0x04;
LD2402.step = LD2402_CMND_MODE;
Ld2402EveryXMSecond();
} else {
LD2402.step = LD2402_CMND_END_CONFIGURATION;
}
return; return;
default: default:
@ -626,8 +626,7 @@ void Ld2402EveryXMSecond(void) {
break; break;
case LD2402_CMND_START_CONFIGURATION: case LD2402_CMND_START_CONFIGURATION:
LD2402.cmnd_param[0] = 0x01; Ld2402SendCommand(command);
Ld2402SendCommand(command, 2);
if (LD2402.initializing) { if (LD2402.initializing) {
LD2402.step = LD2402_CMND_START_CONFIGURATION+CMD_LD2402_BOOT_DELAY; LD2402.step = LD2402_CMND_START_CONFIGURATION+CMD_LD2402_BOOT_DELAY;
return; return;
@ -715,18 +714,19 @@ void Ld2402Detect(void) {
#define D_CMD_SETCOMMON "SetCommon" #define D_CMD_SETCOMMON "SetCommon"
#define D_CMD_SETMOTION "SetMotion" #define D_CMD_SETMOTION "SetMotion"
#define D_CMD_SETMICRO "SetMicro" #define D_CMD_SETMICRO "SetMicro"
#define D_CMD_SAVE "Save"
#define D_CMD_HELP "Help" #define D_CMD_HELP "Help"
#define D_CMD_REREAD "ReRead" #define D_CMD_REREAD "ReRead"
#define D_CMD_FOLLOW "Follow" #define D_CMD_FOLLOW "Follow"
const char kLd2402Commands[] PROGMEM = D_LD2402 "_|" // Prefix const char kLd2402Commands[] PROGMEM = D_LD2402 "_|" // Prefix
D_CMD_MODE "|" D_CMD_AUTOUPDATE "|" D_CMD_STATUS "|" D_CMD_SETCOMMON "|" D_CMD_MODE "|" D_CMD_AUTOUPDATE "|" D_CMD_STATUS "|" D_CMD_SETCOMMON "|"
D_CMD_SETMOTION "|" D_CMD_SETMICRO "|" D_CMD_HELP "|" D_CMD_REREAD "|" D_CMD_SETMOTION "|" D_CMD_SETMICRO "|" D_CMD_SAVE "|" D_CMD_HELP "|" D_CMD_REREAD "|"
D_CMD_FOLLOW; D_CMD_FOLLOW;
void (* const Ld2402Command[])(void) PROGMEM = { void (* const Ld2402Command[])(void) PROGMEM = {
&CmndLd2402Mode, &CmndLd2402AutoUpdate, &CmndLd2402Status, &CmndLd2402Common, &CmndLd2402Mode, &CmndLd2402AutoUpdate, &CmndLd2402Status, &CmndLd2402Common,
&CmndLd2402Motion, &CmndLd2402Micro, &CmndLd2402Help, &CmndLd2402ReRead, &CmndLd2402Motion, &CmndLd2402Micro, &CmndLd2402Save, &CmndLd2402Help, &CmndLd2402ReRead,
&CmndLd2402Follow }; &CmndLd2402Follow };
void CmndLd2402Help(void) { void CmndLd2402Help(void) {
@ -737,6 +737,7 @@ void CmndLd2402Help(void) {
ResponseAppend_P(PSTR(D_LD2402 "_" D_CMD_SETCOMMON", ")); ResponseAppend_P(PSTR(D_LD2402 "_" D_CMD_SETCOMMON", "));
ResponseAppend_P(PSTR(D_LD2402 "_" D_CMD_SETMOTION", ")); ResponseAppend_P(PSTR(D_LD2402 "_" D_CMD_SETMOTION", "));
ResponseAppend_P(PSTR(D_LD2402 "_" D_CMD_SETMICRO", ")); ResponseAppend_P(PSTR(D_LD2402 "_" D_CMD_SETMICRO", "));
ResponseAppend_P(PSTR(D_LD2402 "_" D_CMD_SAVE", "));
ResponseAppend_P(PSTR(D_LD2402 "_" D_CMD_HELP", ")); ResponseAppend_P(PSTR(D_LD2402 "_" D_CMD_HELP", "));
ResponseAppend_P(PSTR(D_LD2402 "_" D_CMD_REREAD", ")); ResponseAppend_P(PSTR(D_LD2402 "_" D_CMD_REREAD", "));
ResponseAppend_P(PSTR(D_LD2402 "_" D_CMD_FOLLOW"\"}")); ResponseAppend_P(PSTR(D_LD2402 "_" D_CMD_FOLLOW"\"}"));
@ -770,17 +771,20 @@ void CmndLd2402Status(void) {
if (1 == status_type) { if (1 == status_type) {
ResponseAppend_P(PSTR("SNS\":{")); ResponseAppend_P(PSTR("SNS\":{"));
Ld2402ResponseAppendReport(); Ld2402ResponseAppendReport();
ResponseJsonEnd();
} else if (2 == status_type) { } else if (2 == status_type) {
ResponseAppend_P(PSTR("FWR\":{\"Version\":\"%s\","),LD2402.version); ResponseAppend_P(PSTR("FWR\":{\"Version\":\"%s\","),LD2402.version);
ResponseAppend_P(PSTR("\"SerialNumber\":\"%s\"}}"),LD2402.serial_number); ResponseAppend_P(PSTR("\"SerialNumber\":\"%s\"}"),LD2402.serial_number);
} else { } else {
ResponseAppend_P(PSTR("\":{\"MaximumDistance\":%d,"), LD2402.max_distance); ResponseAppend_P(PSTR("\":{\"MaximumDistance\":%d,"), LD2402.max_distance);
ResponseAppend_P(PSTR("\"DisappearenceDelay\":%d,"), LD2402.disp_delay); ResponseAppend_P(PSTR("\"DisappearenceDelay\":%d,"), LD2402.disp_delay);
ResponseAppend_P(PSTR("\"MotionThresholds\":[")); ResponseAppend_P(PSTR("\"MotionThresholds\":["));
Ld2402ResponseAppendGates(LD2402.motion_threshold); Ld2402ResponseAppendGates(LD2402.motion_threshold);
ResponseAppend_P(PSTR("],\"MicroThresholds\":["));
Ld2402ResponseAppendGates(LD2402.micro_threshold); Ld2402ResponseAppendGates(LD2402.micro_threshold);
ResponseAppend_P(PSTR("]}}")); ResponseAppend_P(PSTR("]}"));
} }
ResponseJsonEnd();
} }
void CmndLd2402ReRead(void) { void CmndLd2402ReRead(void) {
@ -832,7 +836,7 @@ void CmndLd2402Mode(void) {
ArgV(Argument,1); ArgV(Argument,1);
memset(LD2402.cmnd_param, 0x00, 6); memset(LD2402.cmnd_param, 0x00, 6);
LD2402.cmnd_param[2] = atoi(Argument) ? 0x04 : 0x64; LD2402.cmnd_param[2] = atoi(Argument) ? 0x04 : 0x64;
Response_P(PSTR(D_COMMAND_PREFIX_JSON"%d}"), D_CMD_FOLLOW, (0x04 == LD2402.cmnd_param[2])); Response_P(PSTR(D_COMMAND_PREFIX_JSON "%d}"), D_CMD_MODE, (0x04 == LD2402.cmnd_param[2]));
Ld2402ExecConfigCmnd(LD2402_CMND_MODE); Ld2402ExecConfigCmnd(LD2402_CMND_MODE);
} }
@ -853,7 +857,20 @@ void CmndLd2402AutoUpdate(void) {
LD2402.cmnd_param[(i-1)*2] = (param < 1.0f) ? 10.0f : (param > 20.0f ? 200.0f : param * 10.0f); LD2402.cmnd_param[(i-1)*2] = (param < 1.0f) ? 10.0f : (param > 20.0f ? 200.0f : param * 10.0f);
} }
Ld2402ExecConfigCmnd(LD2402_CMND_AUTO_THRESHOLD); Ld2402ExecConfigCmnd(LD2402_CMND_AUTO_THRESHOLD);
Response_P(PSTR(D_COMMAND_HELP_MSG), D_CMD_REREAD, "Updating ..."); Response_P(PSTR(D_COMMAND_HELP_MSG), D_CMD_AUTOUPDATE, "Updating ...");
}
void CmndLd2402Save(void) {
if (LD2402.busy) {
Response_P(PSTR(D_BUSY_MSG));
return;
}
if (ArgC()) {
Response_P(PSTR(D_COMMAND_HELP_MSG), D_CMD_SAVE, "No Args: Saves configuration parameters in case of power failure (v3.3.2 and above)");
return;
}
Ld2402ExecConfigCmnd(LD2402_CMND_SAVE_PARAM);
Response_P(PSTR(D_COMMAND_HELP_MSG), D_CMD_SAVE, "Saving ...");
} }
void CmndLd2402Motion(void) { void CmndLd2402Motion(void) {
@ -894,6 +911,7 @@ void Ld2402Web(void) {
void Ld2402Show(void) { void Ld2402Show(void) {
ResponseAppend_P(PSTR(",\"" D_LD2402 "\":{")); ResponseAppend_P(PSTR(",\"" D_LD2402 "\":{"));
Ld2402ResponseAppendReport(); Ld2402ResponseAppendReport();
ResponseJsonEnd();
} }
/*********************************************************************************************\ /*********************************************************************************************\