cancel
Showing results for 
Search instead for 
Did you mean: 

Ported VL53L0X Pololu code to STM32 - Always times out, can't find error!

Adam Halliwell
Associate II
Posted on May 29, 2018 at 04:06

Hi all

In lieu of the VL53L0X API being so awkward to use, I've made an effort to port the Pololu version of the VL53L0X library to STM32-compatible C code, using HAL functions to manage I2C communication.

Using an STM32F072RB board, with fast mode I2C (400KHz) and the 'D3' pin as XSHUT1, the setup and operation of the sensor in main.c goes as follows (removed surrounding code for readability)

VL53L0X sensor1;
char msg[64];
main()
{
setup_VL53L0X(&sensor1);
HAL_GPIO_WritePin(XSHUT1_GPIO_Port, XSHUT1_Pin,false);
 HAL_Delay(100);
HAL_GPIO_WritePin(XSHUT1_GPIO_Port, XSHUT1_Pin,true);
 HAL_Delay(20);
if(!init(&sensor1,true))
 {
 snprintf(msg,sizeof(msg),'Failed to initialize\r\n');
 HAL_UART_Transmit(UART, (uint8_t*)msg, strlen(msg), 0xFFFF);
 }
 else
 {
 snprintf(msg,sizeof(msg),'Successfully initialized\r\n');
 HAL_UART_Transmit(UART, (uint8_t*)msg, strlen(msg), 0xFFFF);
 }
setTimeout(&sensor1,500);
 startContinuous(&sensor1,0);
while(1)
{
snprintf(msg,sizeof(msg),'Read value: %u\r\n');//,readRangeContinuousMillimeters(&sensor1));
 HAL_UART_Transmit(UART, (uint8_t*)msg, strlen(msg), 0xFFFF);
}
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Unfortunately the function readRangeContinuousMillimeters(...) always returns a timeout (65536), as if the sensor is never initialised to read continuously (but, as shown in the code, it definitely is). Furthermore, reading WHO_AM_I always returns 0xEE which is correct and proves that the I2C bus is working.

Every function in the VL53L0X library has been ported over appropriately, and I've scanned every line of code to try and find the source of the problem. However, zero luck as of yet.

I have attached both the Pololu and my own version of the VL53L0X library, plus a custom I2C library which makes use of HAL functions, and the full main.c of this project.

If anyone is able to play spot-the-difference in order to get this working I'd be eternally grateful, as I'm completely stumped. Not that it's much in return, but this code is free for anyone to use if they can get it working.

Cheers

#port #vl53l0x
28 REPLIES 28

@AMaci.14​  I never had the 20-second problem, but it seems like it's common to the code provided by vitalij.zhurik. How did you solve it? @Mahdi Bayati​ has the same problem you did.

Practically, after some tests I figured out that it wasn't a 20 seconds. If I wanted to measure a large distance, I had got that 65536. 

However, in the library you can find "writeReg" function which writes an uint8_t value in the register. If this value is grater 255 (max uint8_t), the value will be segmented and in register will arive a wrong value. You can find in library other functions which resolve this problem, such as: writeReg16Bit, writeReg32Bit. A quicker solution (which I implemented) is to make a condition in "writeReg": 

void writeReg(VL53L0X * lidar,uint8_t reg, uint8_t value)

{

if (value > 255)

writeByte(I2C,lidar->address,reg,255);

else

writeByte(I2C,lidar->address,reg,value);

lidar->last_status = 0;

}

In this case, I think you will not receive a correct value for large distance. I proposed myself to make more some tests to understand better

Dear all

I observed the same 20-second trouble with the library provided by vitalij.

I decided to modify the library originally developed for the STM32duino.

Please find attached a functional library. I tested it with a Nucleo-L476RG board and a VL53L0X sensor.

XShut pin is connected to PC8 pin. I2C1 via PB8(SCL) and PB9(SDA) pins is used for communication.

Enjoy

JC

Thank you for your support. I have a question about that XShut pin from VL53L0X. Could I develop without the VL53L0X reset through XShut? I tried without restarting the sensor, but I couldn't communicate with the sensor after the first build. I suppose the driver is implemented to wait some flag from the sensor after it is restarted.

Dear Alexandru

I try to help hobbies like me. I have also developed small tutorials for my students.

https://community.st.com/s/group/0F90X000000AXupSAG/inp-phelma-grenoble

The initialization of the VL53L0X takes place in the function VL53L0X_InitSensor. It starts with a shutdown followed by a 100ms delay and then a restart and a 100ms delay using the XSHUT pin. The presence of the sensor is then detected. In case of a problem, the function returns -1.

I think that this hardware initialization phase is mandatory for the sensor to be in a stable state.

Bye

BDomi
Associate II

Bonjour Jean-Christophe,

Je travaille sur STM32L476 Nucleo avec µphone PDM/DFSDM et également sur STM32F469 Discovery, carte sur laquelle se souhaite implémenter ton super projet.

Je suis un (vieux) copain d'Erwan Le-Saint, je travaille à l'INRS.

Bien cordialement.

Bonjour Dominique

Tiens-moi au courant.

Bien cordialement

JC

BDomi
Associate II

Bonjour Jean-Christophe,

Réponse rapide pour un prof qui doit être encore en vacances...

Je souhaite utiliser la carte "Flow breakout" de SeeedStudio avec son VL53L0X mais également son PWM3901 (optical flow motion).

Je n'ai pas trouvé de projet porté sur STM32 (HAL) à partir de sa bibliothèque Arduino,

Peut-être connais tu quelqu'un qui l'a réalisé et pas encore publié ... :>)

Bonne reprise scolaire

Dominique

BDomi
Associate II

Bonjour Jean-Christophe,

J'espère que tu vas bien ainsi que tes proches dans cette période difficile.

Hier, je t'ai envoyé un mail sur ta messagerie NEEL, je suppose que ton temps est précieux et que tu dois gérer beaucoup d'urgences.

J'ai terminé l'implémentation du PWM3901 (optical flow motion) platine "flowBreakout" sur STM32F469 Discovery, j'ai été agréablement surpris par ses performances (linéarité et vitesse maxi de tracking).

Cela fait 1 semaine que je travaille sur ton code VL53L0X , j'ai résolu un problème d'adressage I2C, pour mon F469, il ne faut pas réalisé le décalage d'un bit vers la gauche dans VL53L0X_I2CRead(). Après correction, la fonction "VL53L0X_Start()" s'exécute normalement.

J'ai un autre bug que je ne parviens pas à résoudre : l'exécution de "VL53L0X_GetDistance()" génère un timeout après 4 s dans VL53L0X_measurement_poll_for_completion() après les 2000 tentatives de 2ms infructueuses.

Configuration de mon GPIO : XSHUT sur PG10, GPIO1 non connecté car le pcb de ma platine "flowBreakout" n'est pas routée.

Merci pour ton aide.

Bonjour Dominique

Je suis directeur adjoint de Phelma et je ne chôme pas en ce moment. Mes étudiants en projets de fin d'étude sont des situations critiques.

Je t'avouerai que cela fait longtemps que j'ai travaillé sur le module VL53L0X en I2C.

Comme tu le sais, avec l'I2C, on peut avoir des mauvaises surprises du style : le capteur est reconnu mais les signaux I2C ne sont pas stables.

Il faut d'abord vérifier les 2 résistances de pull-up (10 kOhms) sur SDA et SDC. Quitte à les rajouter sur une breadboard.

As-tu accès à un analyseur logique pour vérifier les trames I2C?

Je viens de m'apercevoir que j'ai testé la librairie avec une STM32L4 et non une F4 (normalement HAL est plus fiable)

Je te joins le lien sur le module que j'ai acheté

https://fr.aliexpress.com/item/32828144370.html?spm=a2g0s.9042311.0.0.27426c372fevjx clique sur le 2eme choix.

De mémoire dans mes essais, la pin GPIO1 n'est pas utilisée.

Je n'ai pas à ma position une STM32F469 Discovery mais à une Nucleo-F411RE.

Si je trouve le temps, j'essaierai de tester la librairie sur ma Nucleo-F4.

Merci à toi

JC