cancel
Showing results for 
Search instead for 
Did you mean: 

The tof chip anomaly after a long period of non-use

Blue666
Associate II

I discovered a strange phenomenon:

After I powered on the VL53L4CD, I called the interfaces:

The interfaces such as VL53L4CD_SensorInit, VL53L4CD_SetRangeTiming, VL53L4CD_SetDetectionThresholds, and VL53L4CD_SetSignalThreshold complete the initialization operation.

Then call the VL53L4CD_ClearInterrupt and VL53L4CD_StartRanging interfaces to start the measurement. At this time, interrupts can be received normally, and the interrupt pin can rise and fall normally.

At this point, I call the VL53L4CD_StopRanging interface to stop the measurement. At this time, tthe interrupt pin is at a high level.

At this point, I put the device aside without operating it for about two or three days.

I recalled VL53L4CD_ClearInterrupt and VL53L4CD_StartRanging, and immediately received an interrupt. At this time, I called the VL53L4CD_GetResult and VL53L4CD_ClearInterrupt  interface to read the result and found that the value of range_status was 2.

Subsequently, the interrupt pin remained at a low level. I kept calling VL53L4CD_ClearInterrupt, VL53L4CD_StartRanging, and VL53L4CD_StopRanging, but the interrupt pin would not be raised again. Only after setting the xshut pin to low level, turn off the VL53L4CD chip, the interrupt pin will be a high level.

This phenomenon is not certain to occur, but there is a probability of it happening. Could you help me figure out the reason for this? I confirm that the execution mode of the VL53L4CD_StopRanging interface is VL53L4CD_WrByte(dev, VL53L4CD_SYSTEM_START, 0x80).

I repeatedly called to start ranging and stop ranging, and the interrupt pin was normal. So, could it be that there was a problem with the chip's own state after being placed for a long time?

These are the register values read under normal and abnormal conditions, in the attachment.

Could you help me check what the problem is.

 

13 REPLIES 13
Blue666
Associate II

Blue666_0-1749732506106.png

As shown in the figure, VL53L4CD_ClearInterrupt was called, but the interrupt pin still is at a low level. I have tried that under normal circumstances, after calling VL53L4CD_ClearInterrupt, the interrupt pin will become high level

John E KVAM
ST Employee

I think I've seen that. There is a trick. One has to clear the interrupt, then issue the stop command. If you issue the clear interrupt while the ranging engine is stopped the engine is not paying attention and you end up in this situation. 

But it's trickier than that. Unless you have the absolute latest driver the stop as implemented is "stop after the current range completes". And that could be 20ms AFTER you issue the stop command. And after that last range, the interrupt will be triggered, and you can't clear it - because the engine is now stopped.

The solution is to get the latest driver. We implemented the stop as "abort the current range and stop."

Thus, you can get the interrupt, read the data, clear the interrupt and 'STOP NOW'. The engine will halt without completion of the current range, and it will not trigger that last interrupt. 

In the older driver is the function:

uint8_t VL53L4CD_ULP_StopRanging(
		uint16_t dev)
{
	uint8_t status = VL53L4CD_ULP_ERROR_NONE;

	status |= VL53L4CD_ULP_WrByte(dev, VL53L4CD_ULP_SYSTEM_START, 0x00);
	return status;

But you really want:

uint8_t VL53L4CD_ULP_StopRanging(
		uint16_t dev)
{
	uint8_t status = VL53L4CD_ULP_ERROR_NONE;

	status |= VL53L4CD_ULP_WrByte(dev, VL53L4CD_ULP_SYSTEM_START, 0x80); // abort current range
	return status;

I think that's the only change in Version 2.2.2 of the VL54L4CD Ultra Lite Driver but download the latest and prove me right. 

That bug has been in the code for 5 years and you are only the second guy to spot it - and complain.

(I'm pretty embarrassed about it actually.)

- john

 


If this or any post solves your issue, please mark them as 'Accept as Solution' It really helps. And if you notice anything wrong do not hesitate to 'Report Inappropriate Content'. Someone will review it.

Thank you for your reply.

In fact, I have already used the latest version of the driver.

As you said, if VL53L4CD_ULP_WrByte(dev, VL53L4CD_ULP_SYSTEM_START, 0x80) is used, is it necessary to clean before sending the stop instruction?

The strangest thing now is that when this phenomenon occurs, every time I first get a result with rang_status of 2, then the interrupt pin remains low level all the time, and at this time the VL53L4CD is in the ranging state. However, when I call the VL53L4CD_ClearInterrupt interface, it has no effect.

And I can ensure that after the stop, the interrupt pin is at a high level, indicating that there is no data at present. However, after a long period of non-use, this problem was discovered.

There is still one confusion. According to your answer, after calling the stop interface, the VL53L4CD_ClearInterrupt interface should be ineffective. However, I conducted an experiment before. The interrupt is triggered, and at this point, the high level changes to the low level, I did not call the VL53L4CD_ClearInterrupt interface and kept the interrupt pin at a low level all the time. Then call the stop interface. At this time, the interrupt pin also remains at a low level all the time. However, when I call the VL53L4CD_ClearInterrupt interface, the interrupt pin will be at a high level. This seems to be inconsistent with your description.

 

I have reproduced this problem again and would like to describe my discovery to you:

By default, the value of the 0x30 register is 0x11. When there is a problem, the interrupt pin is always low level. If I rewrite the register at this time, changing the 0x30 register to 0x10, the interrupt pin will immediately become high level.

(2) When I call the start and stop interface, I found that the VL53L4CD would send light and stop sending light.

(3) The relevant registers in the VL53L4CD_GetResult interface are changing, indicating that distance measurement is taking place.

Based on the above phenomena, I think the VL53L4CD itself has ranging. It seems that the function related to VL53L4CD_ClearInterrupt is abnormal. Could it be that the processing logic of the VL54L4CD is abnormal?

I hope someone can take a look at this issue for me. Thank you very much!

 

The following are some of my functions

Among them, VL53L4CD_handle_task is the handling function when the interrupt is triggered

Could you please help me check if the problem can be found.

VL53L4CD_ERROR VL53L4CD_StartRanging(
		void *dev)
{
	VL53L4CD_ERROR status = VL53L4CD_ERROR_NONE;
	uint32_t tmp;

	status |= VL53L4CD_RdDWord(dev, VL53L4CD_INTERMEASUREMENT_MS, &tmp);

	/* Sensor runs in continuous mode */
	if(tmp == (uint32_t)0)
	{
		status |= VL53L4CD_WrByte(dev, VL53L4CD_SYSTEM_START, 0x21);
	}
	/* Sensor runs in autonomous mode */
	else
	{
		status |= VL53L4CD_WrByte(dev, VL53L4CD_SYSTEM_START, 0x40);
	}

	return status;
}

static int Tof_VL53L4CD_StartRanging(struct tof_device_s *dev)
{
    int status = 0;
    tof_chip_t *tof_chip = dev->chip_operation;
    tof_commucation_t *com_operation = dev->com_operation;

    status = com_operation->Open(dev->com_param);

    VL53L4CD_ClearInterrupt(dev);
    status = VL53L4CD_StartRanging(dev);

    com_operation->Close(dev->com_param);

    return status;
}

VL53L4CD_ERROR VL53L4CD_StopRanging(
		void *dev)
{
	VL53L4CD_ERROR status = VL53L4CD_ERROR_NONE;

	status |= VL53L4CD_WrByte(dev, VL53L4CD_SYSTEM_START, 0x80);
	return status;
}

static int Tof_VL53L4CD_StoptRanging(struct tof_device_s *dev)
{
    int status = 0;
    tof_commucation_t *com_operation = dev->com_operation;
    tof_chip_t *tof_chip = dev->chip_operation;

    status = com_operation->Open(dev->com_param);
    if (status) {
        return status;
    }

    status = VL53L4CD_StopRanging(dev);

    com_operation->Close(dev->com_param);

    return status;
}

static void VL53L4CD_handle_task(void *param)
{
    uint32_t value;
    int status;
    VL53L4CD_Result_t results;
    struct tof_device_s *dev = (struct tof_device_s *)param;
    tof_chip_t *tof_chip = dev->chip_operation;
    tof_commucation_t *com_operation = dev->com_operation;
    VL53L4CD_Device_s *device_info = (VL53L4CD_Device_s *)tof_chip->private_data;

    while (1) {
        fibo_queue_get(device_info->queue_id, &value, 0);
        status = com_operation->Open(dev->com_param);
        if (status) {
            continue;
        }

        VL53L4CD_ClearInterrupt(dev);
        status = VL53L4CD_GetResult(dev, &results);
        com_operation->Close(dev->com_param);
        fibo_taskSleep(10);
    }

    return;
}

 

Blue666
Associate II

Could someone help me check if there are any problems with my code?

Is it necessary to add a call of VL53L4CD_ClearInterrupt before the call of VL53L4CD_StopRanging to avoid this problem?

if you don't clear the interrupt before stopping the sensor will consume some power pulling that interrupt line low. 

So clear it, then issue the stop, and as discussed, use the latest driver. 

if you find you issued the clear and it didn't clear, then you've somehow lost communication. 

the I2C is not a very robust bus. and noise can stick it. 

Check to see if either the clock or data line is stuck low - that is a common symptom. 

if so, stronger pullups might be required along with all the other noise reduction techniques. 

- john


If this or any post solves your issue, please mark them as 'Accept as Solution' It really helps. And if you notice anything wrong do not hesitate to 'Report Inappropriate Content'. Someone will review it.
John E KVAM
ST Employee

What happens if you immediately clear the interrupt after the start. 

I'm thinking that if the interrupt is being held low, that the ranging engine will be active after the start and will get the command to clear the interrupt.

Then, when the device finishes ranging, it should trigger the interrupt and continue along. 

You can sprinkle clear_interrupt commands before and after your start. calling it twice won't hurt. 

- john


If this or any post solves your issue, please mark them as 'Accept as Solution' It really helps. And if you notice anything wrong do not hesitate to 'Report Inappropriate Content'. Someone will review it.

Must clear_interrupt commands be executed immediately after start?

I attempted to execute clear_interrupt commands a few seconds after executing the start command, but in abnormal condition, the interrupt pin still at a low level.

John E KVAM
ST Employee

It's always a good idea to clear the interrupt just after a start command.

1) It insures you are in sync with the sensor. 

2) When the sensor reboots for any reason, we set the interrupt pin. This way the MCU can check the sensor and make sure it's all good. 

So issue the start, then clear the interrupt, and after the ranging period you will get the 'i'm done' interrupt. 

- john 


If this or any post solves your issue, please mark them as 'Accept as Solution' It really helps. And if you notice anything wrong do not hesitate to 'Report Inappropriate Content'. Someone will review it.

I have tried adding clear the interrupt before stopping the sensor, but the problem I encountered before still occurs.

After not using VL53L4CD for a long time,  I received two interrupts for the first start command, when the last interruption comes, the rang_status is 2, but the interrupt line still at a low level since then. No matter how I sent the clear_interrupt command, it had no effect.

This problem has puzzled me for a long time. Could you help me solve it.