How can I obtain the data from a Garmin LIDAR LITE V3 sensor to analyse it within MATLAB?

25 views (last 30 days)
Mark S
Mark S on 30 Jun 2019
Commented: Walter Roberson on 17 Aug 2020
Hi,
I have been attempting to use the Garmin LIDAR LITE V3 sensor ( https://www.sparkfun.com/products/14032?_ga=2.74401170.142477364.1561912252-1059807822.1559660750 ) and have the data sent to the MATLAB workspace so it can be analysed and used for plots etc.
I have the sensor up and running via the examples provided here ( https://github.com/garmin/LIDARLite_Arduino_Library ) on just the arduino board itself with no difficulty, but when I try to do the same via MATLAB using the Arduino support package toolbox, I am having some difficulty getting the data into the workspace.
The sensor itselfs has I2C communications if that helps, but some assitance with how I can get the data would be appreciated. I have used the HC-SR04 ultrasonic sensor before in a similar fashion but that device already had a toolbox pre made, but I have no experience making one from scratch.
Does anybody have some experience with the LIDAR LITE V3 sensor or having data collected from the arduino and usable in the MATLAB workspace enviroment for this type of application that would be able to help?

Answers (2)

Alexander Walsh
Alexander Walsh on 16 Aug 2020
Edited: Walter Roberson on 16 Aug 2020
Hello,
It took me a while to figure it out but here is a very rough solution I found to get the measurements:
garmin = device(a, 'I2CAddress', '0x62') %a is the arduino object.
while true
writeRegister(garmin, 0, 4);
one = readRegister(garmin, '0x01');
pause(0.05)
D = readRegister(garmin, '0x10', 'uint8');
V = readRegister(garmin, '0x09', 'uint8');
fprintf('\n??: %.2f\nDI: %.2f\nVE: %.2f\n', one, D, V)
end
This just reads the distance in cm and velocity. (I think it's in cm/s). I don't know if you need the pause(0.05) but I just put it there while I was testing.
I'm still not sure what the register '0x01' is for but in the Garmin Lidar-Lite v3 manual it says to "Read register 0x01. Repeat until bit 0 (LSB) goes low." I don't really get what this means but what I did seems to work without it. Not sure about that part.
  3 Comments
Walter Roberson
Walter Roberson on 16 Aug 2020
I do not have any good ideas at the moment, but for the moment I would suggest outputing the value of one each time and seeing if it is changing in an interesting way at the time of the fault.

Sign in to comment.


Alexander Walsh
Alexander Walsh on 17 Aug 2020
Edited: Alexander Walsh on 17 Aug 2020
Here is the completed script. It uses an arduino and 2 servos to make a scanner that then plots a point cloud. It turns out the connection issues I was having were from a joint that needed re-soldered.
%Alexander Walsh 8/16/2020
%Simple Lidar scanner using arduino and Garmin Lidar-Lite v3.
a = arduino(); %Make sure you have 'Servo' and 'I2C' Libraries included.
s1 = servo(a, 'D3');%Creates a servo object on pin D3.
s2 = servo(a, 'D5');%Creates a servo object on pin D5.
garmin = device(a, 'I2CAddress', '0x62')%Connects to the lidar device.
%Zero the servo position.
writePosition(s1, 0);
writePosition(s2, 0);
%Allow time for the servos to move.
pause(1);
%servoAngleT is for the "tilt" servo (up/down).
%servoAngleP is for the "pan" servo (left/right).
%The servos have a range of 0 to 1, Right-Left, Down-Up.
%Servos must have a physical range of 0 to 180 degrees. for this to work.
jj = 1;
ij = 1;
servoAngleT = 0;
clear data
%"data" is the matrix where two angles and the distance value will be
%stored each loop.
while servoAngleT <= 1
%Move the tilt servo up and reset the pan servo.
writePosition(s2, servoAngleT);
pause(0.2)
servoAngleP = 0;
writePosition(s1, servoAngleP)
pause(2)
ii = 1;
while servoAngleP <= 1
%Move the pan servo to the left.
writePosition(s1, servoAngleP);
writeRegister(garmin, 0, 4);
while true
one = readRegister(garmin, '0x01');
if mod(one,2) == 0; break; end
end
%Data from the Garmin Lidar Lite v3 is 2 bytes, but I2C
%communication only allows for 1 at a time, so it sends
%the measurement as 2 8-bit integers. Each distance
%measurement has a low and high byte that must be combined into a
%16-bit integer to get a distance reading. Without this step, you
%are only able to read up to 255cm with the low byte.
DL = readRegister(garmin, '0x10', 'uint8');%Low byte.
DH = readRegister(garmin, '0x0f', 'uint8');%High byte.
%Combine into int16.
DC = uint8([DH DL]);
DC = uint16(DC);
D = typecast(bitor(bitshift(DC(1), 8), DC(2)), 'int16');
%Storing distance and servo position in a matrix.
data(1, ij) = servoAngleP;
data(2, ij) = servoAngleT;
data(3, ij) = D;
ii = ii + 1;
ij = ij + 1;
servoAngleP = servoAngleP + 0.01;%Specifies pan resolution.
end
servoAngleT = servoAngleT + 0.01;%Specifies tilt resolution.
end
%Moving the servos to the center when scan is complete.
writePosition(s1, 0.5);
writePosition(s2, 0.5);
%Extracting 3 seperate lines of data from the matrix.
theta = data(1, :);
phi = data(2, :);
radius = data(3, :);
%Using matlabs built in 'pi' is less precise, so I defined one with more
%decimal places.
pii = 3.1415926535;
%Converting servo values into radians.
phi = phi * pii;
theta = theta * pii;
%Converting from spherical coordinates into cartesian coordinates for
%plotting on a 3d graph.
x = radius .* cos(theta) .* sin(phi);
y = radius .* sin(theta) .* sin(phi);
z = radius .* cos(phi);
%creating a point cloud.
plot3(x, y, z, 'r.')
%Making the axes all the same ensures that the data won't appear
%stretched or squished on any axis. -600 to 600 is just an example.
axis([-600 600 -600 600 -600 600])
hold on
%plotting a marker at 0, 0, 0 to show the center.
plot3(0, 0, 0, 'dg')

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!