We will explain programming for simple distance measurement using VL53L1X, which can measure distances of up to 4 m by ToF (Time of Flight). We used the Full API officially provided by STMicroelectronics to use the VL53L1X. In this article, it is operated by STM32 microcomputer, but it can be ported to other platforms by applying the method introduced.
The VL53L1X is a ToF distance sensor with a size of 4.9 mm x 2.5 mm, which is an ultra-compact sensor. The maximum measurement distance is 4m, and since it can measure at 50Hz, it can be used in various applications (I use it for altitude control of small drones). Sold as a module at Akizuki Denshi and Switch Science There is also an Arduino library.
The operation was confirmed using the following hardware.
You need to download it from the linked page.
--PC: macOS Catalina (Windows and Linux can also be used)
We will introduce a simple method to measure the distance using the VL53L1X Full API. Also, the lightweight version ULD (Ultra Light Driver) can be used in the same way, so it is omitted.
Open main.c in Core / Src / main.c.
Write the include file before main.c. stdio.h was included to use printf.
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include "vl53l1_api.h"
/* USER CODE END Includes */
Next, prepare printf. I referred to Linked page. First, write the following code at the beginning of the main function.
/* USER CODE BEGIN 1 */
setbuf(stdout, NULL);
/* USER CODE END 1 */
In addition, define the __io_putchar function after main.c.
```c
/* USER CODE BEGIN 4 */
int __io_putchar(int ch) {
HAL_UART_Transmit(&huart2, (uint8_t*)&ch, 1, 1000);
return 0;
}
/* USER CODE END 4 */
```
Now you can use printf.
Next, write the process of distance measurement. I referred to SimpleRanging / Src / main.c of X-CUBE-53L1A1. First, the variable declaration and initialization processing are described.
/* USER CODE BEGIN 2 */
VL53L1_Dev_t dev;
VL53L1_DEV Dev = &dev;
int status = 0;
VL53L1_RangingMeasurementData_t RangingData;
Dev->I2cHandle = &hi2c1;
Dev->I2cDevAddr = 0x52;
status = VL53L1_WaitDeviceBooted(Dev);
status = VL53L1_DataInit(Dev);
status = VL53L1_StaticInit(Dev);
status = VL53L1_SetDistanceMode(Dev, VL53L1_DISTANCEMODE_LONG);
status = VL53L1_SetMeasurementTimingBudgetMicroSeconds(Dev, 50000);
status = VL53L1_SetInterMeasurementPeriodMilliSeconds(Dev, 500);
status = VL53L1_StartMeasurement(Dev);
/* USER CODE END 2 */
Next, the iterative process is described.
```c
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
status = VL53L1_WaitMeasurementDataReady(Dev);
if (!status) {
status = VL53L1_GetRangingMeasurementData(Dev, &RangingData);
if (status == 0) {
printf("%d\n", RangingData.RangeMilliMeter);
}
status = VL53L1_ClearInterruptAndStartMeasurement(Dev);
}
}
/* USER CODE END 3 */
```
If you build with this, you can check the distance data by serial communication.
As for the details of API, VL53L1X API_User_Manual_UM2356_rev2.pdf is in doc /, so I will leave it to that and explain only the parts that seem necessary.
The following three modes can be set by using the VL53L1_SetDistanceMode function. If you want to measure up to 4m, use LONG mode, and if you want to prioritize environmental resistance up to 1.3m, use SHORT mode.
The Timing budget is explained as follows.
The timing budget is defined as the programmed time needed by the sensor to perform and report ranging measurement data. During this time, the VCSEL is pulsed. An interrupt is raised or the date ready register is updated at the end of the timing budget.
The Inter-measurement period is explained as follows.
The inter-measurement period is defined as the programmed time between two consecutive measurements.
It is easy to understand by looking at the figure.
It can be interpreted that the Timing budget represents the time until the target is irradiated with the laser and the distance is measured, and the Inter-measurement period represents the measurement interval.
When I read the document, the values that can be set with VL53L1_SetMeasurementTimingBudgetMicroSeconds are from 20ms to 1000ms. In addition, VL53L1_SetInterMeasurementPeriodMilliSeconds is set to a value of Timing budget + 4ms or more.
As an example, when measuring at 20Hz (50ms), do as follows.
VL53L1_SetMeasurementTimingBudgetMicroSeconds(Dev, 46000);
VL53L1_SetInterMeasurementPeriodMilliSeconds(Dev, 50);
First, set the Inter-measurement period to 50 ms, and subtract 4 ms from the Inter-measurement period of the Timing budget to convert it to microseconds.
Detailed data of distance measurement is stored in the VL53L1_RangingMeasurementData_t structure. Most of them are not needed, but distance data can be obtained by accessing RangeMilliMeter, which is a member of the structure.
If the sensor does not work well, check the status value. Since the error code is defined in api / core / vl53l1_error_codes.h, you can check which error corresponds to.
We explained the programming of distance measurement using the ultra-small distance sensor VL53L1X. Detailed information can be obtained from the official user manual and the Example project, so please refer to it. If you have any questions or deficiencies in the content, please leave a comment.
Recommended Posts