VL53L1X disabling Serial Port on Arduino MKR ZERO

Hello Pololu Support,

I use an Arduino MKR ZERO and have set up 3 VL53L1X via the default I2C pins and Pins D3, D4, and D5. I also set up a BT receiver via Serial2 using Pins D0 and D1 (SERCOM3) as per instructions from Arduino (https://docs.arduino.cc/tutorials/communication/SamdSercom).

They both worked great, when using separately. But when used together, the 3 VL53L1X still worked fine but they seemed to disable Serial2. In theory, both operations should be independent.

Can you offer some suggestions?
Thank you so much.

Hello Pololu Support,

I also asked Arduino Forum about the same problem, and the conversations there helped me figure out what the problem is, please see this posting

I bought both VL53L1X and VL53L5CX from Pololu, the sample code that I used for the VL53L1X is from Pololu, while your web site suggested to use the Adafruit library for the VL53L5CX:

which I did and found that the Adafruit library worked together well with my Serial2 port. So it looks like that your VL53L1X sample software is using the I2C hardware somewhat differently than the AdaFruit’s one for the CL53L5CX. Can you give me some guidance on where/what to fix on your VL53L1X sample codes?

Thank you very much.

We are not that familiar with the Arduino MKR Zero or SERCOM, but if one I2C device is working with your other devices then I am not sure why another would not (none of the libraries should use any peripherals or pins other than I2C and its default pins). That makes me suspect that this is more likely to be the result of some bug in your code like Koepel suggested in the Arduino Forum thread you linked to.

We cannot offer much support with troubleshooting user code, but if you simplify your program as much as possible (e.g. a program that reads from your Bluetooth receiver and just one VL53L1X) and post a complete program that demonstrates the issue, then I can take a look and let you know if I see any obvious problems.

- Patrick

Hi Patrick,

Thanks for the feedback, and I made some more progress.

I am now adapting the example named “Continuous” (for 1 sensor) and then added my Serial2 code.

I found that the problem that I encountered is caused by Function read() - see Line 1303 in picture below:

You can see that it is using an argument named “blocking” which is set to “true” by default. If I keep this value at “true” then my Serial2 code does not work.

But if I set it to “false”, then my Serial2 code would work properly, but then the ToF sensor keeps on reading “64351” which obviously is incorrect.

So it looks like that I cannot use “Continuous” mode with my set up. Which function do you suggest that I can use for my setup which has 3 VL53L1X sensors.

Many Thanks

@PatrickM
Some more updates.

Instead of using Method sensor.read(), I had tried to use sensor.readSingle() instead, but my Serial2 code was still being blocked (see Line 86 in picture below).

I even commented out sensor.startContinuous(54) (as shown in screen shot below - Line 78), but my Serial2 code is still being blocked.

As I have a BLE SPI module from Adafruit (Adafruit Bluefruit LE SPI Friend - Bluetooth Low Energy (BLE) : ID 2633 : $17.50 : Adafruit Industries, Unique & fun DIY electronics and kits), I just used that SPI module for BT access instead of that Arduino SERCOM setup, and I can get all three ToFs working together (using your “ContinuousMultipleSensors” sketch), along access via Bluetooth for the Adafruit LE Connect App (‎Bluefruit Connect on the App Store).

So, for now, I am all good with my work around solution using the BLE SPI module. And it is clear to me that somehow the Pololu’s way to read these ToF sensors interfered with the operation of these SERCOM modules, but not when a SPI module is used. May be in the future, Pololu can have the time to look into this SERCOM issue, as I sure prefer to use the SERCOM approach with these ToF sensors.

BTW, using the Adafruit examples does not help. their approach also blocks my Serial2 code.

Warm Regards.

I am glad to hear you found a workaround with the SPI module. As for getting the sensors working with Serial2, it is interesting that trying to do non-blocking reads allows the serial to work, but you are missing some of what you need to actually do the non-blocking reads correctly.

I recommend reviewing the documentation for our VL53L1X Arduino library carefully. As documented in the README for under the “Library reference” header, the default behavior for both read() and readSingle() is to block. You can pass an argument of false to make them not block, but in that case you need to use the dataReady() function to check if valid data is available before retrieving it with read().

I am not sure if the library we link to on the VL53L5CX product page (which is from SparkFun, not Adafruit) includes a good way to read the sensor without blocking.

- Patrick

Thanks for pointing out my mixing up between AdaFruit and SparkFun regarding library usage.

I did see the GitHub note about using read(false) and dataReady(), but I did not have time to get back to this approach yet. I was reading more on the ST’s UM2356 manual for the VL53L1X, and I saw the paragraph below:

which refers to 2 Functions related to DataReady(), but I could not see any reference to them in the two files accessible to me VL53L1X.cpp and VL53L1X.h. Are these two functions implemented in the Pololu library, resulting in the two usages of your Function read(): read(true) and read(false)?

Thank you.

@PatrickM
Thank you very much for the tip about “dataReady()”. It resolved all my issues.

So it looks like that for my setup (using SERCOM service) I have to use a “non-blocking” read(), i.e. read(false).

I am glad to hear that you got it working! Thanks for letting us know.

Just to answer the questions from your previous post, the dataReady() function that I mentioned in my last post should basically be equivalent to the VL53L1_GetMeasurementDataReady() function that you mentioned from the ST API.

There is not a function in our VL53L1X library for Arduino that is directly equivalent to the VL53L1_WaitMeasurementDataReady() function in the ST API, but using read() or read(true) should essentially be the same as using VL53L1_WaitMeasrementDataReady() followed by Vl53L1_GetRangingMeasurementData().

Keep in mind, as documented in the README, while our VL53L1X library for Arduino is based on the VL53L1X API provided by ST, it is intended to be a simplified and streamlined version that is quicker and easier to get started with (and uses less storage and memory), so it does not have some of the more advanced functionality and it has less robust error checking. In case it interests you though, we do have a complete implementation of ST’s VL53L1X API for Arduino available.

- Pastrick