I’m using the VL6180X ToF (Time-of-Flight) sensors successfully in different projects. The VL6180X is great, but only can measure distances up to 20 cm and in ‘extended mode’ up to 60 cm. For a project I need to go beyond that, so the logical choice is the VL53L0X which measures between 30 cm and 100 cm or up to 200 cm. For this project I’m using the VL53L0X breakout board from Adafruit, but similar products are available e.g. from Pololu.
The breakout module from Adafruit (https://www.adafruit.com/product/3317) has all the needed level shifter included and is easy to connect with a microcontroller:
In this project I’m using the tinyK20 NXP Kinetis K20DX128 microcontroller (ARM Cortex-M4 running at 50 MHz). All what I needed is GND, 3.3V (VIN) and the I2C SCL and SDA signals. An Eclipse (GNU gcc) example project for it is available on GiHub.
Software
Unlike the VL6180X, the VL53L0X is a complicated beast and difficult to initialize and run. STM provides a rather heavy driver library, and I have found that without the ‘magic’ in that driver library it is probably not possible to use that device. And it seems that the initialisation sequence needed to run the sensor is only ‘documented’ with that driver library. So it took me a while to get it right, but finally it worked :-).
I have integrated the STM library files plus added a simple interface with vl53l0x.c and vl53l0x.h.That makes using the sensor fairly easy, and all what I have to do in the application is to initialize the sensor and afterwards I can read the sensor distance value in an endless loop like this:
#include "Application.h" #include "LED1.h" #include "WAIT1.h" #include "CLS1.h" #include "PORT_PDD.h" #include "Shell.h" #include "vl53l0x.h" void APP_Start(void) { int16_t mm; uint8_t res; int cntr; /* need pull-up on UART Rx pin (PTC3) on tinyK20 */ PORT_PDD_SetPinPullSelect(PORTC_BASE_PTR, 3, PORT_PDD_PULL_UP); PORT_PDD_SetPinPullEnable(PORTC_BASE_PTR, 3, PORT_PDD_PULL_ENABLE); CLS1_SendStr("\r\n*****************************\r\nVL53L0X with tinyK20\r\n*****************************\r\n", CLS1_GetStdio()->stdOut); /* initialization */ do { res = VL53L0X_Init(); if (res!=ERR_OK) { CLS1_SendStr("ERROR: failed VL53L0X_Init()!\r\n", CLS1_GetStdio()->stdOut); WAIT1_Waitms(1000); } } while(res!=ERR_OK); cntr = 0; for(;;) { /* main loop */ cntr++; if (cntr>60) { /* slow down measurements */ cntr = 0; do { res = VL53L0X_MeasureSingle(&mm); if (res!=ERR_OK) { CLS1_SendStr("ERROR: failed VL53L0X_MeasureSingle()!\r\n", CLS1_GetStdio()->stdOut); WAIT1_Waitms(1000); } } while(res!=ERR_OK); CLS1_printf("\r\nRange: %dmm\r\n", mm); } LED1_Neg(); WAIT1_Waitms(50); SHELL_Parse(); } }
This will periodically do a measurement and print it on the console. Additionally the example includes a command line (shell) integration which can be used to inspect the sensor status and data:
Summary
I’m using just the basic features of the sensor to make ‘one shot’ measurements in default mode, as this is all what I need. So far it works very well and I can accurately measure distances up to 100 cm or even beyond. You can find the sources and the projects files on GitHub (see links section below).
Happy Tofing 🙂
Links
- VL53L0X data sheet: https://www.st.com/en/imaging-and-photonics-solutions/vl53l0x.html
- VL53L0X from Adafruit: https://www.adafruit.com/product/3317
- VL53L0X from Pololu: https://www.pololu.com/product/2490
- Tutorial: STMicroelectronics VL6180X Time-of-Flight LIDARÂ Sensor
- Example project on GitHub: https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/KDS/tinyK20/tinyK20_VL53L0X_ToF
Good day Erich,
Happy New Year to you!
I recently had a need for distance sensors and looked at these ToF sensors, but disregearded them because of distance limitations. In my case I tested some Lidar sensors from Garmin (https://www.robotshop.com/ca/en/lidar-lite-3-laser-rangefinder.html). These worked really well, but are a lot more expensive than the smaller ToF sensors you mentioned in your article… but they can measure far greater distances and are relatively easy to communicate with. I also tested some more robust and longer range ultrasonic sensors (https://www.robotshop.com/ca/en/maxbotix-wrca1-weather-ultrasonic-range.html) and these worked well too… and were easy to communicate with as well. The only caveats with these, and pretty much any inexpensive less intelligent sensors, is one has to be quite aware of the surroundings where the sensors are to be used. What I mean is that in areas where there are a lot of reflective surfaces, these sensors can receive multiple reflected responses causing erroneous results. In my case this was a big problem given the application environment and so I had to use an expensive intelligent microwave sensor that encoded a digital signature to the incident pulse and so any later unintended reflections could be ignored.
With that said, I thought I would mention the above in case you have not considered these other devices.
Cheers,
Sam
LikeLike
Hi Sam,
thanks for providing links to these sensors! I have used Ultrasonic ones in different situations. Naturally, they are not accurate if the air is moving (wind), depend on temperature and air density, etc.
That LIDAR from RobotShop sounds like a good sensor (you get what you pay for), and we have used 3D LIDAR sensors too which costs >10k$, so even more expensive.
LikeLike
Hi Erich,
so is 10 Hz as fast as these sensors go? Have you seen the OPT3101 which seems to be able do 4000hz ? it apparently must use external LED or Laser and photodiode.
Can you use a VL6180X and VL53L0X together to cover a wider range of ranges? Or do they have to be aimed away from each other to hold down interference?
Brynn
LikeLike
I have not used the OPT3101, but that sounds an interesting sensor too. The data sheet of the VL53L0X says something about 20 ms timing budget for a ‘fast’ measurement and 200 ms for a ‘precicse’ measurement, so my guess is that is the max frequency the sensor offers. I did not try the VL6180X and VL53L0X together, and don’t see any specifics about the wavelength and pulses either. So it would be best to have them not aiming at the same object, or not doing measurements at the same time.
LikeLike
Hi Erich,
I have just started my journey with STM and really wanted to run VL53L0X on it. I Have bought the one from Pololu. Give me some advice please, is it possible to run your code on Atollic TrueStudio? What should I change? It seems that, many included libraries are not understanable for it (eg. “CS1.h”, “LED1.h”, “LEDpin1.h”). Are they necessary?\
Best for you!
LikeLike
The general answer is: yes, that is possible to run on STM and Atollic. But you will need to use the STM32Cube low level drivers instead of CS1, LED, etc.
The LED one is a driver for LEDs (you can omit that) plus the CS1 is code for critical sections.
And you will need the STM32 I2C driver of course too.
LikeLike