cancel
Showing results for 
Search instead for 
Did you mean: 

Hello, I'm working with the VL53L0CX on a project with a STM32F437 and I would like to import the API. I check in the software pack in STM32CubeIDE but I only found for VL53L1-3-4-5-7. How can I find the one for the L0, is this possible this way ?

GCout.1
Associate II

Thank you for your help.

7 REPLIES 7
Peter BENSCH
ST Employee

Welcome, @GCout.1​, to the community!

Not all previous software packages can be installed in STM32CubeIDE in this way, but older ones can be added manually. For the VL53L0CX you can find the corresponding library under STSW-IMG005.

Hope that helps?

Regards

/Peter

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.
GCout.1
Associate II

Hello,

Thank you for your answer. I put the API into my project and I had some problem with the include from the APE. First I had windows.h and other .h that were not found. I found these inside " C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\... " that I include in the path of the project.

After that, I had files vcruntime.h and vadefs.h that were not found. I try to include " C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.35.32215\include " but it created errors on all my code : "declaration for parameter '__blkcnt_t' but no such parameter"

Have you a solution to easily integrate the API or to solve the problem ?

Thank you,

John E KVAM
ST Employee

The VL53L0X is a fine sensor. But it was our first 940nm sensor, and we've learned a lot since that one came out.

Consider the VL53L4CD. It's cheaper. The code is easier. Granted the max distance is 1.3M vs the L0's 2Meters, but the effective distance at which you can see people is nearly identical. The L0 does have a wider Field of View - at 27 degrees instead of 18 degrees.

But lets assume you have your reasons for chosing the L0. And I can solve your issues.

As delivered the L0 interfaces to a PC. This was the worst choice imaginable. (I told you we learned a lot.)

The main software all calls functions in the Platform.c file. It is this file that needs to be interface between the sensor and the MCU.

Throw away the platform.c file you have and extract the one from the L4. It's configured to run with an STM32.

The code will look like this:

	/**
  ******************************************************************************
  * @file    platform.c
  * @author  IMG SW Application Team
  * @brief   This file contains all the platform functions prototypes
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
 
#include "vl53l4cd_api.h"
 
/* when not customized by application define dummy one */
#ifndef VL53L4CD_GetI2cBus
/** This macro can be overloaded by user to enforce i2c sharing in RTOS context
 */
#define VL53L4CD_GetI2cBus(...) (void)0
#endif
 
#ifndef VL53L4CD_PutI2cBus
/** This macro can be overloaded by user to enforce i2c sharing in RTOS context
 */
#define VL53L4CD_PutI2cBus(...) (void)0
#endif
 
uint8_t _I2CBuffer[256];
 
/* Private functions prototypes */
 
static int _I2CWrite(Dev_t Dev, uint8_t *pdata, uint32_t count) {
	return Dev->IO.WriteReg(Dev->IO.Address, pdata, count);
}
 
static int _I2CRead(Dev_t Dev, uint8_t *pdata, uint32_t count) {
	return Dev->IO.ReadReg(Dev->IO.Address, pdata, count);
}
 
uint8_t VL53L4CD_WrByte(Dev_t Dev, uint16_t index, uint8_t data) {
    uint8_t Status = VL53L4CD_ERROR_NONE;
    int32_t status_int;
 
    _I2CBuffer[0] = index>>8;
    _I2CBuffer[1] = index&0xFF;
    _I2CBuffer[2] = data;
 
    VL53L4CD_GetI2cBus();
    status_int = _I2CWrite(Dev, _I2CBuffer, 3);
    if (status_int != 0) {
        Status = status_int;
    }
    VL53L4CD_PutI2cBus();
    return Status;
}
 
uint8_t VL53L4CD_WrWord(Dev_t Dev, uint16_t index, uint16_t data) {
    uint8_t Status = VL53L4CD_ERROR_NONE;
    int32_t status_int;
 
    _I2CBuffer[0] = index>>8;
    _I2CBuffer[1] = index&0xFF;
    _I2CBuffer[2] = data >> 8;
    _I2CBuffer[3] = data & 0x00FF;
 
    VL53L4CD_GetI2cBus();
    status_int = _I2CWrite(Dev, _I2CBuffer, 4);
    if (status_int != 0) {
        Status = status_int;
    }
    VL53L4CD_PutI2cBus();
    return Status;
}
 
uint8_t VL53L4CD_WrDWord(Dev_t Dev, uint16_t index, uint32_t data) {
    uint8_t Status = VL53L4CD_ERROR_NONE;
    int32_t status_int;
    _I2CBuffer[0] = index>>8;
    _I2CBuffer[1] = index&0xFF;
    _I2CBuffer[2] = (data >> 24) & 0xFF;
    _I2CBuffer[3] = (data >> 16) & 0xFF;
    _I2CBuffer[4] = (data >> 8)  & 0xFF;
    _I2CBuffer[5] = (data >> 0 ) & 0xFF;
    VL53L4CD_GetI2cBus();
    status_int = _I2CWrite(Dev, _I2CBuffer, 6);
    if (status_int != 0) {
        Status = status_int;
    }
    VL53L4CD_PutI2cBus();
    return Status;
}
 
uint8_t VL53L4CD_RdByte(Dev_t Dev, uint16_t index, uint8_t *data) {
    uint8_t Status = VL53L4CD_ERROR_NONE;
    int32_t status_int;
 
	_I2CBuffer[0] = index>>8;
	_I2CBuffer[1] = index&0xFF;
    VL53L4CD_GetI2cBus();
    status_int = _I2CWrite(Dev, _I2CBuffer, 2);
    if( status_int ){
        Status = status_int;
        goto done;
    }
    status_int = _I2CRead(Dev, data, 1);
    if (status_int != 0) {
        Status = status_int;
    }
done:
    VL53L4CD_PutI2cBus();
    return Status;
}
 
uint8_t VL53L4CD_RdWord(Dev_t Dev, uint16_t index, uint16_t *data) {
    uint8_t Status = VL53L4CD_ERROR_NONE;
    int32_t status_int;
 
    _I2CBuffer[0] = index>>8;
	_I2CBuffer[1] = index&0xFF;
    VL53L4CD_GetI2cBus();
    status_int = _I2CWrite(Dev, _I2CBuffer, 2);
 
    if( status_int ){
        Status = status_int;
        goto done;
    }
    status_int = _I2CRead(Dev, _I2CBuffer, 2);
    if (status_int != 0) {
        Status = status_int;
        goto done;
    }
 
    *data = ((uint16_t)_I2CBuffer[0]<<8) + (uint16_t)_I2CBuffer[1];
done:
    VL53L4CD_PutI2cBus();
    return Status;
}
 
uint8_t VL53L4CD_RdDWord(Dev_t Dev, uint16_t index, uint32_t *data) {
    uint8_t Status = VL53L4CD_ERROR_NONE;
    int32_t status_int;
 
    _I2CBuffer[0] = index>>8;
	_I2CBuffer[1] = index&0xFF;
    VL53L4CD_GetI2cBus();
    status_int = _I2CWrite(Dev, _I2CBuffer, 2);
    if (status_int != 0) {
        Status = status_int;
        goto done;
    }
    status_int = _I2CRead(Dev, _I2CBuffer, 4);
    if (status_int != 0) {
        Status = status_int;
        goto done;
    }
 
    *data = ((uint32_t)_I2CBuffer[0]<<24) + ((uint32_t)_I2CBuffer[1]<<16) + ((uint32_t)_I2CBuffer[2]<<8) + (uint32_t)_I2CBuffer[3];
 
done:
    VL53L4CD_PutI2cBus();
    return Status;
}
 
uint8_t WaitMs(
		Dev_t Dev,
		uint32_t TimeMs)
{
  uint32_t tickstart;
  tickstart = Dev->IO.GetTick();
 
  while ((Dev->IO.GetTick() - tickstart) < TimeMs);
 
  return 0;
}

Notice it takes the I2C read/writes and calls the STM32 hardware functions.

Plumb that in. (There is also a platform.h file you need.)

To get this, download the VL53L4CD API and dig though the files. But be a little careful. As delivered there is an empty platfrom.c file for those who are NOT using an STM32 and a populated one in the exampes that runs on an STM32.

Good luck,

  • john

Our community relies on fruitful exchanges and good quality content. You can thank and reward helpful and positive contributions by marking them as 'Accept as Solution'. When marking a solution, make sure it answers your original question or issue that you raised.

ST Employees that act as moderators have the right to accept the solution, judging by their expertise. This helps other community members identify useful discussions and refrain from raising the same question. If you notice any false behavior or abuse of the action, do not hesitate to 'Report Inappropriate Content'
GCout.1
Associate II

Thank you for your answer. I was checking with the code of the L3. I will take the L4's one then.

Once I took the L4 platform.c functions, I should just create Dev->IO with the I2C function (and other information) and init the device. (VL53L3CX_RegisterBusIO() and VL53LX_DataInit(pObj)) ?

Kind regards,

Guillaume

John E KVAM
ST Employee

The platform files for the L3 and L4 should be nearly identical. And yes, that should work!

  • john

Our community relies on fruitful exchanges and good quality content. You can thank and reward helpful and positive contributions by marking them as 'Accept as Solution'. When marking a solution, make sure it answers your original question or issue that you raised.

ST Employees that act as moderators have the right to accept the solution, judging by their expertise. This helps other community members identify useful discussions and refrain from raising the same question. If you notice any false behavior or abuse of the action, do not hesitate to 'Report Inappropriate Content'
GCout.1
Associate II

Hello,

We will switch to the L4 in this case.

We are working on distance from 25cm to 4-5cm. The performance between L0 and L4 are more or less the same in these cases ? What is the difference between CD and CX version ?

Kind regards,

John E KVAM
ST Employee

Quick note on differences.

The L3 has a field of View of 27 degrees and can see farther. It uses histograms.

The L4 has a field of View of 18 degrees.

The more narrow FOV helps with close distance linearity. You want that. It has no histograms.

The L4CD is our least expensive ToF device. It's effective range is 1.3 meters. (Also max range.)

the L4CD runs autonomously. The L4CD driver is the smallest.

The L4CX uses Histograms. And with Histogram processing, one can 'see' farther. But the histograms are processed in your MCU, so it will not run autonomously. The driver is larger than the L4CD. (It's the same as the L3 driver.)

The L4CX is a superset of the L4CD.

To range from a 0 to 25cm, you really want the L4CD.


Our community relies on fruitful exchanges and good quality content. You can thank and reward helpful and positive contributions by marking them as 'Accept as Solution'. When marking a solution, make sure it answers your original question or issue that you raised.

ST Employees that act as moderators have the right to accept the solution, judging by their expertise. This helps other community members identify useful discussions and refrain from raising the same question. If you notice any false behavior or abuse of the action, do not hesitate to 'Report Inappropriate Content'