cancel
Showing results for 
Search instead for 
Did you mean: 

How to add VL53L0x drivers to STM32 Project

Ehsan Habib
Associate II

I need to simply add VL53L0x API STSW-IMG005 to my project without any compilation errors. And need to know the necessary functions to get the distance.

Regard

1 ACCEPTED SOLUTION

Accepted Solutions
John E KVAM
ST Employee

​The STSW-IMG005 software is an API containing all the calls you need to make - but it stops at the I2C call. You need to supply the platform layer between the I2C_read/write functions and your MCU. Refer to the platform.c file (which is where you put your functions).

Attached is a platform.c file I developed for an STM32 to give you the idea. Adapt it as you require.

As for what is in the main, try something like:

status=VL53L0X_StaticInit(&VL53L0XDevs[i]);
            if( status ){
                debug_printf("VL53L0X_StaticInit %d failed\n",i);
            }
 
            status = VL53L0X_PerformRefCalibration(&VL53L0XDevs[i], &VhvSettings, &PhaseCal);
			if( status ){
			   debug_printf("VL53L0X_PerformRefCalibration failed\n");
			}
 
			status = VL53L0X_PerformRefSpadManagement(&VL53L0XDevs[i], &refSpadCount, &isApertureSpads);
			if( status ){
			   debug_printf("VL53L0X_PerformRefSpadManagement failed\n");
			}
 
            status = VL53L0X_SetDeviceMode(&VL53L0XDevs[i], VL53L0X_DEVICEMODE_SINGLE_RANGING); // Setup in single ranging mode
            if( status ){
               debug_printf("VL53L0X_SetDeviceMode failed\n");
            }
 
            status = VL53L0X_SetLimitCheckEnable(&VL53L0XDevs[i], VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, 1); // Enable Sigma limit
			if( status ){
			   debug_printf("VL53L0X_SetLimitCheckEnable failed\n");
			}
 
			status = VL53L0X_SetLimitCheckEnable(&VL53L0XDevs[i], VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, 1); // Enable Signa limit
			if( status ){
			   debug_printf("VL53L0X_SetLimitCheckEnable failed\n");
			}

To set things up, then to run:

status = VL53L0X_PerformSingleRangingMeasurement(&VL53L0XDevs[SingleSensorNo],&RangingMeasurementData);
            if( status ==0 ){
            	/* Push data logging to UART */
            	trace_printf("%d,%u,%d,%d,%d\n", VL53L0XDevs[SingleSensorNo].Id, TimeStamp_Get(), RangingMeasurementData.RangeStatus, RangingMeasurementData.RangeMilliMeter, RangingMeasurementData.SignalRateRtnMegaCps);

But there are lots of ways to configure and run - so do read the user's guide


If this or any post solves your issue, please mark them as 'Accept as Solution' It really helps. And if you notice anything wrong do not hesitate to 'Report Inappropriate Content'. Someone will review it.

View solution in original post

7 REPLIES 7
S.Ma
Principal

Well, done that for the long range version starting from STSW-IMG009

Add to the project the following files:

+ VLxx_plateform.c/h

+ vlxx_types.h

+ vlxx_api.c/h

+ vlxx_calibration.c/h

In the plateform file, you'll have to implement the I2C HW driver function.

In my case, it's homecooked bitbang I2C by GPIO.

And on top of this, something like this:

I2C_SlaveDevice_t VL53L1SD = { &gI2C_STMod, 0x52, 0 };
I2C_SlaveDevice_t * pVL = &VL53L1SD;
 
 
VL53L1_Dev_t                   dev; // this is the structure
VL53L1_DEV                     Dev = &dev; // this is the pointer to the structure
VL53L1_Dev_t*                  pVL53L1 = &dev; // the cleaner version to use from now
uint8_t byteData;
uint16_t wordData;
 
 
 
int32_t VL53L1_Init(void) { NOPs(1); return 0;}
 
int32_t VL53L1_IsPlugged(void) {
  
  int status=0;
  
  pVL53L1->pSD = &VL53L1SD; 
  
/* Those basic I2C read functions can be used to check your own I2C functions */
  status = VL53L1_RdByte(&dev, 0x010F, &pVL53L1->ModelID); // printf("VL53L1X Model_ID: %X\n", byteData);
  status = VL53L1_RdByte(&dev, 0x0110, &pVL53L1->ModuleType); // printf("VL53L1X Module_Type: %X\n", byteData);
  status = VL53L1_RdWord(&dev, 0x010F, &wordData); // printf("VL53L1X: %X\n", wordData);
  while(pVL53L1->sensorState==0){
	status = VL53L1X_BootState(dev, &pVL53L1->sensorState);
	HAL_Delay(2);
  }
  
  /* This function must to be called */
  status = VL53L1X_SensorInit(dev);
 
  /* Optional functions to set specific parameters here before start ranging */
//  status = VL53L1X_SetDistanceMode(dev, 1); /* 1=short, 2=long */
//  status = VL53L1X_SetTimingBudgetInMs(dev, 100); /* in ms possible values [20, 50, 100, 200, 500] */
//  status = VL53L1X_SetInterMeasurementInMs(dev, 200); /* in ms, IM must be >= TB+ 5ms, otherwise IM*2 */
//  status = VL53L1X_SetOffset(dev,20); /* offset compensation in mm */
//  status = VL53L1X_SetROI(dev, 16, 16); /* minimum ROI 4,4 */
//	status = VL53L1X_CalibrateOffset(dev, 140, &offset); /* may take few second to perform the offset cal*/
//	status = VL53L1X_CalibrateXtalk(dev, 1000, &xtalk); /* may take few second to perform the xtalk cal */
//  printf("VL53L1X Ultra Lite Driver Example running ...\n");
  status = VL53L1X_StartRanging(dev);   /* This function has to be called to enable the ranging */
 
  return status;
}
 
 
int32_t VL53L1_50ms(void) {
 
  int status;
  uint8_t dataReady;
  
  status = VL53L1X_CheckForDataReady(dev, &dataReady);  
  if(dataReady == 0)
    return 0;
 
  HAL_Delay(2);
  status = VL53L1X_GetRangeStatus(dev, &pVL53L1->RangeStatus);
  status = VL53L1X_GetDistance(dev, &pVL53L1->Distance);
  status = VL53L1X_GetSignalRate(dev, &pVL53L1->SignalRate);
  status = VL53L1X_GetAmbientRate(dev, &pVL53L1->AmbientRate);
  status = VL53L1X_ClearInterrupt(dev); /* clear interrupt has to be called to enable next interrupt*/
  NOPs(1); // breakpoint hook point
  return status;
}
 
int32_t VL53L1_Report(ByteVein_t* pL) {
  
  BTEL_Printf(pL,"*A%d", pVL53L1->Distance); // distance in mm
  
  return 0;
}

 This version of the baseline code is Application Minded, no blocking function, poll method for "data ready" which by I2C takes less than 1 msec.

Previous implementation (IMG007) was blocking for long time, which wouldn't be practical beyond RTOS use.

I guess this is for VL53L1x 400 cm ToF. I have already used and implemented VL53L1x using the following method provided by digikey. Here is the link https://www.digikey.com/eewiki/display/microcontroller/Adding+the+VL53L1X+Driver+to+an+STM32Cube+Project. I have already tried using this method for VL53L0x 200 cm ToF but failed to compile it. It gives errors missing file "windows.h" etc.

S.Ma
Principal

No experience in VL53L0x, only VL53L1x running ok on STM32L4R5 bare metal.

John E KVAM
ST Employee

​The STSW-IMG005 software is an API containing all the calls you need to make - but it stops at the I2C call. You need to supply the platform layer between the I2C_read/write functions and your MCU. Refer to the platform.c file (which is where you put your functions).

Attached is a platform.c file I developed for an STM32 to give you the idea. Adapt it as you require.

As for what is in the main, try something like:

status=VL53L0X_StaticInit(&VL53L0XDevs[i]);
            if( status ){
                debug_printf("VL53L0X_StaticInit %d failed\n",i);
            }
 
            status = VL53L0X_PerformRefCalibration(&VL53L0XDevs[i], &VhvSettings, &PhaseCal);
			if( status ){
			   debug_printf("VL53L0X_PerformRefCalibration failed\n");
			}
 
			status = VL53L0X_PerformRefSpadManagement(&VL53L0XDevs[i], &refSpadCount, &isApertureSpads);
			if( status ){
			   debug_printf("VL53L0X_PerformRefSpadManagement failed\n");
			}
 
            status = VL53L0X_SetDeviceMode(&VL53L0XDevs[i], VL53L0X_DEVICEMODE_SINGLE_RANGING); // Setup in single ranging mode
            if( status ){
               debug_printf("VL53L0X_SetDeviceMode failed\n");
            }
 
            status = VL53L0X_SetLimitCheckEnable(&VL53L0XDevs[i], VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, 1); // Enable Sigma limit
			if( status ){
			   debug_printf("VL53L0X_SetLimitCheckEnable failed\n");
			}
 
			status = VL53L0X_SetLimitCheckEnable(&VL53L0XDevs[i], VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, 1); // Enable Signa limit
			if( status ){
			   debug_printf("VL53L0X_SetLimitCheckEnable failed\n");
			}

To set things up, then to run:

status = VL53L0X_PerformSingleRangingMeasurement(&VL53L0XDevs[SingleSensorNo],&RangingMeasurementData);
            if( status ==0 ){
            	/* Push data logging to UART */
            	trace_printf("%d,%u,%d,%d,%d\n", VL53L0XDevs[SingleSensorNo].Id, TimeStamp_Get(), RangingMeasurementData.RangeStatus, RangingMeasurementData.RangeMilliMeter, RangingMeasurementData.SignalRateRtnMegaCps);

But there are lots of ways to configure and run - so do read the user's guide


If this or any post solves your issue, please mark them as 'Accept as Solution' It really helps. And if you notice anything wrong do not hesitate to 'Report Inappropriate Content'. Someone will review it.

Thanks John for your reply. I need to know which files needs to add in the Code,along with platform.c . Cause their is a file called "vl53l0x_i2c_win_serial_comms", I don't think i need to add this file in my code right ??

Then their is this file "vl53l0x_platform_log" ,Do i need to add this file ???

So if possible just tell me the files name i need to add in the project.. And for your information i am using STM32F446ZET6 Nucleo Board for my Project. I am using CubeMx & True Studio

As delivered the code runs on a PC. I have no idea who chose that. It was an odd choice. You don’t need any “win�? files. The platform_log file is for logging. You can take that out and just use printf to debug. Enclosed is what my code structure looks like. Maybe that will help. [sensor2]VL53L1X – Time of Flight Sensor John KVAM | Tel: (408) 919-8502 | Mobile: (650) 521-2084 STMicroelectronics | 2755 Great America Way, 3rd Floor | Santa Clara, CA 95054 Introduction to Time-of-Flight<> and SensorExpo Time-of-Flight<>

If this or any post solves your issue, please mark them as 'Accept as Solution' It really helps. And if you notice anything wrong do not hesitate to 'Report Inappropriate Content'. Someone will review it.
Julien NGUYEN
ST Employee

​Hello Eshan,

It seems to me that you are familiar with STM32 Cube that you have used for VL53L1X. I would suggest you to use the same SW environment to run the VL53L0X, see link below.

https://www.st.com/en/ecosystems/x-cube-53l0a1.html

Thanks,

Julien


In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.