无法正确读取来自 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()
.
之前
我试图让 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()
.