Skip to main content
Associate II
April 23, 2024
Question

VL53L4CD - Signal is below the defined threshold

  • April 23, 2024
  • 11 replies
  • 6286 views

Hey,

I have a custom made board/device which is using 4x VL53L4CD Tof Sensors to measure the distance. I have trouble to calibrate the sensors correctly or get correct values from them from time to time. Sometimes it works well - sometimes it does not.
What I can see is, that for sensor where the distance is not accurate I am receiving the result status " Signal is below the defined threshold", as described in the datasheet.
What exactly does that mean and how can I fix that? What is causing this issue?

The signal threashold is set to 5000 and the sigma is set to be 10.

I noticed when I am running the offset and xtalk calibration - this issue can disappear but it takes multiple calibration iterrations and sometimes it does not fix the problem.

 

And as well: what exactly is a 17% reflective material!? (as mentioned in the datasheet to calibrate offset and xtalk)

This topic has been closed for replies.

11 replies

John E KVAM
ST Employee
April 24, 2024

In order to get a range, the light must bounce off the target and have enough signal so we can measure the photon arrival times. We cannot measure the photon times directly. Light is too fast. So, we use a statical model. And that model takes a number of photon timings. 

Ideally, we want 20M photons per second. But as long as we get 0.5M photons per second we can give a pretty precise answer. Below the threshold you set, we will return an answer, but will set the status to 'low signal'. It's a warning to you.

We also have a Sigma value. This is a measure of precision. With a good signal we will return the distance +/- a sigma of a few mm. With a very low signal we will return a distance +/- a much larger sigma.

Setting the sigma tells the sensor what you want, and we will return a warning in the range status that we did not achieve that sigma.   

Want to get rid of the status error - Lower the signal and increase the sigma. The status error will go away, but you will have to do your own checking of the signal and sigma if you want to guarantee the range is of a good quality. 

17% reflective paper is a calibrated paper that returns 17% of the 940nm photons that hit it. 

White paper is about 88% reflective. Flat black paint sprayed on a cardboard sheet is 5% reflective. 

17% is a dark gray. Most colored paints are about 50%. You skin is somewhere between 40 and 60%.

Wool is 88% reflective, no matter what color you dye it. So reflectivity at 940nm is NOT easy to tell my looking at it.

DrD00mAuthor
Associate II
April 24, 2024

I actually found a very strange behavior on my board and I am afraid that this is layout related. 
Have you ever seen something like this:

DrD00m_0-1713978640168.png

I tested it on 3 different Board with no initial config setup, no threshold, no sigma. 
Pretty raw. I also tried different I2C Speeds (all of the sensors are on the same bus). 
This one sensor show very strange numbers, 1536 for example the most and not much variation. Any idea what could cause this? 

John E KVAM
ST Employee
April 24, 2024

This is an educated guess. 

Are all these sensors pointing the same direction?

When 2 sensors are pointed at the same place, and there is a reasonably bright target surface, they generally do not interfere with each other. But sometimes they do.

To prevent EMI we use clock dithering. And this movement of the base timing tends to ensure the clocks don't line up. But just due to the randomness, they sometimes do. 

one can keep a running average to even out the data. Or one can use the Inter-measurement period on the sensors to try to get them out of lock-step. Or one can slightly tilt one so the Field of View have less overlap. Generally this only happens with near or reflective targets. Can you avoid those?

 

- john

 

 

 

 

DrD00mAuthor
Associate II
April 24, 2024

All 4 sensors point into the same direction and they are exactly 4cm appart from eachother.
There is actually no object in front of the sensor when measuring and I also tried it by using one by one, disabling all others while the one is measuring (just to make sure)
The dips you see is distance. So there is no shiny or reflective object in front.
could it be something else? This sensor returns 0 mm distance if I apply the config to it.

DrD00mAuthor
Associate II
April 25, 2024

I inspected the I2C now using my analg analyzer and at least on I2C side everything looks exactly as it should.
Here is the sequence I am sending with my test app:

 

 

write to 0x29 ack data: 0x00 0x01 0x2A << set I2C Address
write to 0x2A ack data: 0x00 0x08 0x81 << start temperature update 
write to 0x2A ack data: 0x0B 0x92 
write to 0x2A ack data: 0x00 0xDE 
read to 0x2A ack data: 0x00 0x26
write to 0x2A ack data: 0x00 0x6C 0x00 0x00 0x00 0x00 
write to 0x2A ack data: 0x00 0x6C 
read to 0x2A ack data: 0x00 0x00 0x00 0x00 
write to 0x2A ack data: 0x00 0xDE 
read to 0x2A ack data: 0x00 0x26
write to 0x2A ack data: 0x00 0x87 0x21 
write to 0x2A ack data: 0x00 0x30 
read to 0x2A ack data: 0x11
write to 0x2A ack data: 0x00 0x31 
read to 0x2A ack data: 0x02
write to 0x2A ack data: 0x00 0x86 0x01 
write to 0x2A ack data: 0x00 0x87 0x00 
write to 0x2A ack data: 0x00 0x08 0x09 
write to 0x2A ack data: 0x0B 0x00 << END start temperature setup
write to 0x2A ack data: 0x00 0x6C << start ranging
read to 0x2A ack data: 0x00 0x00 0x00 0x00
write to 0x2A ack data: 0x00 0xDE 
read to 0x2A ack data: 0x00 0x26
write to 0x2A ack data: 0x00 0x87 0x21 
write to 0x2A ack data: 0x00 0xDE 
read to 0x2A ack data: 0x00 0x26
write to 0x2A ack data: 0x00 0x6C 0x00 0x00 0x0E 0x18 << set inter measurment ms to be 90ms
write to 0x2A ack data: 0x00 0x6C 
read to 0x2A ack data: 0x00 0x00 0x0E 0x18 << reading the value we just set
write to 0x2A ack data: 0x00 0xDE 
read to 0x2A ack data: 0x00 0x26
write to 0x2A ack data: 0x00 0x06 
read to 0x2A ack data: 0xBC 0x00
write to 0x2A ack data: 0x00 0x5E 0x02 0xC0 << write range config A
write to 0x2A ack data: 0x00 0x61 0x03 0x80 << write range config B
write to 0x2A ack data: 0x00 0x30 
read to 0x2A ack data: 0x11
write to 0x2A ack data: 0x00 0x31 
read to 0x2A ack data: 0x02
write to 0x2A ack data: 0x00 0x89 
read to 0x2A ack data: 0x08
write to 0x2A ack data: 0x00 0x8C 
read to 0x2A ack data: 0x04 0x02
write to 0x2A ack data: 0x00 0x8E 
read to 0x2A ack data: 0x00 0x54
write to 0x2A ack data: 0x00 0x90 
read to 0x2A ack data: 0x00 0x02
write to 0x2A ack data: 0x00 0x92 
read to 0x2A ack data: 0x00 0x06
write to 0x2A ack data: 0x00 0x96 << reading the first distance
read to 0x2A ack data: 0x00 0x46
write to 0x2A ack data: 0x00 0x86 0x01 
write to 0x2A ack data: 0x00 0x30 
read to 0x2A ack data: 0x11
write to 0x2A ack data: 0x00 0x31 
read to 0x2A ack data: 0x02
write to 0x2A ack data: 0x00 0x89 
read to 0x2A ack data: 0x08
write to 0x2A ack data: 0x00 0x8C 
read to 0x2A ack data: 0x04 0x02
write to 0x2A ack data: 0x00 0x8E 
read to 0x2A ack data: 0x00 0x00
write to 0x2A ack data: 0x00 0x90 
read to 0x2A ack data: 0x00 0x02
write to 0x2A ack data: 0x00 0x92 
read to 0x2A ack data: 0x00 0x00
write to 0x2A ack data: 0x00 0x96 
read to 0x2A ack data: 0x00 0x46
write to 0x2A ack data: 0x00 0x86 0x01 
write to 0x2A ack data: 0x00 0x30 
read to 0x2A ack data: 0x11
write to 0x2A ack data: 0x00 0x31 
read to 0x2A ack data: 0x03
write to 0x2A ack data: 0x00 0x30 
read to 0x2A ack data: 0x11
write to 0x2A ack data: 0x00 0x31 
read to 0x2A ack data: 0x03
write to 0x2A ack data: 0x00 0x30 
read to 0x2A ack data: 0x11
write to 0x2A ack data: 0x00 0x31 
read to 0x2A ack data: 0x02
write to 0x2A ack data: 0x00 0x89 
read to 0x2A ack data: 0x08
write to 0x2A ack data: 0x00 0x8C 
read to 0x2A ack data: 0x04 0x02
write to 0x2A ack data: 0x00 0x8E 
read to 0x2A ack data: 0x00 0x0A
write to 0x2A ack data: 0x00 0x90 
read to 0x2A ack data: 0x00 0x00
write to 0x2A ack data: 0x00 0x92 
read to 0x2A ack data: 0x00 0x06
write to 0x2A ack data: 0x00 0x96 
read to 0x2A ack data: 0x00 0x46
write to 0x2A ack data: 0x00 0x86 0x01 
write to 0x2A ack data: 0x00 0x30 
read to 0x2A ack data: 0x11
write to 0x2A ack data: 0x00 0x31 
read to 0x2A ack data: 0x03
write to 0x2A ack data: 0x00 0x30 
read to 0x2A ack data: 0x11
write to 0x2A ack data: 0x00 0x31 
read to 0x2A ack data: 0x03
write to 0x2A ack data: 0x00 0x30 
read to 0x2A ack data: 0x11
write to 0x2A ack data: 0x00 0x31 
read to 0x2A ack data: 0x02
write to 0x2A ack data: 0x00 0x89 
read to 0x2A ack data: 0x08
write to 0x2A ack data: 0x00 0x8C 
read to 0x2A ack data: 0x04 0x02
write to 0x2A ack data: 0x00 0x8E 
read to 0x2A ack data: 0x00 0x48
write to 0x2A ack data: 0x00 0x90 
read to 0x2A ack data: 0x00 0x00
write to 0x2A ack data: 0x00 0x92 
read to 0x2A ack data: 0x00 0x06
write to 0x2A ack data: 0x00 0x96 
read to 0x2A ack data: 0x00 0x46
write to 0x2A ack data: 0x00 0x86 0x01 
write to 0x2A ack data: 0x00 0x30 
read to 0x2A ack data: 0x11
write to 0x2A ack data: 0x00 0x31 
read to 0x2A ack data: 0x03
write to 0x2A ack data: 0x00 0x30 
read to 0x2A ack data: 0x11
write to 0x2A ack data: 0x00 0x31 
read to 0x2A ack data: 0x03
write to 0x2A ack data: 0x00 0x30 
read to 0x2A ack data: 0x11
write to 0x2A ack data: 0x00 0x31 
read to 0x2A ack data: 0x03
write to 0x2A ack data: 0x00 0x30 
read to 0x2A ack data: 0x11
write to 0x2A ack data: 0x00 0x31 
read to 0x2A ack data: 0x02
write to 0x2A ack data: 0x00 0x89 
read to 0x2A ack data: 0x08
write to 0x2A ack data: 0x00 0x8C 
read to 0x2A ack data: 0x04 0x02
write to 0x2A ack data: 0x00 0x8E 
read to 0x2A ack data: 0x00 0x00
write to 0x2A ack data: 0x00 0x90 
read to 0x2A ack data: 0x00 0x02
write to 0x2A ack data: 0x00 0x92 
read to 0x2A ack data: 0x00 0x04
write to 0x2A ack data: 0x00 0x96 
read to 0x2A ack data: 0x00 0x46
write to 0x2A ack data: 0x00 0x86 0x01 
write to 0x2A ack data: 0x00 0x87 0x00

 

The Sensor is now pointing down onto a white paper because to read the I2C I had to turn the device around. 
It returns a distance of 0 if it points into the room (no object)

 



John E KVAM
ST Employee
April 25, 2024

It bothers me that you are getting some 1600 mm when you say there is no object in front of your sensors. With no object you should be getting a 'no signal' Range Status =2. That means any range information is probably suspect. 

It looks to me like there is an object at 1.6 meters or so. Your ceiling perhaps?

Most MCUs are a lot faster than that tiny sensor. If you toggle the Xshut at MCU speeds you could well get the sensor into a half-reset state. When restarting, give it a few milliseconds between lower and raising the XShut pin. 

Rather than look at the I2C, gather up the range_status, the distance, the signal strength and the ambient. Look for your clues in that data. 

The VL53L4CD is limited to about 1.3M. Yet you are getting 1.6M. This means that your ceiling is, perhaps, a nice reflective white. But I'm guessing you are getting a Range status of 4. This happens when one of the two sub-ranges does not return a result and the other does. It's a warning that something odd is going on. (You can get it with motion or if you target starts to wrap around and a 2M target shows up as a 40cm target. Radar aliasing is what this wrap condition is called.)

-john

DrD00mAuthor
Associate II
April 25, 2024

Maybe my exprectations are wrong and the device works way different then I thought. 
I thought the device will not detect anything further then ~15cm. Of course it is pointing to the ceiling and the ceiling is shiny white! 

My goal is a sensor which - when started - reads the distance multiple times (30 times). The distance value will be averaged and set as threshold (minus 10%). In a real world use-case the sensor will point down to the ground propably. What ever will pass this sensor (lowering the distance) will trigger an interrupt.
But what also might happen is: the sensor is higher, pointing into the distance - then the threashold will be the maximum distance or whatever makes sense (what would that be then? 1.3m?) The problem here is, that the sensor sometimes delivers 0 or 1600mm or something around that (when pointing towards my ceiling). Tbh I was not expecting it to actually "see" the ceiling)

So my guess was - if it points into the distance "without" an object (within 15cm or so) it will give me ~1600. But I guess I was totaly wrong about thst one. That means I really can ONLY take values into account, when they are valid (status == 0).

But then I have this issue, where one sensor returns a wrong value even tho I am pointing it at something (like my table). In the log below you can see the sensor returns weird values.
This is causing the device to end up in a interrupt loop where it can never escape from.

 

E (299) quad_psram: PSRAM ID read error: 0x00ffffff, PSRAM chip not found or not supported, or wrong PSRAM line mode
E (299) esp_psram: PSRAM enabled but initialization failed. Bailing out.
[toit] INFO: starting <v2.0.0-alpha.145>
[toit] DEBUG: clearing RTC memory: invalid checksum
[toit] INFO: running on ESP32S3 - revision 0.2
[rep-trap] INFO: Starting RepTrap...
[app] DEBUG: Starting VL53L4CD Sensor Array 1
[app] DEBUG: Initializing BLE API
[app] ERROR: BLE API Service unavailable
I2C address changed from 42 to 42
I2C address changed from 43 to 43
I2C address changed from 44 to 44
I2C address changed from 45 to 45
---------- VL53_1 ------------
Continuous Mode
Setting offset for VL53_1 to -132
Setting xtalk for VL53_1 to 127.0
Error setting xtalk for VL53_1
Signal Threashold: 1496
Autonomous Mode
Autonomous Mode
distance: 126 [✓ Valid measurement]
distance: 127 [✓ Valid measurement]
distance: 128 [✓ Valid measurement]
distance: 127 [✓ Valid measurement]
distance: 128 [✓ Valid measurement]
distance: 125 [✓ Valid measurement]
distance: 125 [✓ Valid measurement]
distance: 125 [✓ Valid measurement]
distance: 126 [✓ Valid measurement]
distance: 126 [✓ Valid measurement]
distance: 126 [✓ Valid measurement]
distance: 126 [✓ Valid measurement]
distance: 124 [✓ Valid measurement]
distance: 124 [✓ Valid measurement]
distance: 125 [✓ Valid measurement]
distance: 126 [✓ Valid measurement]
distance: 125 [✓ Valid measurement]
distance: 126 [✓ Valid measurement]
distance: 125 [✓ Valid measurement]
distance: 127 [✓ Valid measurement]
distance: 124 [✓ Valid measurement]
distance: 128 [✓ Valid measurement]
distance: 126 [✓ Valid measurement]
distance: 125 [✓ Valid measurement]
distance: 125 [✓ Valid measurement]
distance: 126 [✓ Valid measurement]
distance: 124 [✓ Valid measurement]
distance: 125 [✓ Valid measurement]
distance: 125 [✓ Valid measurement]
distance: 124 [✓ Valid measurement]
Average: 125
Threshold percentage: 10
Threshold: 113
Signal Threashold: 5000
Sigma mm: 10
Autonomous Mode
System Status: 3
result-range-status: 0
---------- VL53_2 ------------
Continuous Mode
Setting offset for VL53_2 to -160
Signal Threashold: 1496
Autonomous Mode
Autonomous Mode
distance: 104 [- : Warning! Signal is below the defined threshold]
distance: 77 [- : Warning! Signal is below the defined threshold]
distance: 75 [- : Warning! Signal is below the defined threshold]
distance: 59 [- : Warning! Signal is below the defined threshold]
distance: 59 [- : Warning! Signal is below the defined threshold]
distance: 90 [- : Warning! Signal is below the defined threshold]
distance: 87 [- : Warning! Signal is below the defined threshold]
distance: 67 [- : Warning! Signal is below the defined threshold]
distance: 94 [- : Warning! Signal is below the defined threshold]
distance: 107 [- : Warning! Signal is below the defined threshold]
distance: 105 [- : Warning! Signal is below the defined threshold]
distance: 52 [- : Warning! Signal is below the defined threshold]
distance: 77 [- : Warning! Signal is below the defined threshold]
distance: 76 [- : Warning! Signal is below the defined threshold]
distance: 110 [- : Warning! Signal is below the defined threshold]
distance: 89 [- : Warning! Signal is below the defined threshold]
distance: 91 [- : Warning! Signal is below the defined threshold]
distance: 82 [- : Warning! Signal is below the defined threshold]
distance: 98 [- : Warning! Signal is below the defined threshold]
distance: 83 [- : Warning! Signal is below the defined threshold]
distance: 89 [- : Warning! Signal is below the defined threshold]
distance: 110 [- : Warning! Signal is below the defined threshold]
distance: 99 [- : Warning! Signal is below the defined threshold]
distance: 123 [- : Warning! Signal is below the defined threshold]
distance: 66 [- : Warning! Signal is below the defined threshold]
distance: 101 [- : Warning! Signal is below the defined threshold]
distance: 86 [- : Warning! Signal is below the defined threshold]
distance: 67 [- : Warning! Signal is below the defined threshold]
distance: 83 [- : Warning! Signal is below the defined threshold]
distance: 92 [- : Warning! Signal is below the defined threshold]
Average: 86
Threshold percentage: 10
Threshold: 77
Signal Threashold: 5000
Sigma mm: 10
Autonomous Mode
System Status: 3
result-range-status: 2
---------- VL53_3 ------------
Continuous Mode
Setting offset for VL53_3 to -184
Signal Threashold: 1496
Autonomous Mode
Autonomous Mode
distance: 124 [✓ Valid measurement]
distance: 122 [✓ Valid measurement]
distance: 122 [✓ Valid measurement]
distance: 122 [✓ Valid measurement]
distance: 123 [✓ Valid measurement]
distance: 121 [✓ Valid measurement]
distance: 123 [✓ Valid measurement]
distance: 124 [✓ Valid measurement]
distance: 124 [✓ Valid measurement]
distance: 123 [✓ Valid measurement]
distance: 122 [✓ Valid measurement]
distance: 125 [✓ Valid measurement]
distance: 122 [✓ Valid measurement]
distance: 123 [✓ Valid measurement]
distance: 123 [✓ Valid measurement]
distance: 124 [✓ Valid measurement]
distance: 122 [✓ Valid measurement]
distance: 121 [✓ Valid measurement]
distance: 124 [✓ Valid measurement]
distance: 122 [✓ Valid measurement]
distance: 122 [✓ Valid measurement]
distance: 121 [✓ Valid measurement]
distance: 122 [✓ Valid measurement]
distance: 122 [✓ Valid measurement]
distance: 120 [✓ Valid measurement]
distance: 123 [✓ Valid measurement]
distance: 123 [✓ Valid measurement]
distance: 123 [✓ Valid measurement]
distance: 120 [✓ Valid measurement]
distance: 118 [✓ Valid measurement]
Average: 122
Threshold percentage: 10
Threshold: 110
Signal Threashold: 5000
Sigma mm: 10
Autonomous Mode
System Status: 3
result-range-status: 0
---------- VL53_4 ------------
Continuous Mode
Setting offset for VL53_4 to -160
Signal Threashold: 1496
Autonomous Mode
Autonomous Mode
distance: 119 [✓ Valid measurement]
distance: 121 [✓ Valid measurement]
distance: 119 [✓ Valid measurement]
distance: 121 [✓ Valid measurement]
distance: 119 [✓ Valid measurement]
distance: 117 [✓ Valid measurement]
distance: 119 [✓ Valid measurement]
distance: 120 [✓ Valid measurement]
distance: 120 [✓ Valid measurement]
distance: 121 [✓ Valid measurement]
distance: 123 [✓ Valid measurement]
distance: 120 [✓ Valid measurement]
distance: 124 [✓ Valid measurement]
distance: 121 [✓ Valid measurement]
distance: 121 [✓ Valid measurement]
distance: 122 [✓ Valid measurement]
distance: 119 [✓ Valid measurement]
distance: 121 [✓ Valid measurement]
distance: 123 [✓ Valid measurement]
distance: 120 [✓ Valid measurement]
distance: 119 [✓ Valid measurement]
distance: 121 [✓ Valid measurement]
distance: 122 [✓ Valid measurement]
distance: 120 [✓ Valid measurement]
distance: 121 [✓ Valid measurement]
distance: 121 [✓ Valid measurement]
distance: 120 [✓ Valid measurement]
distance: 119 [✓ Valid measurement]
distance: 118 [✓ Valid measurement]
distance: 119 [✓ Valid measurement]
Average: 120
Threshold percentage: 10
Threshold: 108
Signal Threashold: 5000
Sigma mm: 10
Autonomous Mode
System Status: 3
result-range-status: 0
[toit] INFO: entering deep sleep for 43200000ms

 

 

I also checked my code again with the "config". I was writing 91 bytes to 0x002d without going one by one, assuming that this is not an issue. I am still not sure if it is tho. I changed that to write them one by one increasing the register. 

John E KVAM
ST Employee
April 25, 2024

Writing in a block is fine. We were trying to write the most basic code we could and write_multi() was dropped as one generally does not initialize the sensor very often and it's one less function a user has to migrate. 

The sensor is going to return anything it can. 

What you want is a threshold.

It says, 'Don't generate an interrupt unless the status is good, the signal is strong, the sigma is low, and the distance is below this level.

In Autonomous mode, you set the integration period (timing budget) and how often you range (Inter-measurement period).

If you want to eliminate the ceiling, set the signal threshold high, so that only near, bright objects can be seen. 

(But not too high as you will lose your required target.)

 

John E KVAM
ST Employee
April 25, 2024

The sensor will never give you zero, unless your object is very close indeed. 

An error would return a distance of 8192 minus the error number. So no-signal would return 8190 (no signal being error 2).

I'm not sure what threshold percentage is in this context. 

I would have expected you to use:

 

VL53L4CD_Error VL53L4CD_SetDetectionThresholds(Dev_t dev,
 uint16_t distance_low_mm,
 uint16_t distance_high_mm,
 uint8_t window);
Using this you would only get an interrupt based on distance.

 

 

 

 

 

DrD00mAuthor
Associate II
April 26, 2024

I have never seen something like 8192 so far.

threshold percentage is a value I subtract from the threshold I am about to set to avoid false-positives - so I simply subtract 10% of the average value I measured. 

I am setting low and high_mm to be this threshold. But I am setting the threshold after the measurment you see in the log. 

I try again to explain:

  1. you setup the device in a position x above ground 
  2. you start the device which will measure the current distance 30 times.
  3. This 30 distance values will be averaged minus 10% (example: if the average is 100, I will set 90 as threshold)
  4. the edvice will be enabled as low power mode with interrupts on that threshold

When I run this pointing to my ceiling I get this result

 

Sensor 1 Average: 1819
Sensor 2 Average: 70
Sensor 3 Average: 1826
Sensor 4 Average: 1815

 

where the values of sensor 2 are as follows

 

distance: 37 [- : Warning! Signal is below the defined threshold]
distance: 53 [- : Warning! Signal is below the defined threshold]
distance: 55 [- : Warning! Signal is below the defined threshold]
distance: 77 [- : Warning! Signal is below the defined threshold]
distance: 238 [- : Warning! Signal is below the defined threshold]
distance: 74 [- : Warning! Signal is below the defined threshold]
distance: 61 [- : Warning! Signal is below the defined threshold]
distance: 70 [- : Warning! Signal is below the defined threshold]
distance: 37 [- : Warning! Signal is below the defined threshold]
distance: 36 [- : Warning! Signal is below the defined threshold]
distance: 86 [- : Warning! Signal is below the defined threshold]
distance: 0 [- : Warning! Signal is below the defined threshold]
distance: 84 [- : Warning! Signal is below the defined threshold]
distance: 41 [- : Warning! Signal is below the defined threshold]
distance: 87 [- : Warning! Signal is below the defined threshold]
distance: 53 [- : Warning! Signal is below the defined threshold]
distance: 58 [- : Warning! Signal is below the defined threshold]
distance: 113 [- : Warning! Signal is below the defined threshold]
distance: 25 [- : Warning! Signal is below the defined threshold]
distance: 54 [- : Warning! Signal is below the defined threshold]
distance: 95 [- : Warning! Signal is below the defined threshold]
distance: 33 [- : Warning! Signal is below the defined threshold]
distance: 65 [- : Warning! Signal is below the defined threshold]
distance: 261 [- : Warning! Signal is below the defined threshold]
distance: 76 [- : Warning! Signal is below the defined threshold]
distance: 70 [- : Warning! Signal is below the defined threshold]
distance: 46 [- : Warning! Signal is below the defined threshold]
distance: 66 [- : Warning! Signal is below the defined threshold]
distance: 16 [- : Warning! Signal is below the defined threshold]
distance: 40 [- : Warning! Signal is below the defined threshold]

 

even tho they are all pointing to the ceiling.

Now I left the device over night and all 4 sensors on my board showing the same ceiling values except: one of them triggers the interrupt permanently.

DrD00mAuthor
Associate II
April 26, 2024

 

I placed an object 100mm in front of the sensors and one of them gave me this values:

distance: 42 [- : Warning! Signal is below the defined threshold]
distance: 102 [✓ Valid measurement]
distance: 101 [✓ Valid measurement]
distance: 92 [- : Warning! Signal is below the defined threshold]
distance: 104 [✓ Valid measurement]
distance: 75 [- : Warning! Signal is below the defined threshold]
distance: 102 [✓ Valid measurement]
distance: 101 [✓ Valid measurement]
distance: 100 [✓ Valid measurement]
distance: 102 [✓ Valid measurement]
distance: 74 [- : Warning! Signal is below the defined threshold]
distance: 103 [✓ Valid measurement]
distance: 75 [- : Warning! Signal is below the defined threshold]
distance: 76 [- : Warning! Signal is below the defined threshold]
distance: 102 [✓ Valid measurement]
distance: 102 [✓ Valid measurement]
distance: 79 [- : Warning! Signal is below the defined threshold]
distance: 102 [✓ Valid measurement]
distance: 101 [✓ Valid measurement]
distance: 103 [✓ Valid measurement]
distance: 94 [- : Warning! Signal is below the defined threshold]
distance: 101 [✓ Valid measurement]
distance: 102 [✓ Valid measurement]
distance: 56 [- : Warning! Signal is below the defined threshold]
distance: 101 [✓ Valid measurement]
distance: 100 [✓ Valid measurement]
distance: 43 [- : Warning! Signal is below the defined threshold]
distance: 101 [✓ Valid measurement]
distance: 104 [✓ Valid measurement]
distance: 66 [- : Warning! Signal is below the defined threshold]

all others gave me

distance: 103 [✓ Valid measurement]
distance: 101 [✓ Valid measurement]
distance: 103 [✓ Valid measurement]
distance: 105 [✓ Valid measurement]
distance: 102 [✓ Valid measurement]
distance: 104 [✓ Valid measurement]
distance: 103 [✓ Valid measurement]
distance: 102 [✓ Valid measurement]
distance: 101 [✓ Valid measurement]
distance: 102 [✓ Valid measurement]
distance: 101 [✓ Valid measurement]
distance: 102 [✓ Valid measurement]
distance: 102 [✓ Valid measurement]
distance: 102 [✓ Valid measurement]
distance: 101 [✓ Valid measurement]
distance: 101 [✓ Valid measurement]
distance: 100 [✓ Valid measurement]
distance: 100 [✓ Valid measurement]
distance: 101 [✓ Valid measurement]
distance: 103 [✓ Valid measurement]
distance: 101 [✓ Valid measurement]
distance: 102 [✓ Valid measurement]
distance: 101 [✓ Valid measurement]
distance: 101 [✓ Valid measurement]
distance: 101 [✓ Valid measurement]
distance: 102 [✓ Valid measurement]
distance: 104 [✓ Valid measurement]
distance: 102 [✓ Valid measurement]
distance: 102 [✓ Valid measurement]
distance: 100 [✓ Valid measurement]

This happens on 3 different boards every time. 

Now - I wrote the driver code in toit - and it works for 3 of 4 sensors. And this is something I do not understand at all. I also have written the same code in Micropython, where it works for all 4 sensors perfectly fine.
I can not run the Arduino code of yours because it always crashes with a core-panic "divisionByZero".

I am going crazy right now - this is day 5 I try to understand this behavior and I have no clue whats going on. I can't even break it down to anything.
I have seen the same behavior on 3 different Boards
Always Sensor 1 and 2 had issues, never Sensor 3 and 4 
There is no difference in how they are attached or placed. 
It can not be I2C as far as I see it because I can see all data on the bus
The same sensor works with my micropython code but it does not with my toit code. (I can not see a difference there in the implementation)
After it was working with micropython, switching back to toit, it works until I power reset the board.
I have never seen something like that.

If it works with micropython - it can not be a hardware problem, right?

With toit it works with 3 out of 4 Sensors - so it must be a software problem? But how can I have one board which just works with toit on all 4 sensors?? This is driving me crazy.

Is there any way you can help me with that?

DrD00mAuthor
Associate II
April 26, 2024

Your Arduino example code is also crashing btw.

Starting...
Guru Meditation Error: Core 1 panic'ed (IntegerDivideByZero). Exception was unhandled.

Core 1 register dump:
PC : 0x42002125 PS : 0x00060830 A0 : 0x8200199c A1 : 0x3fcebbe0 
A2 : 0x3fc958b8 A3 : 0x000000ff A4 : 0x00000000 A5 : 0x00000000 
A6 : 0x00000000 A7 : 0x0000e100 A8 : 0x00000000 A9 : 0x3fcebbb0 
A10 : 0xffffffff A11 : 0x00000052 A12 : 0x00000006 A13 : 0x00000000 
A14 : 0x3fcec6bc A15 : 0x00000000 SAR : 0x0000001b EXCCAUSE: 0x00000006 
EXCVADDR: 0x00000000 LBEG : 0x40056f5c LEND : 0x40056f72 LCOUNT : 0x00000000 


Backtrace: 0x42002122:0x3fcebbe0 0x42001999:0x3fcebc10 0x42003d12:0x3fcebc50




ELF file SHA256: 972f97422299d5a6

 

John E KVAM
ST Employee
April 29, 2024

Are all your pointing at exactly the same place? If so, light from one sensor can be recevied by the other sensors. 

Consider starting them at different times and set your timing Budget and inter-measurement period such that they are not all running at the same time. 

My guess is one always works, but there is interaction between the sensors. 

One can get the ambient light measurement from the sensor. When you get these issues, is the ambient light going way up?

I suspect you are confusing what the sensor is giving you with what you are getting from the software. 

I'm not familiar with the particular software you are using. 

Generally, we like at least 0.5M counts. 5000 seems like a high setting. Your 'low signal' is just a warning that your signal is under the count you set. Try 500. (Again, I'm assuming that is K counts. Could be different based on your software. 

The Range A and Range B setting are for how long the sensor integrates. Call setting Set_timingBuget and watch those change. The units for this clock register are really odd. But bigger is longer. The ULP uses settings that are really low to save power. It gives up a lot of accuracy, however. 

 

Perhaps you could submit another entry on "Arduino example code is crashing." Tell me where you got that code, and how you ran it. I will have someone look at it. 

Could you tell me where you got your software. I'd like to look into it. So many people have taken our software and adapted it for various things. It would be interesting for me to have a look at it. 

DrD00mAuthor
Associate II
April 29, 2024

I still haven't figured out what the problem is - I posted another thread about the interrupt issue.
You can find my code here:
https://github.com/open-thngs/trap-a-rep-trigger/blob/main/src/toit/src/vl53l4cd-driver.toit

https://github.com/open-thngs/trap-a-rep-trigger/blob/main/src/toit/src/vl53l4cd.toit

https://github.com/open-thngs/trap-a-rep-trigger/blob/main/src/toit/src/config.toit

Those are the main files or driver implementation which I ported from the C and C++ code (from adafruit). I tried running this code with a single sensor while disabling all others. Still the same problem. (which means there is no interference with the sensors). I made sure the sensors are disabled by looking at them with my phone-camera.
Also the sensor returns a value 0mm (with the warning about being below the limit) which is odd. I assume if it reads a 0 that something got dropped in I2C maybe? still being ACK?!

I tried so many things and currently it is always the second sensor - but from hardware point of view I can not identify any difference. If I run the micropython code in this repo (you can find it in src/micropython/app2.py) everything is working perfectly fine with all 4 sensors.
I also have now one board where the toit code also works just fine - which does not really help, it makes it even more confusing. You can find the board schematics in this repo as well.

So my hard guess is, that it has something to do with I2C. But also here I can not figure out what it is. I am assuming that the sensor somehow is reacting wirdly to the I2C or it misses some bytes. But thats just a feeling - because if I track the i2c communication on the bus I can see all data being transmitted on the bus correctly.

Is there any timing issues I need to know for any of the commands? 

DrD00mAuthor
Associate II
May 2, 2024

I am pretty sure something is wrong with the sensors. I tried to run the Arduino example code again and made it work.

 

#include <Arduino.h>
#include <Wire.h>
#include <vl53l4cd_class.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <assert.h>
#include <stdlib.h>

#define DEV_I2C Wire
#define SerialPort Serial


// Components.
VL53L4CD sensor_vl53l4cd_sat1(&DEV_I2C, 47);
VL53L4CD sensor_vl53l4cd_sat2(&DEV_I2C, 17);
VL53L4CD sensor_vl53l4cd_sat3(&DEV_I2C, 5);
VL53L4CD sensor_vl53l4cd_sat4(&DEV_I2C, 8);

/* Setup ---------------------------------------------------------------------*/

void setup()
{

 // Initialize serial for output.
 SerialPort.begin(115200);
 SerialPort.println("Starting...");

 // Initialize I2C bus.
 DEV_I2C.begin(38, 48);

 // Configure VL53L4CD satellite component.
 sensor_vl53l4cd_sat1.begin();
 sensor_vl53l4cd_sat2.begin();
 sensor_vl53l4cd_sat3.begin();
 sensor_vl53l4cd_sat4.begin();

 // Switch off VL53L4CD satellite component.
 sensor_vl53l4cd_sat1.VL53L4CD_Off();
 sensor_vl53l4cd_sat2.VL53L4CD_Off();
 sensor_vl53l4cd_sat3.VL53L4CD_Off();
 sensor_vl53l4cd_sat4.VL53L4CD_Off();

 //Initialize VL53L4CD satellite component.
 sensor_vl53l4cd_sat1.InitSensor(43);
 sensor_vl53l4cd_sat2.InitSensor(44);
 sensor_vl53l4cd_sat3.InitSensor(45);
 sensor_vl53l4cd_sat4.InitSensor(46);

 // Program the highest possible TimingBudget, without enabling the
 // low power mode. This should give the best accuracy
 sensor_vl53l4cd_sat1.VL53L4CD_SetRangeTiming(80, 120);
 sensor_vl53l4cd_sat2.VL53L4CD_SetRangeTiming(80, 120);
 sensor_vl53l4cd_sat3.VL53L4CD_SetRangeTiming(80, 120);
 sensor_vl53l4cd_sat4.VL53L4CD_SetRangeTiming(80, 120);

 // Start Measurements
 sensor_vl53l4cd_sat1.VL53L4CD_StartRanging();
 sensor_vl53l4cd_sat2.VL53L4CD_StartRanging();
 sensor_vl53l4cd_sat3.VL53L4CD_StartRanging();
 sensor_vl53l4cd_sat4.VL53L4CD_StartRanging();
}

void loop()
{
 uint8_t NewDataReady = 0;
 VL53L4CD_Result_t results1;
 VL53L4CD_Result_t results2;
 VL53L4CD_Result_t results3;
 VL53L4CD_Result_t results4;
 uint8_t status;
 char report[64];


 sensor_vl53l4cd_sat1.VL53L4CD_ClearInterrupt();
 sensor_vl53l4cd_sat1.VL53L4CD_GetResult(&results1);
 snprintf(report, sizeof(report), "S1[%2u] Distance = %4u mm | ",
 results1.range_status,
 results1.distance_mm,
 results1.signal_per_spad_kcps);
 SerialPort.print(report);

 sensor_vl53l4cd_sat2.VL53L4CD_ClearInterrupt();
 sensor_vl53l4cd_sat2.VL53L4CD_GetResult(&results2);
 snprintf(report, sizeof(report), "S2[%2u] Distance = %4u mm | ",
 results2.range_status,
 results2.distance_mm,
 results2.signal_per_spad_kcps);
 SerialPort.print(report);

 sensor_vl53l4cd_sat3.VL53L4CD_ClearInterrupt();
 sensor_vl53l4cd_sat3.VL53L4CD_GetResult(&results3);
 snprintf(report, sizeof(report), "S3[%2u] Distance = %4u mm | ",
 results3.range_status,
 results3.distance_mm,
 results3.signal_per_spad_kcps);
 SerialPort.print(report);

 sensor_vl53l4cd_sat4.VL53L4CD_ClearInterrupt();
 sensor_vl53l4cd_sat4.VL53L4CD_GetResult(&results4);
 snprintf(report, sizeof(report), "S4[%2u] Distance = %4u mm | \r\n",
 results4.range_status,
 results4.distance_mm,
 results4.signal_per_spad_kcps);
 SerialPort.print(report);

 delay(250);
}

 

 As you can see I initialise all 4 sensors and read there distance value. It is printing the following line:

S1[ 4] Distance = 1879 mm | S2[ 4] Distance = 1804 mm | S3[ 4] Distance = 1804 mm | S4[ 4] Distance = 1822 mm | 

Even the second sensor is working just fine here. BUT - and this is increadibly strange - sensor 2 and 3 always showing the exact same values. If I put my finger ontop of sensor 2, sensor 3 shows the same changes and the other way around. This is super strange.
I then changed the I2C addreses for all sensors from the above to be:

sensor_vl53l4cd_sat1.InitSensor(43);
sensor_vl53l4cd_sat2.InitSensor(45);
sensor_vl53l4cd_sat3.InitSensor(47);
sensor_vl53l4cd_sat4.InitSensor(49);

I basically just increased the address by 2 instead of 1 and now both ssensors show different values. How can this be? This is clearly an issue with the sensors and I am pretty sure this is the reason why my code does not work either. I tried to also change the I2C Addresses in my toit code but it was not fixing the problems.

John E KVAM
ST Employee
May 2, 2024

Don't get me started on how bad that I2C bus is, but you found your issue. And it's a sneaky one. 

A USB address consists of a 7-bit address and a write/read bit. 

At boot the ToF sensors are at address 0x29 - which is the 7-bit number. 

To write to the chip, one shifts the 0x29 left by one = 0x52 and then sets the LSB to 0.

To read from the chip, set the LSB to one and you get 0x53. 

So, each USB device, has in effect, and address pair. 

But it seems silly to keep doing that shift by one all the time, so some drivers reference the chip by its 8-bit address. 

Your seeming duality was in fact, just that. Address 0x52 and 0x53 are addresses to the same chip. 

And that is why some returned the same number. You were reading the same chip twice. 

Sorry I did not spot that sooner. I should have. I've been there; done that. 

-john

DrD00mAuthor
Associate II
May 2, 2024

Do you have any explanation for the interrupt which can not be cleared? Did you had a chance to check the code?
I am currently in the installation phase of my hardware and I am about to swap the sensor because I am pretty sure it is an issue of this sensor not being able to communicate properly via I2C. 

You mentioned that the interrupt should only trigger if there was a valid distance reading, but I get interrupts when it is actually reading 0 mm. After it initialises the sensor I have the GPIO for the interrupt LOW which triggers the interrupt code which then clears that interrupt but it never gets cleared. 

I did change the I2C addresses now to be 20, 30, 40 and 50. 
Which are 0x14, 0x1e, 0x28, 0x32

 

Is there any way to get a call and talk to someone here? I can not get anywhere with this.

DrD00mAuthor
Associate II
May 6, 2024

@John E KVAM it would be nice to get a littlebit better and faster support here. is that possible?

The I2C Address issue from earlier does not fix the problem with the sensors.
Didn't you said, that the sensor should not give back 0mm?

I see 0mm often on this sensors. Whenever it was 0 I was printing all data:

Sensor VL53_2 [0x1e]
Distance: 1651 mm [✗ Error: Phase out of valid limit]
Distance: 1871 mm [✗ Error: Phase out of valid limit]
Distance: 1666 mm [✗ Error: Phase out of valid limit]
Distance: 1903 mm [✗ Error: Phase out of valid limit]
Distance: 1661 mm [✗ Error: Phase out of valid limit]
Distance: 1867 mm [✗ Error: Phase out of valid limit]
Distance: 1647 mm [✗ Error: Phase out of valid limit]
Distance: 1888 mm [✗ Error: Phase out of valid limit]
Distance: 1661 mm [✗ Error: Phase out of valid limit]
Distance: 1875 mm [✗ Error: Phase out of valid limit]
Result: SPAD=203, Signal=592, Ambient=392, Sigma=8, Distance=0, Signal/SPAD=2, Ambient/SPAD=1 | ✗ Error: Phase out
 of valid limit
Distance: 0 mm [✗ Error: Phase out of valid limit]
Distance: 1876 mm [✗ Error: Phase out of valid limit]
Distance: 1669 mm [✗ Error: Phase out of valid limit]
Distance: 1879 mm [✗ Error: Phase out of valid limit]
Distance: 1661 mm [✗ Error: Phase out of valid limit]
Distance: 1896 mm [✗ Error: Phase out of valid limit]
Distance: 1667 mm [✗ Error: Phase out of valid limit]
Distance: 1894 mm [✗ Error: Phase out of valid limit]
Result: SPAD=203, Signal=616, Ambient=376, Sigma=7, Distance=0, Signal/SPAD=3, Ambient/SPAD=1 | ✗ Error: Phase out
 of valid limit
Distance: 0 mm [✗ Error: Phase out of valid limit]
Distance: 1882 mm [✗ Error: Phase out of valid limit]
Result: SPAD=203, Signal=648, Ambient=368, Sigma=7, Distance=0, Signal/SPAD=3, Ambient/SPAD=1 | ✗ Error: Phase out
 of valid limit
Distance: 0 mm [✗ Error: Phase out of valid limit]
Distance: 1865 mm [✗ Error: Phase out of valid limit]
Distance: 1664 mm [✗ Error: Phase out of valid limit]
Distance: 1894 mm [✗ Error: Phase out of valid limit]
Distance: 1662 mm [✗ Error: Phase out of valid limit]

 The setup has not changed - the device is still pointing towards my ceiling without any other object close by.
Why do they return 0 mm as distance here?

John E KVAM
ST Employee
May 6, 2024

You are of course correct. If one uses the 7-bit base address, they can go up by one. 

So that wasn't it. 

Let's talk about:

Distance: 1651 mm [✗ Error: Phase out of valid limit]

 This happens when the two sub-ranges do not match. 

We use two sub-ranges with different Pulse Repetition Intervals (PRI) to prevent something called radar aliasing or wrap-around. Aliasing happens when a target is past the max distance the sensor can range. The photons from pulse N were received AFTER pulse N+1 got sent out. So, a target at 4.2Meters would be detected at 0.4Meters. 

With two different PRI we can detect this condition. But it can be caused by other things. 

Motion can cause the two sub ranges to disagree - but both are valid. 

A weak return signal can cause one range to fail, and the other pass. 

In your case that ceiling is just bright enough that it's detected by one on the ranges, but not the other.  

You might increase your timing budget. This will allow both ranges to pass and you'd get better accuracy. 

I still don't know what is going on. Perhaps covering the some of the sensors with bits of paper to determine it there is some interaction we don't understand?

- john

DrD00mAuthor
Associate II
May 7, 2024

@John E KVAM Why do you think this is an issue? 
It measure the correct distance more or less but the ceiling is clearly out of the range (the spec says 1.3m). So this is fine, right?

I would be more interested, why it shows 0mm some times even tho I do not change anything on the setup. 
We discovered aglitch yesterday on the data line.

image.png

This should not be there I think. I changed the pull-up resistor on one of the boards to be 4.7k instead of 2.2k and the spike was gone. But also reducing the I2C speed from 400kHz to 300kHz made this spike disappear. Not sure what is causing this spike tho but I think it is coming from the ESP32-S3. 

Since then I did not had the problem with a sensor being stuck in the interrupt.

 

But still this value 0mm is strange. The sensor measures the distance in default mode to determine a threshold, then sets the sensor into low power mode and sets this threshold to be interrupted when below. 
To do so I measure 25 times and take the average of that measurment. So far this worked pretty well but if the sensor sends 0mm the average will be wrong. I even had the situation where the sensor was sending only 0mm.
So what is the default behavior of the sensor or how should I handle such situations? 
Should I ignore 0mm values? 
I do not mind that while measuring the distance, if there is no object. That can happen if the sensor points into nothingness - then I will set the threshold to be 1300mm anyway. But should the sensor give me a value every time or 0mm a valid measurment? This is what I still don't understand