3D Lidar Scanner

Electronics - 28-10-2017


In order to perform an accurate 3D scan of a room/environment, I created this lidar (LIght Detection And Ranging) turret as a 3-day project. Based on the Garmin™ LIDAR-Lite v3, it scans its surroundings using an infrared laser beam and rotating it using small servomotors. This video shows the completed apparatus:

The scan time mainly depends of the step size we chose. It ranges from less that a minute to about 30 minutes (full resolution, more that 32,000 data points). The accuracy of the measurements is about 1 cm, up to 40 meters in range.

The acquisition and visualization software I created for this project can extract the point cloud for further use (3D Printing, CAD software, etc.).


Hardware-wise, the scanner is rather basic: two 9g micro servomotors control the roll and pitch rotational axes. The brackets that hold them together are 3D printed.

Servomotors construction

Download the 3D files (SolidWorks & STL)

Concerning the electronics, I used:

  • Arduino Nano: the controller for the turret. It drives the servomotors and control the lidar while doing a small amount of computation to output the point cloud.
  • LIDAR-Lite v3: a compact, high-performance optical distance measurement sensor.
  • 9g SG90 Servomotors: actuators to rotate the lidar. Although these weak motors are a major bottleneck to the system, I used them simply because I already had them. Some more powerful and less "wobbly" servos would definitely enhance the quality and speed of the capture.
  • 650uF capacitor: this large electrolytic capacitor prevents the micro-controller from rebooting during the current spikes that both the lidar and the motors create.

This is the wiring diagram for the my lidar turret:

Wiring diagram of the Lidar


The software that operates this project is divided into two distinct bits of code: the micro-controller side and the data acquisition/visualization software. It is of course fully open-source, and you can download the complete source for both parts by clicking on this button:

Download the source

Arduino code

Thank to the Servo.h and LIDARLite.h Arduino libraries, the code to control these elements is made much easier. The basic work-flow of the code is the following:

  Init. lidar, servos and serial;
  For YawAngle = 0 to 180
    For PitchAngle = 0 to 180
      Compute coordinates;
      Send value;

The micro-controller only knows the angles of the servos and the distance to the obstacle. A small amount of computation is required to convert the yaw angle, pitch angle and range information into much more usable X, Y and Z coordinates.

Spherical coordinates conversion formulas

Using these spherical to Cartesian coordinates system conversion formulas, it outputs the position of the point on the serial port.

Data acquisition and visualization software

In order to collect, display and use the turret, I created a software using Processing. It is a very convenient open-source Java framework made for graphic related work. LidarViewer reads the serial port to get the data; displays it as a 3D point cloud we can zoom, pan, rotate and move; and saves it to a file so we can use it later on (in Meshlab for instance).

LidarViewer software

Author: Charles Grassin

What is on your mind?

  • #1 SHAHID

    How to save a file that can be open in Meshlab or CAD

    on November 21 2018, 0:37

  • #2 Charles

    My LIDARviewer Processing sketch is a basic 3D viewer I created for this application and does not include a lot of features. You can save the point cloud by pressing the S key, so you can import it into Meshlab. However, you can't open an existing point cloud in it. However, this would be a pretty easy to add feature. I recommand not to take this code as-is and to have a look at the Java. There is probably a lot of room for improvement!
    Good luck!

    on November 22 2018, 6:23

  • #3 Hardrone

    1) I am facing "'import' does not name a type"error in .pde file (Under LidarViewer.pde)
    2) I am getting "Datestamp >> >> nack" message for each detection, instead of the distance measured in Serial Monitor (Under LidarTurret.ino)
    3) How to get the output in terms of point cloud out the distance measured? I mean, what you have shown is, you are getting a continuous point cloud generation with respect to the distance measured.

    on February 6 2019, 10:18

  • #4 Janu

    Hey how did you view the data points in processing? we have to use same code used in Arduino for processing as well?

    on February 8 2019, 4:32

  • #5 Jaime Candelaria

    Amazinig project Charles
    I am currently working with the same lidar but with a raspberry pi and 2 servo motors in order to have the pitch and yaw angles. I keep noticing that, when scanning, the sensor reads distances that do not make any sense (like 10,000cm when scanning a small room or box). Were you faced with this problem? How did you over came it?
    Thanks a lot!

    on February 18 2019, 19:44

  • #6 Charles

    @Janu: the visualization software is the "LidarViewer.pde" sketch, while the Arduino code is the "LidarTurret.ino" sketch.

    on February 19 2019, 20:40

  • #7 Charles

    @Jaime Candelaria: Thank you! No I did not encountered this problem... Does it always do it, or is it some intermittent error? Have you put the capacitor on the power lines of the lidar? I draws a large current on its measurements, and may have an erratic behaviour if this is not dealt with. What I would do is try my sketch if you have an Arduino laying around. It is a much simpler system than the Raspberry Pi, and could help you rule out an electrical issue.

    on February 19 2019, 20:46

  • #8 janu

    Hi. the file is not getting saved for me. I pressed S key and I searched processing install directory. I couldn't find my file. All other keys are working for example x key for erasing and other movement keys except s key. where exactly the file will be saved.

    on March 5 2019, 5:47

  • #9 Charles

    Hi janu! For some reason, Processing may be trying to save the file somewhere else. A quick workaround is to replace the path in the "void saveToFile()" method by hard-coding the fileName variable with a path of your choice (for instance, String fileName = "C:/file.xyz"; on Windows or String fileName = "/home/<your user name>/file.xyz"; on Linux). If you are on Linux, you need write permission on the folder.

    on March 5 2019, 9:53

  • #10 Paul

    hi Charles first of all thank you for your work, 2nd I wonder if I use different servo motors would this change the results ??

    on March 14 2019, 23:01

  • #11 Charles

    Hi Paul! The SG90 servo I used are the cheapest servo motor you can buy. They are actually pretty bad because their control loop tend to oscillate and not be very stable. Additionnally, they have plastic (nylon) gears. Hence, different servos would probably be better. Of course, the mount must be adapted.

    on March 20 2019, 7:04

  • #12 Alexander

    Hi Charles, how would I change it to only include a one dimensional movement, for example only PITCH and no YAW

    on March 27 2019, 19:57

  • #13 Alexander

    Hi Charles, sorry I forgot to mention that thank you for this! Also might I ask what you mean by the mechanical wobble?

    on March 27 2019, 19:58

  • #14 Alexander

    Also might I ask my friend what the s[15] means?

    on March 27 2019, 21:49

  • #15 Olga3

    Hello Charles, Thanks for this project. But I was wondering why the final result is like two scans inside each other? The ceiling is like two and not one and I notice in your screenshot it is the same. How we can overcome this problem? Thanks in advance for the help.

    on June 17 2019, 21:46

  • #16 olga

    Hello Charles, Thanks for this project. But I was wondering why the final result is like two scans inside each other? The ceiling is like two and not one and I notice in your screenshot it is the same. How we can overcome this problem? Thanks in advance for the help.

    on June 17 2019, 21:48

  • #17 Dario

    Hello, I based my project in this schema but I changed the Pan and Tilt kit so for that reason the servo motors changed the coordinate system, I could resolve this problem just switching cos and sin parameters but the final result also change because its symetric (like a mirror) its easy to fix just calculate the symetric function and thats it. I would like to say thank you for sharing this project it was really helpful for me , but if somebody will change something should be very carefull because it could make a lot of difference.

    on July 29 2019, 11:18

  • #18 Charles

    Thank you Dario, glad you were able to make it work! Yes, trigonometry can be tricky...

    on July 30 2019, 5:25

  • #19 pablo

    hello, I wanna use it for 3d mapping with a phantom4 drone, it is possible I hope you can help

    on December 26 2019, 3:55

  • #20 pablo

    hello, I wanna use it for 3d mapping with a phantom4 drone, it is possible I hope you can help

    on December 26 2019, 3:57

  • #21 Rob

    Nice code. I was wondering if you could help me with using this same code to identify what an object or shape could be. Say a cylinder, box, etc...

    on April 18 2020, 1:17

  • #22 CIRO


    on May 19 2020, 3:52

  Back to projects

Related articles