garmin / LIDARLite_Arduino_Library

High-performance optical distance sensing.
Apache License 2.0
181 stars 84 forks source link

LIDAR-LITE V3HP distance measurement results unclear.... #25

Open KingZuluKing opened 3 years ago

KingZuluKing commented 3 years ago

Dear all, We are interfacing the Garmin LIDAR-LITE V3HP with our hardware and using the datasheet to send the i2C commands to make a distance measurements. We use ATmega1284p AVR as Host MCU.

It seems that what we receive is garbage, and/or not correct measurement data. Below is the i2C session which we initiate with device. Any information regarding the i2C transaction and its commands being sent to achieve the correct data will be highly appreciated.... David

      uint8_t receiver_reply;
      i2cStart(); // start a i2C session
      i2cSend(0xC4); // LIDAR address with write bit
      receiver_reply = TWSR; // MCU register with session codes, to checkup on errors....
      receiver_reply = receiver_reply & 0b11111000;

      printBinaryByte(receiver_reply);
      printString("\r\n");

      if(receiver_reply == 0x18){  // if Ack receieved from LIDAR
            printString("\r\n issuing start condition ok, device accessible\r\n");
            i2cSend(0x00); // send the register address
            receiver_reply = TWSR; // again checkup on Ack and errors.....
            receiver_reply = receiver_reply & 0b11111000;
            printBinaryByte(receiver_reply);
            printString("\r\n");
            if(receiver_reply == 0x28){
                    printString("\r\n register 0x00 address sent >> ok\r\n");
                    i2cSend(0x04); // writing 0x04 to register 0x00 to start a distance measurement
                    receiver_reply = TWSR; // again checkup on Ack and errors.....
                    receiver_reply = receiver_reply & 0b11111000;
                    printBinaryByte(receiver_reply);
                    printString("\r\n");

                    i2cStop();
                    if(receiver_reply == 0x28){ // again checkup on Ack and errors.....
                            printString("\r\n wrote 0x04 to register 0x00\r\n");
                            i2cStart();
                            i2cSend(0xC5); // put LIDAR in Read mode
                            receiver_reply = TWSR; // again checkup on Ack and errors.....
                            receiver_reply = receiver_reply & 0b11111000;
                            printBinaryByte(receiver_reply);
                            printString("\r\n");

                            if(receiver_reply == 0x40){
                                i2cSend(0x01);
                                 for(int i = 0; i < 100; i ++){
                                     uint8_t lidar_busy_flag = i2cReadAck();
                                     printBinaryByte(lidar_busy_flag);
                                     printString("\r\n");
                                     if((lidar_busy_flag & 0b00000001) == 0x00){
                                          i2cSend(0x0f); // send address of highbyte 
                                          receiver_reply = TWSR;
                                          receiver_reply = receiver_reply & 0b11111000; 
                                          printBinaryByte(receiver_reply);
                                         uint8_t distance_high = i2cReadAck(); // read highbyte 
                                          i2cSend(0x01); // send address of lowbyte
                                         uint8_t distance_low = i2cReadNoAck(); // read lowbyte
                                        uint16_t range = distance_high << 8;
                                        range = range | distance_low;
                                        printWord(range);
                                        printString("\r\n");
                                     }
                                     else{
                                        printString("busy flag!");
                                        printBinaryByte(lidar_busy_flag);
                                        printString("\r\n");
                                   }
                                   }
BradWiseman commented 3 years ago

In your example code, you have the following line:

// i2cSend(0x01); // send address of lowbyte

That refers to the wrong address. The correct address would be 0x10:

// i2cSend(0x10); // send address of lowbyte

KingZuluKing commented 3 years ago

Hello Brad, Thanks for the feedback. I have changed, and rewritten some part of the code and we get now stable data from LIDAR Lite v3HP.

But there is one thing which seems to be unclear to me in the code below. There are some debug printouts in between to follow each transaction on i2C. When I use this code below to poll status, everything is okay, and I can see what status LIDAR Lite currently has. But when I remove these debug printouts, then this code starts tells me LIDAR Lite is Busy all the time. If I turn back on the debug printouts then it start working properly. Any ideas what could be a reason for that behavior.

David

uint8_t check_LIDAR_busyFlag(void){

uint8_t receiver_reply;
uint8_t status_register = 0;

i2cStart();                                                          // start a session on the i2C BUS
i2cSend(0b11000100);                                                       // write operation on LIDAR

receiver_reply = TWSR;                                                         // read twi status code
receiver_reply = (receiver_reply & 0b11111000);                               // mask the lower 3 bits

if(receiver_reply == TW_MT_SLA_ACK){                        // if LIDAR sent Ack! proceed to next step
        printString("issuing address + write bit >> ok!, device accessible\r\n");
        printBinaryByte(receiver_reply);                       // return the upper 5 bits for check-up
        printString("\r\n");

        i2cSend(0b00000001);                             // sending LIDAR status register address here

        receiver_reply = TWSR;                                                 // read twi status code
        receiver_reply = receiver_reply & 0b11111000;                         // mask the lower 3 bits

        if(receiver_reply == TW_MT_DATA_ACK){               // if LIDAR sent Ack! proceed to next step
                printString("register 0x01 address sent >> ok!\r\n");
                printBinaryByte(receiver_reply);               // return the upper 5 bits for check-up
                printString("\r\n");
                i2cStop();                                                         // stop i2C session
            }
        }
        printString("i am here");
        printString("\r\n");

        i2cStart();                                                       // start a i2C session again
        i2cSend(0b11000101);                                        // send LIDAR address and read bit

        receiver_reply = TWSR;                                                 // read twi status code
        receiver_reply = receiver_reply & 0b11111000;                         // mask the lower 3 bits

        printBinaryByte(receiver_reply);                       // return the upper 5 bits for check-up
        printString("\r\n");

        if(receiver_reply == TW_MR_SLA_ACK){                // if LIDAR sent Ack! proceed to next step
                printString("issuing address + read bit >> ok!, device accessible ------\r\n");
                printBinaryByte(receiver_reply);               // return the upper 5 bits for check-up
                printString("\r\n");
                status_register = i2cReadNoAck();
                printString("\r\nLIDAR-STATUS = ");
                printBinaryByte(status_register);
                printString("\r\n");
        }
        return(status_register);

}