Hi,
we are trying to use your vl53l8cx carrier board connected on I2C bus of a NUCLEO L496ZG.
Unlikely other I2C peripherals, we are issuing some bad behavior.
The I2C bus is dedicated to this board only (no other devices with different address are connected to it)
When we start a I2C WRITE to device, it HANGS immediatly and causes drop of voltage on SCL and SDA lines.
If we disconnect the device from bus, the lines are driven correctly.
Please see attached pictures
Can you post the code you are using along with some pictures that show all of your physical connections, including close-ups showing both sides of the VL53L8CX carrier?
One thing you might try right away is using shorter wires. As we note on the product page, the level shifter on this board is more sensitive to external loads than the circuit we typically use, so we recommend taking extra care to keep connected communication wires short (ideally under 3 inches or 8 cm). How long are the ones you are using?
It’s not very easy to check your connections from those pictures, so could you list what pins each wire is connected to (on both the Nucleo and the VL53L8CX board)?
For I2C communication, the SPI/I2C pin should be driven or tied low (connected to GND), and LP should be driven or tied high (or you can leave it disconnected for now since it’s pulled up by the board). Can you confirm that is how you have those two pins set up?
Hi Kevin, you’re right: the pics are a mess, but the shorter the connectors, the more difficult is to “make space”. So I’ll resume connections (see details in attached pics):
VIN connected to V3.3 on connector C8
GND connected to GND on connector C8
SCL connected to PB_8 (I2C_SCL) on connector C7
SDA connected to PB_9 (I2C_SDA) on connector C7
LP connected to PA_5 (GPIO_OUT) on connector C7 (driven HIGH)
SPI/I2C connected to PA_4 (GPIO_OUT) on connector C7 (driven LOW)
CS connected to PB_15 (GPIO_OUT) on connector C7 (driven LOW)
actually at startup we perform a RESET sequence on PA_4 (LOW-HIG-LOW), in order to reset I2C interface, as reported on datasheet.
Follows initialization code sequence
Since we are in testing phase, could you suggest us other similar devices? We have to detect some object’ positioning/presence (within 20-30 cm)
I saw there are vl53l7 and vl53l5…
Your connections and initialization seem okay to me. Have you been able to communicate with other I2C devices successfully with that Nucleo board?
I am not familiar with the Nucleo L496ZG, but if it is compatible with Arduino code, you could try the STM32duino VL53L8CX library and its examples to see if they work any better for you.
As for comparable sensors, the VL53L5CX and VL53L7CX are the most similar to the VL53L8CX; they differ from each other mainly in their field of view. You might find the comparison table on our ST ToF sensor carrier category page helpful. It’s possible your issue is being caused by the level shifter on our VL53L8CX carrier, which is more sensitive to external loads than the circuit we use on most of our other boards (although your setup doesn’t seem like it should be problematic), so trying a different sensor board could help determine if that’s the case.
Hi Kevin,
we changed sensor’s board and switched to vl53l5cx. Now the I2C communication is working well, and driver can correctly initialize. The problem now is in polling loop:
the function vl53l5cx_check_data_ready set always flag isReady to zero, even if communication occurs correctly (I suppose received data are not as expected).
A probe on INT pin shows it is raised.
Here the loop code:
void vl53l5_loop()
{
/* Use polling function to know when a new measurement is ready.
* Another way can be to wait for HW interrupt raised on PIN A3
* (GPIO 1) when a new measurement is ready */
Status = vl53l5cx_check_data_ready(&Dev, &isReady);
if(isReady)
{
vl53l5cx_get_ranging_data(&Dev, &Results);
/* As the sensor is set in 4x4 mode by default, we have a total
* of 16 zones to print. For this example, only the data of first zone are
* print */
printf("Print data no : %3u\n", Dev.streamcount);
for(i = 0; i < 16; i++)
{
printf("Zone : %3d, Status : %3u, Distance : %4d mm\n",
i,
Results.target_status[VL53L5CX_NB_TARGET_PER_ZONE*i],
Results.distance_mm[VL53L5CX_NB_TARGET_PER_ZONE*i]);
}
printf("\n");
}
/* Wait a few ms to avoid too high polling (function in platform
* file, not in API) */
VL53L5CX_WaitMs(&(Dev.platform), 5);
}
Now I’ll try to connect a serial to collect printf output, in order to have more debug info.
Hi again, Kevin.
The problem is that vl53l5cx_init() fails with status == 1. It means that timeout is exceeded when _vl53l5cx_poll_for_answer is issued. Timeout is set to 2s. I’ve raised to 10s but it still expires.
Any idea about how to unlock this?
Thanks
Enrico
What implementation of the VL53L5CX API are you using, and is your main program an example that you found or one that you wrote yourself? If you wrote it yourself, can you post the full program as an attachment (or a simplified version that demonstrates the issue)? How did you determine that _vl53l5cx_poll_for_answer() is causing the problem (and which instance is it, since that function is called multiple times from vl53l5cx_init())?
Also, can you show some pictures of your new board and setup so that I can check them again?
I’ve downloaded the library from ST download page
I’ve copied the initialization and loop from example1_range_basic.c source file
With STM32 Cube IDE I’ve put a breakpoint in _vl53l5cx_pool_for_answer at line 41 when timeout expires (vl53l5cx_api.c) where timeout error flag is set.
The instance where this happens in vl53l5cx_init is at line 277 when sensor is rebooted after 1st SW reboot sequence.
The I2C communication now seems working, since all read/write commands returns HAL_OK.
I’ll send you some pictures on next post.
I’ve connected VIN to 3.3V, I2C_RST is connected to a gpio driven LOW, while LPn to a gpio driven HIGH.
Hi, I’ve had some improvements, reviewing implementation of Read/Write functions.
Now the _vl53l5cx_pool_for_answer does not lock anymore.
The initialization goest through until the FW flashing, where it returns an error in transmission.
/* Download FW into VL53L5 */
status |= VL53L5CX_WrByte(&(p_dev->platform), 0x7fff, 0x09);
status |= VL53L5CX_WrMulti(&(p_dev->platform),0,
(uint8_t*)&VL53L5CX_FIRMWARE[0],0x8000);
status |= VL53L5CX_WrByte(&(p_dev->platform), 0x7fff, 0x0a);
status |= VL53L5CX_WrMulti(&(p_dev->platform),0,
(uint8_t*)&VL53L5CX_FIRMWARE[0x8000],0x8000);
status |= VL53L5CX_WrByte(&(p_dev->platform), 0x7fff, 0x0b);
status |= VL53L5CX_WrMulti(&(p_dev->platform),0,
(uint8_t*)&VL53L5CX_FIRMWARE[0x10000],0x5000);
status |= VL53L5CX_WrByte(&(p_dev->platform), 0x7fff, 0x01);
/* Check if FW correctly downloaded */
status |= VL53L5CX_WrByte(&(p_dev->platform), 0x7fff, 0x02);
status |= VL53L5CX_WrByte(&(p_dev->platform), 0x03, 0x0D);
status |= VL53L5CX_WrByte(&(p_dev->platform), 0x7fff, 0x01);
status |= _vl53l5cx_poll_for_answer(p_dev, 1, 0, 0x21, 0x10, 0x10);
if(status != (uint8_t)0){
goto exit;
}
The 1st write multi returns status!=0 (0xFF) hence initialization fails
Please let me share how platform.c is implemented, since I suspect it fails transmitting huge arrays of data on I2C vl53l5cx_platform.c (3.6 KB)
Hi Kevin, good news!
I could get rid of this: found an existing implementation of platform part for STM, and actually was wrong the implementation. Both WriteMulti and ReadMulti, were not working. Here the correct implementation
Now the sensors initializes and runs correctlry.
Thanks for your support!
Enrico