2021-06-04 07:58 AM
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.
Solved! Go to Solution.
2021-06-07 07:40 AM
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);
}
2021-06-07 01:30 AM
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?
2021-06-07 07:40 AM
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);
}
2021-06-08 01:53 AM
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.