2020-03-08 07:25 AM
Hello,
I'm working on a project with a VL6180X ranging sensor, and I'm running into the problem that it responds to reflective surfaces far beyond the desired range (100 mm) - e.g. it picks up reflective stripes on the jackets of emergency personnel at over 1200 mm (4 feet) distance, rendering the whole thing unusable.
The datasheet mentions a Wrap-Around Filter (WAF) to solve this problem; however, it turns out that this filter (and only this filter) requires the use of the VL6180X API - which is a problem, as I'm using a simple PIC controller for the overall functionality (switching on a small liquid pump when a hand is within range).
I already checked out the API, but it isn't clear at all how this WAF works. Could someone shed some light on this? If it is merely a matter of setting a bunch of registers, my controller should be able to handle that just fine; and even if some continuous external processing is required, it shouldn't be impossible.
(I also looked if I could simply decrease the VCSEL output to limit the range, but there seems to be no register setting for this.)
What I don't want, is to redesign and rebuild the hardware and software in order to be able to use just this one feature.
Thanks already for any help!
Richard
2020-05-19 08:05 AM
That wrap around is also called radar aliasing, and is a fact of life with ToF sensors. The light that goes at time A comes back AFTER the light goes out at time B. So the photons captured are the wrong photons, and an object that appears at 10 cm is actually at 1200 or any multiple of the wrap distance.
As the light is fairly weak, this will only happen with exceptionally reflective objects - like safety strips or mirrors.
Typically the method of detecting wrap is good for a bit, but as the photons are not coded in any way, there will always be another wrap point - just farther out.
One thing you might try - use the reflectivity of the object. Compare the reflectivity of a real hand to that of your reflective jacket at long distance.
You might find a solution there.
2020-05-20 04:18 AM
Hello John,
Thank you for your answer.
The principle of wrap-around is clear, as are possible countermeasures such as taking reflectivity into account.
However, one thing that is not addressed as a solution, is extending the time interval between emitted light pulses (I was hoping that the WAF in the API was based on this, using some undocumented register settings, but it isn't).
With light traveling at 3E8 meters per second, a 1-meter round trip takes approximately 6.7 nanoseconds (2 x 3.3 ns). Wouldn't it be a solution to simply set the light pulse interval at 20 nanoseconds, i.e. 3 meters of distance? In my setup, no wrap-around occurred beyond 2700 millimeters (also see below for details).
The VL6180X documentation provides no value for the interval between light pulses, although the minimum range of 900 millimeters for wrap-around to occur would suggest a value of 6 nanoseconds; the upper range of 1500 millimeters would suggest a pulse duration of 4 nanoseconds. This is confirmed by the observation that a second wrap-around range starts at approximately 2500 millimeters.
Also, I could find no documented register for setting this light pulse interval. Is there such a register? Or is this interval hardwired into the device?
I did manage to implement some filtering of my own, where several subsequent measurements must not include the 0x00 value in order to be considered valid. This appears to work pretty well, although testing is still under way.
Here are some measurements and tests:
Summarizing, it seems that I managed to filter out wrap-around sufficiently to make my application usable, although we still experience occasional quirks in the functioning of the device (but that may be due to my code - we've had a sensor becoming unresponsive for range measurements, even though it did respond properly when polled for the sensor ID).
In any case, I'd still be interested in your thoughts about the interval and duration of the light pulses emitted, and in particular if it is possible to extend this interval.
Please also let me know if it is helpful if I provide the register settings I'm using at this point.
Thank you once again,
Best regards,
Richard
2020-05-20 08:49 AM
The pulse interval is fixed unfortunately.
Increasing the pulse interval means a slower device. As you well imagine, we use a lot of pulses and do statistics to get the answer. It's how one has to do it if you don't have a 300GHz device.
With our other sensors - which all do longer ranges - the wrap point is much farther out. And changing the pulse interval is one of the things we did.
Unfortunately the longer range parts have some issues at the very short distances. But if wrap is your biggest problem, it might be worth looking into.
The VL53L0X has a wrap at much farther out.
We did a lot of work with mirrors and reflective tape to extend the wrap point, but in the end it's simply a trade-off between speed of the device and wrap point.
You did a lot of work, and I'm glad you got your application usable.
2020-05-21 04:00 AM
Hello John,
Thank you for your clarification. I appreciate that this is quite tricky technology at the very least, and it is already an achievement that you succeeded in making it work as it is. For me, it has been an education too in all the intricacies of optical behavior in a less than 100% predictable environment.
Yes, I also looked at the VL53L0X, and it has some quite appealing characteristics compared to the VL6180X. Unfortunately, I was already committed to the current controller hardware and software setup, which doesn't allow for the use of your API (the API being the only way that the VL53L0X can be deployed).
The VL6180X range measurement still seems somewhat prone to becoming unresponsive at unpredictable moments, but I'll first make certain that this doesn't have anything to do with my code before returning here for support. (The final product is supposed to run for months or years on end unattended, so I'm checking regularly if the VL6180X devices are still responsive by checking their ID - and if not, an attempt at re-initialization is made. Unfortunately, I can't force a hardware reset with GPIO0 at this moment, so it can't recover automatically from an internal lock-up.)
Anyway, since the application appears functional for now, I'll just leave it at thanking you again for your reply.
Best regards,
Richard
2020-06-02 11:44 AM
@RichardR I'm curious if you used an I2C sniffer to see if there is anything unusual or different in the way the controller running the API configures/uses the sensor versus your PIC implementation? Maybe there is something in there you could use. I'd certainly hope the wrap-around filter, if limited to the API, is because it's indeed implemented in the API and not in some hidden configuration of the device.
2020-06-02 12:23 PM
I never actually used the API, but from John's answer and my own unraveling of the relevant API code, I found that _filter_Start() (the lowest-level call AFAICT) doesn't set or change any registers; it merely seems to do some complicated juggling with the data set already retrieved from the device.
So no, there appear to be no undocumented registers involved in wrap-around filtering (although quite a few of those are involved in the initialization of the device).
Anyway, my far simpler filtering seems to do the job just fine, even though there are some mysterious errors with the live test setup in an actual sanitary environment that don't happen on my workbench. But I'm still working on that.
Thank you for your reply,
Best regards
2020-09-17 02:50 AM
Hello John,
I'd like to pick your mind once more about some rather persistent issues we experience with the VL6180X: every few hours or so, the device becomes unresponsive for short periods of time, but only in the (highly reflective) environment where it is supposed to be used, i.e. a tiled booth, some 20 miles away from my place of work.
In other places (my workshop, and the customer's test facility), it keeps working without errors for months on end.
I suspect it may have something to do with the 100 ms intervals at which the devices are read out. Please note that there are two devices, some 250 mm (10") apart.
Here is what happens in more detail, 10 times every second:
Then the same is done for the second device. After step 4 for the second device, the controller waits until 100 ms have elapsed before returning to step 1.
If I read the datasheet correctly (page 26-27), one range measurement should complete in no more than 20 ms, including pre-cal and averaging, so 100 ms should be more than enough time to obtain a measurement.
The occasional error happens at step 1, with the device becoming temporarily unresponsive. Several things I observed and tested:
Is there any way that reflectivity and/or wrap-around measurements could render the device unresponsive, even for short periods of time? I could also provide the initialization sequence if that helps.
Or is it possible that both devices interfere with each other? The second device's cycle lags about 10 microseconds behind the first device, and maybe they somehow manage to trip each other up occasionally, although I can't think of a way how this could happen.
To further troubleshoot this problem, I'm also about to implement remote monitoring, with a Raspberry Pi collating and submitting all measurements, so that I can remotely watch what happens in real time. But if you have any idea what might be happening here, I'd be most grateful, as we're struggling with this for many months now.
Thanks once again already, best regards,
2020-10-05 05:23 PM
Richard -
I'm sorry I missed this. Probably best to start a new thread whenever you change topics.
I forwarded your query. With a little luck I'll get an answer back.
is it possible that there was noise on either the I2C line or the XSHUT line. The XSHUT is very sensitive and really needs a good pullup.
I2c is always a pain. It hangs all the time. The symptom appears to be 'bus stuck low'. When idle the I2C should always be high. If it's low for very long, your bus is stuck.
Pull-up, decoupling caps, bigger wires are all good ideas.
And if the bus is stuck your processor should send 8 clocks to clear it.
I'll see if I get more ideas.
2020-10-06 12:26 AM
Hello John,
First, my apologies for resurrecting an old thread; yes, it would perhaps have been better to start a new one.
About the issues described in my last message: I also figured that I2C might have something to do with it, and I already made some changes in the code to make these communications more robust (mostly to do with timing and exception handling). But your suggestion of sending extra clock signals to release the bus is a very good one, and I'll certainly add that to the error-handling part of my I2C library as the first thing to try in case of unresponsiveness.
Last week, I also installed remote monitoring, logging and transmitting everything that happens with both sensors in realtime. So far, things are quite encouraging, as I only got one spurious reading with near-zero proximity (perhaps someone wiping over it with a cloth, or maybe an insect crawling over it), and no errors at all. I really hope that we solved the last problems -- and so far, it looks quite good.
Thank you for your continued support and good suggestions! I think that we're out of the woods by now, and that the sensor system is working reliably, so chances are that I won't be bothering you any more.
Best regards,
Richard