Skip to main content
frank1
Associate II
June 4, 2021
Solved

Cannot read distance after I2C address is changed. VL53L1X time of fight sensor

  • June 4, 2021
  • 2 replies
  • 1478 views

Hello,

I'm currently working with the VL53L1X distance sensor on the nRF52. I'd like to use two of them with te same i2c busses. Therefore, I need to change the address of one of these.

I have successfully used a single sensor (using the default address 0x29). Now I want to change the address of this sensor (still using a single sensor), but when I try to read the distance, I get error -13.

The I2C address is correctly changed, because i do get this new address when I read the I2C address buffer (0x0001). Also, my logic analyser confirms that the new i2c address is used, but the read/write command is not acknowledged (so no distance is read of cource).

I looked to the api and logic analyser results in more detail, and I added the following line in the function VL53L1_init_and_start_range() (from vl53l1_api_core.c):

if (i2c_index == 0x001 && buffer[0] == 0x29 && Dev->I2cDevAddr != 0x29) { buffer[0] = Dev->I2cDevAddr; }

(This line changes default i2c address (0x29) to the correct one, but only when data is written to the i2c index of the i2c_slave__device_address (0x0001))

This new line results in a success while reading the distance, but this should not be the correct way of doing this.

So my question is: What is going wrong after I changed the i2c address? And how can I fix this?

Also, is it possible to change the i2c address if I only use one vl531x?

if there is any information missing, please tell me.

This topic has been closed for replies.
Best answer by Julien NGUYEN

Hi Frank1

Please have a look on the example MultiSensorRanging in the X-CUBE-53L1A1 on st.com

Thanks

/* Reset the 3 ToF sensors on the expansion board */

for (ToFSensor=0;ToFSensor<3;ToFSensor++){

status = XNUCLEO53L1A1_ResetId(ToFSensor, 0);

}

/* Bring the sensors out of the reset stage one by one and set the new I2C address */

for (ToFSensor=0;ToFSensor<3;ToFSensor++){

switch(ToFSensor){

case 0:

Dev=&devLeft;

break;

case 1:

Dev=&devCenter;

break;

case 2:

Dev=&devRight;

break;

}

status = XNUCLEO53L1A1_ResetId(ToFSensor, 1);

Dev->comms_speed_khz = 400;

Dev->I2cHandle = &hi2c1;

Dev->comms_type = 1;

Dev->I2cDevAddr=0x52; /* default ToF sensor I2C address*/

VL53L1_RdWord(Dev, 0x010F, &wordData);

printf("VL53L1X: %02X\n\r", wordData);

newI2C = Dev->I2cDevAddr + (ToFSensor+1)*2;

status = VL53L1_SetDeviceAddress(Dev, newI2C);

Dev->I2cDevAddr=newI2C;

VL53L1_RdWord(Dev, 0x010F, &wordData);

printf("VL53L1X: %02X\n\r", wordData);

/* Device Initialization and setting */

status = VL53L1_WaitDeviceBooted(Dev);

status = VL53L1_DataInit(Dev);

status = VL53L1_StaticInit(Dev);

status = VL53L1_SetDistanceMode(Dev, VL53L1_DISTANCEMODE_SHORT);

status = VL53L1_SetMeasurementTimingBudgetMicroSeconds(Dev, 50000);

status = VL53L1_SetInterMeasurementPeriodMilliSeconds(Dev, 100);

}

2 replies

frank1
frank1Author
Associate II
June 7, 2021

I looked further into my problem, and apparently the LLData is not updated correct (at least regarding the i2c slave address).

To change the i2c address i use the function VL53L1_SetDeviceAddress() from vl53l1_api.c. Here, only the new i2c address is written to the device and no LLData is changed. Should I change this LLData myself, or should this be done automatically?

Julien NGUYEN
Julien NGUYENBest answer
ST Employee
June 7, 2021

Hi Frank1

Please have a look on the example MultiSensorRanging in the X-CUBE-53L1A1 on st.com

Thanks

/* Reset the 3 ToF sensors on the expansion board */

for (ToFSensor=0;ToFSensor<3;ToFSensor++){

status = XNUCLEO53L1A1_ResetId(ToFSensor, 0);

}

/* Bring the sensors out of the reset stage one by one and set the new I2C address */

for (ToFSensor=0;ToFSensor<3;ToFSensor++){

switch(ToFSensor){

case 0:

Dev=&devLeft;

break;

case 1:

Dev=&devCenter;

break;

case 2:

Dev=&devRight;

break;

}

status = XNUCLEO53L1A1_ResetId(ToFSensor, 1);

Dev->comms_speed_khz = 400;

Dev->I2cHandle = &hi2c1;

Dev->comms_type = 1;

Dev->I2cDevAddr=0x52; /* default ToF sensor I2C address*/

VL53L1_RdWord(Dev, 0x010F, &wordData);

printf("VL53L1X: %02X\n\r", wordData);

newI2C = Dev->I2cDevAddr + (ToFSensor+1)*2;

status = VL53L1_SetDeviceAddress(Dev, newI2C);

Dev->I2cDevAddr=newI2C;

VL53L1_RdWord(Dev, 0x010F, &wordData);

printf("VL53L1X: %02X\n\r", wordData);

/* Device Initialization and setting */

status = VL53L1_WaitDeviceBooted(Dev);

status = VL53L1_DataInit(Dev);

status = VL53L1_StaticInit(Dev);

status = VL53L1_SetDistanceMode(Dev, VL53L1_DISTANCEMODE_SHORT);

status = VL53L1_SetMeasurementTimingBudgetMicroSeconds(Dev, 50000);

status = VL53L1_SetInterMeasurementPeriodMilliSeconds(Dev, 100);

}

frank1
frank1Author
Associate II
June 8, 2021

Thank you for the answer.

I had set the address after "Device initialization and setting", but as your code shows it must be done before. I changed it and it is working now.