How can I obtain the data from a Garmin LIDAR LITE V3 sensor to analyse it within MATLAB?
    10 views (last 30 days)
  
       Show older comments
    
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?
0 Comments
Answers (2)
  Alexander Walsh
 on 16 Aug 2020
        
      Edited: Alexander Walsh
 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
  Alexander Walsh
 on 16 Aug 2020
				
      Edited: Alexander Walsh
 on 16 Aug 2020
  
			I'm trying to incorporate servo movement to make a sort of "scanner." And I've implemented your loop here:
servoAngle = 0;
ii = 1;
clear data
    while servoAngle <= 1
        writePosition(s1, servoAngle);%s1 is the servo, range 0 to 1.
        writeRegister(garmin, 0, 4);
        while true
            one = readRegister(garmin, '0x01');
            if mod(one,2) == 0; break; end
        end
        D = readRegister(garmin, '0x10', 'uint8');
        data(1, ii) = D;
        data(2, ii) = servoAngle;
        ii = ii + 1;
        servoAngle = servoAngle + 0.02;
    end
It works for a few seconds but then I get the error: "Error occured while reading data from the I2C device. Check the connections between the hardware and device, clear the device object and create a new one."
Any idea why I'd get this after a few loops? I have checked that all the connections are solid but this still continues to happen.
  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.
  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')
1 Comment
  Walter Roberson
      
      
 on 17 Aug 2020
				D = typecast(uint8([DL DH]), 'int16') ;  %low high on intel architecture
See Also
Categories
				Find more on Instrument Control Toolbox in Help Center and File Exchange
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!