Test to connect LD19 to Arduino Mega (solved)

Hello everyone,
I am trying to connect an LD19 Lidar with arduino. Following the record trace I understand that the record header consists of 0x54+0x2c.
I have done many tests to try to get the record in the correct format but without success.
The sequence 0x54+0x2c. is rarely detected even when reading the bytes one at a time or inserting pauses or buffers.

One version of the tests done is this:

#define BUFFER_SIZE 70  // Double the size of the packet to handle partial buffer

const byte HEADER = 0x54;
const byte VER_LEN = 0x2C;
const int POINTS_PER_PACK = 12;
const int PACKET_LENGTH = 35;  // Length of a packet

struct LidarPoint {
  uint8_t distance;
  uint8_t intensity;
};

struct LiDARFrame {
  uint8_t header;
  uint8_t ver_len;
  uint16_t speed;         // 2 bytes
  uint16_t start_angle;   // 2 bytes
  LidarPoint points[POINTS_PER_PACK];
  uint16_t end_angle;     // 2 bytes
  uint16_t timestamp;     // 2 bytes
  uint8_t crc8;
};

char buffer[BUFFER_SIZE];
int bufferIndex = 0;

void setup() {
  Serial2.begin(240300);  // Initialize Serial2 at 240300 baud
  Serial.begin(115200);     // Initialize USB serial for debugging
  Serial.println("Initialization completed");
}

void loop() {
  while (Serial2.available() > 0) {
    int receivedByte = Serial2.read();
    if (receivedByte != -1) {
      // Add the byte to the buffer if there is space
      if (bufferIndex < BUFFER_SIZE) {
        buffer[bufferIndex++] = (char)receivedByte;
      } else {
        // If the buffer is full, shift the data to make space
        memmove(buffer, buffer + 1, BUFFER_SIZE - 1);
        buffer[BUFFER_SIZE - 1] = (char)receivedByte;
      }

      // Search for the header and ver_len byte in the buffer
      if (bufferIndex >= 2 && buffer[bufferIndex - 2] == HEADER && buffer[bufferIndex - 1] == VER_LEN) {
        // If found, read the complete packet
        if (bufferIndex >= PACKET_LENGTH) {
          LiDARFrame frame;
          memcpy(&frame, buffer + bufferIndex - PACKET_LENGTH, PACKET_LENGTH);
          
          // Print packet data
          Serial.print("Speed: ");
          Serial.println(frame.speed);
          Serial.print("Start Angle: ");
          Serial.println(frame.start_angle);
          Serial.print("End Angle: ");
          Serial.println(frame.end_angle);
          Serial.print("Timestamp: ");
          Serial.println(frame.timestamp);
          
          for (int i = 0; i < POINTS_PER_PACK; i++) {
            Serial.print("Point ");
            Serial.print(i + 1);
            Serial.print(" Distance: ");
            Serial.print(frame.points[i].distance);
            Serial.print(" mm, Intensity: ");
            Serial.println(frame.points[i].intensity);
          }
          
          // Reset buffer
          bufferIndex = 0;
        }
      }
    }
  }

  //delay(10);
}

At the moment I have eliminated the CRC handling because it always comes back incorrect (will that mean something?).

Can anyone confirm the correct record structure or have a working example?

The lidar has the PWM pin grounded.

Many thanks in advance.

Translated with DeepL.com (free version)

Can you first output the raw data from the LD19 using your computer’s serial port software?

Then output the raw data from the serial port via arduino.

Also, please provide data frames for both

via image or txt

.

If the data frames of both are the same, then you need to consider the logic of the code.

Hi,
many thanks for your reply,

I tried as your suggestion and I dumped the serial data from my Arduino with this sketch:

const int HEADER = 0x54;  // Frame header of data package
const int VER_LEN = 0x2C; // VerLen value indicating valid packet

byte myInputBuffer[63];

// ****************************
void setup() {
  Serial.begin(115200);
  Serial2.begin(230400);
}
// ****************************
void loop() {
  if (Serial2.available()) {            
    Serial2.readBytes(myInputBuffer, 63); 

    for (int n = 0; n < 63; n++) {
      Serial.print(myInputBuffer[n], HEX);
      Serial.print(" ");

      // almost never happens
      if (myInputBuffer[n] == HEADER && myInputBuffer[n + 1] == VER_LEN) {
        Serial.println("HEADER");
      }
    }

    Serial.println();
  }
}

and the PC’s serial port.

The result is, of course, that the PC data is correct and I can easily see the 0x54+0x2C header which is not present in the Arduino dump.
The connection to the PC is via the Lidar interface and I think this is the difference.
I don’t know what the interface does other than adjust the speed. I have brought the PWN pin as ground as stated in the manuals perhaps this is not always correct?
My next test will be to try connecting the Lidar to the PC via an FTDI interface to check what data is actually being sent.

Regards.

The result with the FTDI interface is the same as with the Lidar interface, so the problem lies either in the Arduino’s serial port or in the data reading code.
A test could be done with a USB host shield and the FTDI board.

I think I realised that the problem lies in the Mega’s serial, which probably cannot handle 230400 baud. By connecting a new Arduino R4, the data arrives correctly.
Now we have to start decoding.

Thank you.

1 Like