Lidar Lite v3 "free running" operation questions

I have been using the device for a while but recently I started trying to do some “calibration”. I’m using the Garmin Arduino I2C-based library (LidarLiteV3) to capture distances, using bias correction. While pointed at a reasonably decent surface perpendicular to the lidar, I found, using the distance() method and sampling “as fast as possible”, that over 100-200 samples, the reported range can change dramatically. As a specific example, with the device positioned ~103 cm from the surface, the first reading was 119 cm; somewhere between 100-200 samples the reading “stabilized” around 102-105. So some sort “break in” or “warm up” appears to be needed. Even after the 200 readings, if the unit sits idle, readings again get more erroneous; for example, with the actual distance ~103 cm, the first reading could be 108, and after maybe 20 samples again settles to 102-105.

Thus I’ve been trying to keep the sensor “warmed up”. In my system, I really only want to get a distance about every 30-50 ms (I’m waiting on the servo upon which the lidar is mounted to finish movement before each reading). Taking a few hundred readings prior to starting servo movement seems to help, but I still experience some higher than expected erroneous distances, I think due to the delay between readings, allowing the unit to “cool down”.

The Garmin specification mentions a “free running” mode. There is not much really said about it, but it seems that it might be a good way to keep the device “warmed up”. So far in my testing, I seem to be able to get the device into free running (tho I confess I am still not 100% certain) using the following:

  // set OUTER_LOOP_COUNT register for free running operation
  lidar.write(0x11, 0xff, LIDARLITE_ADDR_DEFAULT);
  
  // start acquistion with bias correction (ACQ_COMMAND register)
  lidar.write(0x00, 0x04, LIDARLITE_ADDR_DEFAULT);

I then get distances using the following:

    byte distanceArray[2]; // Array to store high and low bytes of distance
    // Read two bytes from register 0x8f (autoincrement for reading 0x0f and 0x10)
    lidar.read(0x8f, 2, distanceArray, false, LIDARLITE_ADDR_DEFAULT);
    // Shift high byte and add to low byte
    int distance = (distanceArray[0] << 8) + distanceArray[1];

I copied that code from the library. The only thing of interest is that apparently the the busy flag in the status register does not function reliably. So, fundamentally, this works, at least after a fashion. The obvious problem is that it is difficult to tell when there is truly a new reading, so have to depend more or less on understanding the delay between measurements during free running operation.

The real problem I’m having is turning off free running and getting back to the default “not free running state”. The code I use to do that is:

  // reset the unit
  lidar.reset(LIDARLITE_ADDR_DEFAULT);
  delay(100);
  // do initial config again
  lidar.configure(0);

The reset() should take all registers to the power on value, and the configure() should set up the device as initially configured. I then use the distance() method to try to get samples. The library emits “> read x” which signifies a read failure. So, at best getting back to “normal” works sporadically, and so might as well never work. So far the only way I’ve found to fix this is to power the device down and back up.

I’ve done a bit of searching, but I can find nothing that helps me understand the problems I’m seeing. Any advice or suggestions would be welcome.

1 Like

An additional question and some additional information.

The question: Above I mentioned positioning the lidar device ~103 cm from a surface for tests. I have to admit I don’t really know how to measure the true physical distance from the device to a target surface. The drawings on page 12 of the specification suggest the end of the lens. However, the distance readings suggest that the distance may be the “block” to which the lens are attached. Can you offer advice.

Additional information: I’ve begun experimenting with burst mode instead of free running. So far it appears that I can successfully switch between burst and single mode. Good news. But it does not help explain why cannot switch out of free running…

1 Like

Hey @gaflurry,

Thanks for the all the details you provided. Makes figuring out how to help that much easier! :wink:

The reset function (sending 0x00 to address 0x00) should indeed reset the FPGA and therefore all register values to defaults.
Unsure as to why it does not revert back. Maybe it busies itself in continuous mode and cannot respond properly to mode change request?
Maybe when it is in that state it would be helpful to check what is in the status register and see if that provides more info.

That sounds quite good. Hopefully that works well for your project.

IIRC, the PCB itself on which the sensor is mounted is the reference point for distance measurement. Something like this:
image

Sincerely,

Thanks for the feedback. I’ll play with continuous some more per your advice.

To add fuel to the fire, I’ve done more work on burst mode, and I’m gaining confidence that I can use it nearly as effectively as continuous. That is the good news.

The bad news is that I have to report what appears to be more anomalous behavior. I wondered if I could use the velocity register as an indicator that the device had warmed up. The theory is that assuming the device points to a fixed surface, once warmed up, the velocity should oscillate around 0, within the bounds of the device precision. I began some testing and found that occasionally there would be odd readings. I decided to look at the LAST_DELAY_x registers and I’ve found some very odd things. Some examples:

  • with FULL_DELAY_x=98 @ measurement N-1, LAST_DELAY_x=89 @ measurement N
  • with FULL_DELAY_x=104 @ measurement N-1, LAST_DELAY_x=102 @ measurement N
  • with FULL_DELAY_x=102 @ measurement N-1, LAST_DELAY_x=101 @ measurement N

I cannot explain this by other than an intermittent bug in the device.

Any thoughts?

Responding to one of your suggestions, I checked the busy flag for both continuous and burst modes. In burst, the device is busy for the entire burst, but once the burst is complete, it shows ready. This is entirely consistent with the way ‘single’ mode works. In continuous, once started, the device is busy and in effect stays that way forever, since as yet I’ve found no way to cancel continuous other than a full power off. The continuous busy indication actually makes sense; however, having no way to cancel continuous mode does not.

Do you have any contacts with the Garmin folks that might be able to offer deeper technical support?

I managed to navigate to Garmin tech support a few days ago. I thought it might be useful to summarize what they told me:

  • “FREE RUNNING” (CONTINUOUS) MODE: Its very existence appears to be a holdover from prior versions. Once in it, the only way out is power off/on. They don’t recommend it as one can never tell when measurements are stable, as the busy flag indicates always busy.

  • BURST MODE: Another holdover. While, as I reported earlier, it does work, they don’t recommend it, again due to the busy flag behavior. I should note that, for the problem I was trying to solve (break in or warm up), it would work fine.

  • “WARMUP”: The problem I mentioned earlier manifests as erroneous measurements (larger to much larger) for some time after power up, or some number of measurements (to me still not clear). In addition to the example earlier, I’ve seen an instance where, after power up, the error did not disappear until after 5,400 measurements; in another instance it took 12,000 measurements; in one instance where the device power was on for maybe 20 minutes without any measurements, with the device positioned 100 cm from the target, there were 9 reports of ~130 cm and then several hundred of ~100. Garmin says there is an unresolved bug in the “zero reference” processing. They suggested some work arounds but I’ve not yet tried them, as they appear to have some affect on accuracy.

The bottom line: The device is a bit more complicated to use with confidence. Further, the anomalous behaviors I’ve experienced are real. I will continue to use the device.

I forgot that Garmin tech support gave this [reference](https://support.garmin.com/en-US/?faq=C9KE7ATPNf51XO0FBKCDU7&partNumber=010-01722-00&searchQuery=continuous&tab=topics).