We have already mentioned several sensors for the detection and distance measure of nearby objects: cheap acoustic sonars, very expensive laser telemeters, and several optical sensors in between. Among those, we hadn't yet tested the Garmin LIDAR-Lite v4.
Successor to the first LIDAR-Lite that we tested six years ago and to the more recent version illustrated with the release of the Yocto-I2C, this sensor seems to use a new and more compact optic:
The LIDAR-Lite v4 is more compact than previous versions
The electronics was also modified as this version offers new connection options. Relevant for our purposes, the I2C connection now officially uses 3.3V levels. Note however that on this new enclosure, Garmin forgot to offer mounting holes, too bad.
Connection
The LIDAR-Lite v4 has a little pad on which you can solder up to 10 wires depending on the applications, but only four wires are necessary to use it in I2C with the firmware which is factory supplied by Garmin: two for the 5V power supply and two for the I2C line:
Connecting the LIDAR-Lite v4 to the Yocto-I2C
Reading the sensor
The I2C address of the LIDAR-Lite v4 when leaving the factory is 0x62, but you can change it if need be. In a very similar way to version 3, to obtain a measure you must write 0x04 in register 0x00 to trigger the measure, wait for bit 0 of the 0x01 register to go to zero to indicate the end of the measure, then read the distance in cm, coded over two bytes in the 0x10 register, in little-endian. The returned measure is actually the average of several measures taken by the sensor and combined to improve accuracy.
You can represent this protocol with a small state machine, which can be directly implement in the Yocto-I2C as a job, so that the module directly queries the sensor and publishes the measures as if it were a native Yoctopuce sensor:
The I2C querying the LIDAR-Lite v4
Here is the corresponding job for the Yocto-I2C
- Task "init" (periodic, one time, to initialize)
- assert !isset($state)
- compute $state = 0
- Task "trigger" (periodic, 10ms, to trigger the measure)
- assert isset($state)
- assert $state == 0
- writeLine @62:0004
- expect 62:{A}{A}{A}
- compute $state = 1
- Task "read" (periodic, 2ms, to wait for the result)
- assert isset($state)
- assert $state == 1
- writeLine@62:01xx
- expect 62:{A}{A} 62:{A}($ready:BYTE)
- assert ($ready & 1) == 0
- writeLine @62:10xxxx
- expect 62:{A}{A} 62:{A}($1:WORDL)
- compute $state = 0
Note that we have been able to combine states 1 and 2 into the task "read", as the effect of the assert in the middle of the task when the condition is not met is to stay in the same state and retry later from the beginning of the task.
On purpose, we used very short repetition periods, as the sensor can take measures very quickly when the object is close. But note that the farther the object, the longer the measure takes, and therefore the measured value changes less frequently.
Results
Garmin announces that this sensor can measure distances up to ten meters. We were rather sceptical, given our previous experiments with other models, and having seen that the specifications indicated that these ten meters were guaranteed only inside and with a 90% reflective surface. Actually, we were pleasantly surprised: the measures are reasonably stable thanks to the embedded averaging, and we obtained correct values beyond 5 meters even outside with an significant luminosity (between 30'000 and 50'000 lux).
Using this sensor with the Yocto-I2C is therefore a very interesting alternative to the Yocto-RangeFinder for applications requiring a measure of distances above 1 or 2 meters, or requiring a more focussed viewing angle.