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.