Home Assistant Smart Home (LD2451 Rear Vehicle Detection)

Introduction: The LD2451 radar module supports rear vehicle detection with LED light prompts (who drives without playing music? So playing prompts is somewhat redundant; it’s better to use light prompts directly). It can only be used as an auxiliary; good driving skills still require frequent checking of the rearview mirror.Wiring Diagram:Home Assistant Smart Home (LD2451 Rear Vehicle Detection)

//#include <SoftwareSerial.h>// Source code from Bilibili, modified based on it#include <HardwareSerial.h>#include <HLK_LD2451.h>// Radar serial port configuration (RX=4, TX=5)#define RXD2 4#define TXD2 5HardwareSerial radarSerial(2);  // RX=D2(4), TX=D1(5)// Radar protocol constantsconst uint8_t DATA_HEADER[4] = {0xF4, 0xF3, 0xF2, 0xF1};const uint8_t DATA_FOOTER[4] = {0xF8, 0xF7, 0xF6, 0xF5};// Pin definitionsconst int LEFT_PIN = 10;    // Left side vehicle control pin (active low)const int RIGHT_PIN = 11;   // Right side vehicle control pin (active low)// State machine variablesenum ParserState {  WAITING_HEADER,  READING_LENGTH,  READING_DATA,  READING_FOOTER};ParserState state = WAITING_HEADER;uint8_t headerIndex = 0;uint16_t dataLength = 0;uint16_t dataIndex = 0;uint8_t packetBuffer[128];  // Data buffer// Vehicle detection status flagsbool hasVehicleDetected = false;bool leftVehicleDetected = false;   // Left side vehicle flagbool rightVehicleDetected = false;  // Right side vehicle flag// Last print timestamp (for controlling output frequency)unsigned long lastPrintTime = 0;// Print interval (milliseconds)const unsigned long PRINT_INTERVAL = 2000;  // Print every 2 secondsvoid setup() {  // Initialize serial port  Serial.begin(115200);      // Debug serial  radarSerial.begin(115200, SERIAL_8N1, RXD2, TXD2); // Radar default baud rate  // Initialize control pins  pinMode(LEFT_PIN, OUTPUT);  pinMode(RIGHT_PIN, OUTPUT);  delay(1000);  Serial.println("LD2451 Vehicle Detection System Started");  // Set initial state to high (off)  digitalWrite(LEFT_PIN, HIGH);  digitalWrite(RIGHT_PIN, HIGH);  // Send radar configuration command  sendConfigCommand();}void loop() {  // Process radar data  while (radarSerial.available()) {    processRadarData(radarSerial.read());  }  // Check if no vehicle detected and print in a loop  unsigned long currentTime = millis();  if (!hasVehicleDetected && currentTime - lastPrintTime >= PRINT_INTERVAL) {    Serial.println("NO Car");  //  Serial.println("未检测到车辆");    // Keep high (off) when no vehicle detected    digitalWrite(LEFT_PIN, LOW);    digitalWrite(RIGHT_PIN, LOW);    lastPrintTime = currentTime;  } else {    // Control pins based on left and right detection status (active low)    if (leftVehicleDetected && rightVehicleDetected) {      // Both sides have vehicles approaching      digitalWrite(LEFT_PIN, HIGH);      digitalWrite(RIGHT_PIN, HIGH);    } else if (leftVehicleDetected) {      // Only left side vehicle      digitalWrite(LEFT_PIN, HIGH);      digitalWrite(RIGHT_PIN, LOW);    } else if (rightVehicleDetected) {      // Only right side vehicle      digitalWrite(RIGHT_PIN, HIGH);      digitalWrite(LEFT_PIN, LOW);    }  }  // Reset detection flags at the end of each loop  hasVehicleDetected = false;  leftVehicleDetected = false;  rightVehicleDetected = false;}// Send radar configuration commandvoid sendConfigCommand() {  // Enable configuration command  uint8_t enableCmd[] = {0xFD, 0xFC, 0xFB, 0xFA, 0x04, 0x00,                          0xFF, 0x00, 0x01, 0x00,                          0x04, 0x03, 0x02, 0x01};  radarSerial.write(enableCmd, sizeof(enableCmd));  delay(50);  // Target detection parameter configuration (100m distance, only detect approaching, 1km/h minimum speed, 2s delay)  uint8_t configCmd[] = {0xFD, 0xFC, 0xFB, 0xFA, 0x06, 0x00,                         0x02, 0x00, 0x64, 0x02, 0x01, 0x02,                         //0x64,        0x02,      0x01,       0x02                         //100m distance, near and far detection, 1km/h minimum speed, 2s delay                         0x04, 0x03, 0x02, 0x01};  radarSerial.write(configCmd, sizeof(configCmd));  delay(50);  // End configuration command  uint8_t endCmd[] = {0xFD, 0xFC, 0xFB, 0xFA, 0x02, 0x00,                      0xFE, 0x00, 0x04, 0x03, 0x02, 0x01};  radarSerial.write(endCmd, sizeof(endCmd));  Serial.println("Radar Configuration Applied");}// Radar data processing state machinevoid processRadarData(uint8_t byte) {  switch (state) {    case WAITING_HEADER:      if (byte == DATA_HEADER[headerIndex]) {        headerIndex++;        if (headerIndex == 4) {          state = READING_LENGTH;          dataIndex = 0;        }      } else {        headerIndex = 0;      }      break;    case READING_LENGTH:      packetBuffer[dataIndex++] = byte;      if (dataIndex == 2) {        dataLength = (packetBuffer[1] << 8) | packetBuffer[0]; // Little-endian format        dataIndex = 0;        if (dataLength > 0 && dataLength < sizeof(packetBuffer)) {          state = READING_DATA;        } else {          state = WAITING_HEADER;        }      }      break;    case READING_DATA:      packetBuffer[dataIndex++] = byte;      if (dataIndex >= dataLength) {        state = READING_FOOTER;        headerIndex = 0;      }      break;    case READING_FOOTER:      if (byte == DATA_FOOTER[headerIndex]) {        headerIndex++;        if (headerIndex == 4) {          parseTargetData();          state = WAITING_HEADER;          headerIndex = 0;        }      } else {        state = WAITING_HEADER;        headerIndex = 0;      }      break;  }}// Parse target datavoid parseTargetData() {  if (dataLength < 2) return;  uint8_t targetCount = packetBuffer[0];  uint8_t alarmInfo = packetBuffer[1];  // Reset left and right detection status  leftVehicleDetected = false;  rightVehicleDetected = false;  // Check for valid targets  if (targetCount == 0 || dataLength < 2 + targetCount * 5) {    return;  }  // Process each target  for (int i = 0; i < targetCount; i++) {    int offset = 2 + i * 5;    // Parse target parameters    int8_t angle = packetBuffer[offset] - 0x80;  // Angle conversion    uint8_t distance = packetBuffer[offset + 1]; // Distance (meters)    uint8_t dir = packetBuffer[offset + 2];      // Direction (0x01=approaching)    uint8_t speed = packetBuffer[offset + 3];    // Speed (km/h)    uint8_t snr = packetBuffer[offset + 4];      // Signal-to-noise ratio    // Filtering conditions: approaching + valid speed + excluding directly behind ±5°    if (dir == 0x01 && speed >= 1 && abs(angle) > 5) {      // Fix direction judgment logic (angle>0 corresponds to right side, angle<=0 corresponds to left side)      //String direction = (angle > 0) ? "右侧" : "左侧";      String direction = (angle > 0) ? "Right" : "Left";       // Serial output results      Serial.print(direction + " Car is coming, ");      Serial.print("Speed:" + String(speed) + "km/h, ");      Serial.print("Distance:" + String(distance) + "m, ");      Serial.print("Angle:" + String(angle) + "°");      //Serial.print(direction + "来车, ");      //Serial.print("速度:" + String(speed) + "km/h, ");      //Serial.print("距离:" + String(distance) + "m, ");      //Serial.print("角度:" + String(angle) + "°");      Serial.println();      // Update flag when vehicle detected      hasVehicleDetected = true;      // Update left and right detection status      if (direction == "Left") {      //if (direction == "左侧") {        leftVehicleDetected = true;      } else {        rightVehicleDetected = true;      }    }  }}

Leave a Comment