cancel
Showing results for 
Search instead for 
Did you mean: 

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

frank1
Associate II

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.

1 ACCEPTED SOLUTION

Accepted Solutions
Julien NGUYEN
ST Employee

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);

}


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.

View solution in original post

3 REPLIES 3
frank1
Associate II

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
ST Employee

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);

}


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.

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.