Getting Started with the Garmin Lidar‐Lite v3 - Carleton-SRL/SPOT GitHub Wiki
Important
THIS ENTRY IS A WIP!!
Getting the distance from the Lidar-Lite is actually pretty easy once you have it hooked up right.
The Python code is:
import os
import fcntl
import time
import struct
import socket
import math
# Set up I2C
f = os.open('/dev/i2c-7', os.O_RDWR)
fcntl.ioctl(f, 0x0703, 0x62)
try:
while True:
os.write(f, b'\x00\x04')
time.sleep(0.005)
os.write(f, b'\x8f')
dist = struct.unpack('>H', os.read(f, 2))[0]
# Convert to 32-bit float (single) and send
dist_float = float(dist)
#data = bytearray(struct.pack("f", dist_float))
#sock.sendto(data, server_address)
print(f"Distance: {dist_float:.2f} cm")
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address_red = ('192.168.1.110', 35678)
server_address_black = ('192.168.1.111', 35678)
server_address_blue = ('192.168.1.112', 35678)
data = bytearray(struct.pack("f", dist_float))
sock.sendto(data, server_address_red)
sock.sendto(data, server_address_black)
sock.sendto(data, server_address_blue)
time.sleep(0.005)
except KeyboardInterrupt:
print("\nStopped")
finally:
os.close(f)
sock.close()
Note
We will need to expand on this code [1] and include a way to pass the data around, and we need to develop an integrated circuit for the Lidar-Lite.
[1] For example, we are currently using time.sleep()
to wait for a measurement; in contrast, the spec recommends reading register 0x01
until bit 0 (LSB) goes low.
constant | description |
---|---|
/dev/i2c-7 |
I2C bus 7 |
Ox0703 |
flag to set the I2C device address |
0x62 |
the default I2C address for the Lidar-Lite |
\x00\x04 |
writes 0x04 to register 0x00 ("Take distance measurement with receiver bias correction") |
\x8f |
the read register (two bytes!) for the laser rangefinder measurement |
>H |
a big-endian unsigned short integer |
import time
from smbus2 import SMBus
# Use the correct I2C bus (check with `i2cdetect -l` or `i2cdetect -y <bus_num>`)
I2C_BUS = 1 # Example: /dev/i2c-1
DEVICE_ADDR = 0x62
with SMBus(I2C_BUS) as bus:
# Step 1: Write 0x04 to register 0x00
bus.write_byte_data(DEVICE_ADDR, 0x00, 0x04)
# Step 2: Poll register 0x01 until bit 0 goes low
while True:
status = bus.read_byte_data(DEVICE_ADDR, 0x01)
if (status & 0x01) == 0:
break
time.sleep(0.01)
# Step 3: Read two bytes from register 0x8f
data = bus.read_i2c_block_data(DEVICE_ADDR, 0x8f, 2)
result = (data[0] << 8) | data[1]
print(f"Read value: {result:#06x}")
Revision A
Sep 2016
190-02088-00
link: https://static.garmin.com/pumac/LIDAR_Lite_v3_Operation_Manual_and_Technical_Specifications.pdf
According to the spec sheet, the LIDAR Lite has 6 pins:
pin | function |
---|---|
1 | 5 Vdc |
2 | power enable (internal pull-up) |
3 | mode control |
4 | I2C SCL (clock) |
5 | I2C SDA (data) |
6 | Ground |
Basic functionality is possible with four pins (power | ground | clock | data). In addition:
- Pin 2 can be driven low to shut off power to the device; and
- Pin 3 can be driven low to trigger a PWM measurement mode
After discussion with Steve, it was decided that
- Pin 2 should be driven low by default and driven high when measurements are desired; and
- Pin 3 should be driven high by default.
Specification | Measurement |
---|---|
range | 40 m |
resolution | ± 1 cm |
accuracy < 5 m | ± 2.5 cm |
update rate | 270 Hz (typical) |
Note
range and update rate assume a 70% reflective target.
Warning
A nonlinearity is present below 1 m.
Specification | Measurement |
---|---|
beam diameter at laser aperture | 12 × 2 mm |
divergence | 8 mrad (~0.5°) |
Note
Less than 1 m, the beam diameter is about the size of the aperture (lens).
For distances greater than 1m, you can estimate the beam diameter as distance / 100.
Note
A measurement of 1.00 cm indicates an invalid measurement.
The device has a 7-bit address with a default value of 0x62
; this corresponds to I2C addresses of 0xC4
(write) and 0xC5
(read).
The simplest method of obtaining measurements is as follows:
- write
0x04
to register0x00
.- "Take distance measurement with receiver bias correction"
- read register
0x01
until bit 0 (LSB) goes low. - read two bytes from
0x8f
to obtain the 16-bit measured distance in centimetres.