2019-10-31 06:13 AM
I recently purchased VL53L1X ToF laser ranging sensor and for the last couple of weeks I am trying to make it work. Based on reference schematic from the datasheet I built the following setup:
Using STM32L011 uCU, ULD API and LowLevel I2C libraries I am interfacing the sensor AND successfully reading/writing data from/to it. Here is a snippet of my communication to the sensor:
void LaserSense (void)
{
uint8_t sensorState = 0;
uint8_t byteData = 0;
uint16_t wordData = 0;
// Test I2C Communication.
status = VL53L1_RdByte(VL53L1X_ADDRESS, 0x010F, &byteData); //Model ID = 0xEA
status = VL53L1_RdByte(VL53L1X_ADDRESS, 0x0110, &byteData); //Module Type = 0xCC
status = VL53L1_RdByte(VL53L1X_ADDRESS, 0x0111, &byteData); //Mask Revision = 0x10
// End test I2C Communication.
// Reset Sensor
status = VL53L1_WrByte(VL53L1X_ADDRESS, SOFT_RESET, 0x00); //Reset
DelayMillisec(100);
status = VL53L1_WrByte(VL53L1X_ADDRESS, SOFT_RESET, 0x01); // Exit Reset
DelayMillisec(1000);
// Wait for device to boot. FixMe: Implement a timeout condition.
while((sensorState & 0x1) == 0)
{
status = VL53L1X_BootState(VL53L1X_ADDRESS, &sensorState);
DelayMillisec(100);
}
...Some more code...ommited for simplicity reasons...
}
Here are oscillograms of the I2C bus, for the code above:
READ Model ID:
READ Module Type:
READ Mask Revision:
WRITE Enter Reset Command:
WRITE Exit Reset Command:
READ Sensor Boot State:
From the oscillograms it is seen that the I2C communication is working.
The issue is that when I read the boot state internal register I am always receiving 0, which means that the device is not booted. This stops me from further device use.
Things I have tried so far:
2019-10-31 08:07 AM
One suggestion :
Use a status += VL53L1_ReadByte(...)
That little += on all your calls means you can stop your debugger at any point and see if there was ever an error. Then you just have to find it.
I do not do the soft reset. Bringing the XSDN high is enough. Try removing the reset
The fact that you can read the Chip ID means the chip is booted. So the BootState is a bit redundant. Although I use the code below.
while(sensorState==0){
status = VL53L1X_BootState(dev, &sensorState);
HAL_Delay(2);
}
What happens if you comment that out?
2019-10-31 08:22 AM
I tried to remove the reset and start directly with the check, but it just never gets out of the while, cos BootState() never returns 1. The hint with += would be useful, thanks.
// Wait for device to boot. FixMe: Implement a timeout condition.
while(sensorState == 0)
{
status = VL53L1X_BootState(VL53L1X_ADDRESS, &sensorState);
DelayMillisec(2000);
}
2019-11-20 08:36 AM
It's an I2C configuration error on the host MCU.
You have to check the status return to get a handle on it.
2020-09-14 02:42 AM
Hello.
I have a similar problem with VL53L1X. The difference is that VL53L1X always returns as boot state 0x03.
This is my code (I don's use ST's platform):
This is what I first read on the bus (chip ID 0xea, 0xcc, etc):
As John says above: 'The fact that you can read the Chip ID means the chip is booted'. However, I get the boot state = 0x03! What does this mean?
Regards
2020-09-14 07:52 AM
The bootstate register spec is:
[1] firmware_first_range: FW first range status
[0] firmware_bootup: FW initial boot status, Set by FW after completing initial coldboot.
I can only conjecture that you called this function after your device was already alive.
Perhaps you restarted your code without first powercycling the sensor?
At initial boot I'd expect a 0x1, then after a range, I'd expect a 0x3.
2020-09-15 12:46 AM
I resolved my issue and took me half a year to figure it out. Hope it helps you, too - The register address needs to be sent as 16-bit, NO MATTER IF ITS VALUE IS LESS THAN 0xFF e.g. on VL53L1X there is an address 0x0031 (which is < 0xFF) and needs to be sent as 16-bit address. It has to be padded with 1 byte of zeroes, so that [15:8] = 0x00 and [7:0] = 0x31.
2020-09-15 12:55 AM
Hello John, thanks for your quick response.
** I can only conjecture that you called this function after your device was already alive.
I don't think my device is alive because the code I posted above is executed immediatly after initializing I2C, timers and other MCU peripherals.
** Perhaps you restarted your code without first powercycling the sensor?
What exactly do you mean by "powercycling the sensor". I you mean pulling pin XSHUT first OFF and then ON, I do it immediatly before calling "VL53L1X_BootState()" and "i2c_readByte()", as you can see in my code.
Another thing I relized after writing the first post is the 100ms delay I used after XSHUT ON. Not using this delay the device returns bootstate = 0x02. What's the meaning of this?
2020-09-15 07:50 AM
Hardwariano,
Can I ask that you ask again on a different thread. This one is too long, and "Velizarw's" 'I figured it out' makes a fitting end.
But to answer your question, putting noise on the XShut line is really bad, the chip will start to shutdown, then come back up in a bad state and you have no idea where you are. So drop XSHUT, leave it off for a bit, then bring it back up.
I had problems with this register too. I think the documentation has it backwards.
So boot, read the register quickly, see what it reads a few millisec later, then range. With a little luck it will go from 0 to 2 to 3 after ranging.
2020-09-16 05:59 AM
Hi Velizarw, thanks for your response. I checked my code and I always send 16 bits as register address, so I have to keep investigating.
Thanks for your help