Pololu Blog »
Now available: VL53L1X library for Arduino
We’ve released a basic VL53L1X library for Arduino to make it easier to get started using an ST VL53L1X time-of-flight distance sensor with an Arduino-compatible controller.
Because of how complex the VL53L1X is and how difficult it is to learn how it works, developing a library for it has been more of a challenge than writing one for a typical sensor like an LSM303 accelerometer/magnetometer. ST’s public documentation for the VL53L1X does not describe the sensor’s internal registers or the procedures to configure and operate it; instead, they provide an API (application programming interface) for interfacing with the sensor. (This was also the case for the preceding VL53L0X, and some people have not been too thrilled with this kind of support.)
The API consists of set of functions that can be used to communicate with the VL53L1X, and its source code can be customized and compiled for a chosen platform. It’s nice to have official software that should just work, but in practice, there are several factors that make the API a less than ideal solution for the Arduino platform. For one thing, given the limited resources on an 8-bit AVR, the API uses a lot of storage and memory; when compiled for an A-Star with an ATmega32U4 microcontroller, our implementation of the ST API uses 79% of the program storage space and 49% of the dynamic memory. Additionally, the API is structured in a way that makes it a little more awkward to work with multiple sensors.
With these drawbacks in mind, my goal when writing this Arduino library was to create a streamlined software interface that makes it easy to start using the sensor in your own programs and uses less storage and memory than the API. My development process involved first modifying the API to log all of the I²C communication between the Arduino and the sensor, then digging through the API source code to try to understand how it generates all of those accesses and how it could be made more efficient. The latter task was a lot of work because of how the API compartmentalizes logic and splits it into many layers of function calls. For example, here is a call graph for one of the main functions used to initialize the sensor:
This call graph was made with Doxygen, a tool for generating documentation from source code, which I found very helpful for understanding the structure of the API; I wish I had thought of using it when writing our VL53L0X library earlier. There are actually some comments in the API source code that contain Doxygen commands, so it’s a good bet that the engineers at ST used Doxygen while originally developing the API.
I felt that the API splits things up more than is necessary for good organization, so our library combines some operations into fewer functions. For comparison, here is a call graph of the library’s initialization function, whose role includes that of the API’s
VL53L1_StaticInit function shown above (though keep in mind that the library is more limited in capability and scope):
As for memory, part of the reason the API uses so much is that it keeps a copy of the sensor’s configuration registers in memory, manipulating the register values there and writing them to the device in big chunks only when it starts a measurement. This seemed inefficient to me, especially in cases where a particular setting is configured when the sensor starts up and then never changed again, so the library performs a one-time initialization that immediately writes most of the sensor’s configuration and then only writes a few essential registers to start each measurement.
The result is that our library has significantly smaller memory and storage footprints compared to the API: the example sketch in the screenshot above uses 37% of program space and 27% of dynamic memory on an ATmega32U4, while the more minimal “Continuous” example only uses 32% and 17%, respectively. (Some of the storage and memory usage comes from the USB code in the ATmega32U4 Arduino core; it is lower on a non-USB AVR, like the ATmega328P.) The library should also feel more comfortable to work with for a typical Arduino user, since it represents a sensor as an instance of a C++ object the same way most Arduino libraries represent devices.
However, it is important to acknowledge the library’s limitations. Our library does not support everything that ST’s API can do, such as calibrating the sensor to work well under a cover glass or selecting a smaller region of interest (ROI); while I’m interested in adding more functionality in the future, the library will probably never be as capable or flexible as the official API. The library also has less stringent error checking, so it might not be as tolerant of unexpected conditions as the API. Beyond that, while our library seems to work fine, it’s hard for me to be sure that I’ve adapted the API code correctly and that the library is performing the right operations and calculations. Consequently, using ST’s API could still be a better choice for you if you want to make sure you’re interfacing with the VL53L1X correctly, especially if you’re using an Arduino with more memory and storage space that can accommodate the API more easily.
For the typical hobbyist or experimenter, though, I expect this library to be a good way to get started with the VL53L1X and an Arduino. You can learn how to install and use the library on its GitHub page. Please let us know if you have any feedback on it, including any problems you experience or functionality you would like to see added.
(A frequent question we’ve gotten about the VL6180X and VL53L0X is how to use multiple sensors on the same I²C bus, and the VL53L1X works the same way, so I’m planning to write an example program for doing that. Hint: you have to individually enable each sensor and assign it a unique address, which only lasts until the next reset or power-off.)
I recently purchased this sensor and tried this library. I am getting "Failed to detect and initialize sensor!" error message. Can you please help?
I am sorry you are having trouble interfacing with your sensor. We would have to know more about your system in order to figure out why you are getting that message, but the comments section of a blog post is not a good place to begin troubleshooting. Can you create a new topic on our forum and tell us more about your setup? In particular, it would be good to know which Arduino you are using and how you are supplying power to the VL53L1X. It would also help for you to share pictures that show all of your connections and soldered joints.
Some friends and I are working with the VL53L1X for our Electrical Engineering Senior Design project. We are using the sensor with a Raspberry Pi, and we are interested in speaking with you further regarding your blog post and some follow up questions. Would you be able to reach out, so that we may discuss?
Sure, please start a discussion on our forum and I (or the other engineers here) can respond to your questions.
How many mximum number of VL53L1X sensors can be connected to arduino Atmega 2560?
please let me know asap.
The practical limit is going to depend on the design of your system. In general, the method of addressing multiples of those sensors is the same as for the VL53L0X. You might look at this thread on our forum and continue the discussion there or post a new topic with more details about your system if you have further questions:
First, thanks for this library, I've connected a VL53L1X-Satel to my Arduino Uno and it works great.
However, I'm looking for a way to make a trigger event at a certain distance, does anyone know how to achieve this?
I've posted it on the Arduino Forum as well, without any luck.
I'm trying to make sure the VL53L1X is measuring whenever there is a change (by using the standby mode).
If the distance decreases by one meter, a LED should go on.
Also, a more difficult situation, I want to count people with the sensor(s)
Is there any tips or support available for these situations, I'm stuck now.
You might look at the VL53L1X Time-of-Flight sensor datasheet and the VL53L1X API user manual for details on how the GPIO1 pin can be used for interrupts.
As for counting people, you can see our response here to a similar question on our forum.
I am looking for a driver to develop using the VL53L1X. The ST Micro Ultra Lite driver looks like what I need but I can't fine it supports the Arduino IDE. Their sketches do not compile on Arduino processors.
Any held will be appreciated.
Our VL53L1X Arduino library does not support changing the ROI and calibrating the sensor at this time, so if you need that functionality, you should probably use one of the official ST APIs like you mentioned (either the full or ultra lite API). We do have an implementation of the full VL53L1X API for Arduino, although we do not have a port of the ultra lite API. From a quick web search, I found that someone else made this Arduino port of the VL53L1X ULD, so that might be useful to you, although we have not tried it.