无法正确读取来自 Cygbot LIDAR 的数据包

Can't read packets from Cygbot LIDAR properly

我试图让 MCU 通过 UART 从 LIDAR 读取数据,但出于某种原因,校验和不正确。我正在使用 ESP32-WROOM 开发芯片(使用 Arduino)和带有此 datasheet 的 Cygbot D1 LIDAR。我能够读取 2D 数据包,但不能读取更长的 3D 数据包。

收到数据包后,我使用一系列 Serial.read() 调用逐字节读取数据。正确读取包头、包长度字节和有效负载头。负载长度为 14,401 字节。

当我完成读取数据时,校验和不匹配,串行缓冲区中还剩下大约 300 个字节。经过大量调试后,我卡住了,非常感谢任何关于如何摆脱卡住的指示或想法。

我的代码的相关部分:

bool readPacket() {
  /*
   * Call when we're expecting a packet. The top of the buffer
   * must be the correct packet header. 
   */
  if (Serial2.available()) {
    //Check the header, return false if it's wrong
    if (not checkHeader()) {
      return false;
    }
    
    //Next 2 bytes are the packet length
    byte b0 = Serial2.read();
    byte b1 = Serial2.read();
    unsigned int payloadLen = combineBytesIntoInt(b0, b1);

    //Read in the data based on the payload header. 
    byte payloadHeader = Serial2.read();
    
    byte sum = b0 ^ b1 ^ payloadHeader; //Start computing checksum
    if (payloadHeader == 0x08) {
      sum ^= parse3D();
    }

    byte packetChecksum = Serial2.read();
    
    if (packetChecksum != sum) {
      Serial.println("Checksum error");
      return false;
    }
    return true;
  } else {
    return false;
  }
}

byte parse3D() {
  /*
   * Parse a 3D dataset, reading directly from the serial. 
   * Reading in batches of 3 due to the way data is formatted in the packet.
   * Returns checksum. 
   */
  byte checksum = 0;
  for (int i=0; i<N_MEASURES_3D; i+=2) {
    int msb0 = -1; 
    //If data hasn't been sent, Serial2.read will return -1. Wait until we receive valid data before proceeding.
    while (msb0 < 0) {
      msb0 = Serial2.read();
    }
    int split = -1;
    while (split < 0) {
      split = Serial2.read();
    }
    int lsb1 = -1;
    while (lsb1 < 0) {
      lsb1 = Serial2.read();
    }
    
    checksum ^= byte(msb0) ^ byte(split) ^ byte(lsb1);
  }
  return checksum
}

void loop() {
  //When the button is clicked, send a packet. 
  if (buttonState == 1) {    
    ct += 1;
    if (ct % 2 == 0) {
      Serial.println("Write packet: start 3d");
      lidarStart3DMode();
    }
  }
  
  bool readSuccess = readPacket();
  if (readSuccess) {
    lidarStop();
  }

  //This code just updates the button  
  if ((digitalRead(BUTTON_PIN) == 1) and (millis() - lastTime > BUTTON_DEBOUNCE_TIME)) {
      lastTime = millis();
      buttonState = 1;
  } else {
    buttonState = 0;
  }
}


此处代码中的所有内容:

byte b0 = Serial2.read();
byte b1 = Serial2.read();
unsigned int payloadLen = combineBytesIntoInt(b0, b1);

//Read in the data based on the payload header. 
byte payloadHeader = Serial2.read();

这里

byte packetChecksum = Serial2.read();

并且可能在 checkHeader() 中(您没有提供),应该是 safe-guarded 对缓冲区 under-run,即。当 none 可用时读取字节。

您可以添加

while (!Serial.available());

在每个 read().

之前