VL53LOX multiple sensors in continuous mode

I apologize up front for a “fuzzy” set of data to diagnose my problem…

I have two VL53LOX sensors connected (I2C) to a A* Micro. I use them in continuous mode to minimize the time between readings. To use two sensors I obviously have to change the I2C address of one of them. I successfully unit tested address change and continuous mode (or so I thought) using the pair prior to integrating them into my project.

In my project, sensor address change and initialization are in setup(). loop() looks for incoming commands from Serial. For one command, loop() turns on continuous mode for both sensors, starts reading as fast as possible, and looks at the readings to detect certain conditions. When those conditions occur, loop() turns off continuous mode. It then starts looking for commands again.

Assuming the A* program is loaded, if I power up the sensors (using a power bank), plug in the A* to my laptop, fire up Monitor and send the command, both sensors report valid readings and everything works fine. However, generally this only works for the first command. The vast majority of attempts to repeat the command the sensor with the changed address reports 8190/1 (no report) instead of valid data; the other sensor reports valid data. The only way to fix this that I’ve found is to unplug the A*, remove power to the sensors, power up the sensors, plug in the A*.

I created a simpler test sketch that does something similar (see below). It uses only one sensor with its address changed. The sketch simply starts continuous mode, samples a few times, then stops continuous mode, and repeats the sequence. If simply left running, it does not fail. However, It does sometimes fail as above. The approach that causes failure most easily is: power on the sensors, plug the A* into laptop, start Monitor, run for a bit (will see good data), unplug A*, plug in A* (in essence a reset), kill Monitor, start Monitor. After doing this, the sensor reports 8190/1. Sometimes, the problem occurs when: power on the sensors, plug the A* into laptop, start Monitor, run for a bit (will see good data), kill Monitor, unplug A*, plug in A* (in essence a reset), start Monitor.

I created a sketch that does the same thing, but with no address change. That too would fail using the first approach.

Just to go further, I created a similar sketch that reads both sensors. Same failure (one reads correctly, the one whose address is changed reads 8190/1). The order of reading does not matter; the sensor with the changed address is always the one that fails. The first approach frequently causes a failure. The second approach may not.

I don’t understand at all what is happening. There certainly appears to be something unique about the behavior of the sensor with the changed address. There may be some affect from the use of serial communications. I am hoping for an answer, but would gladly accept suggestions for further diagnosis.

#include <Wire.h>
#include <VL53L0X.h>

VL53L0X sensor;

void setup()
{
  Serial.begin(9600);
  Wire.begin();

  // change address
  sensor.setAddress(44);

  sensor.init();
  sensor.setTimeout(500);
}

void loop()
{
  // take readings
  sensor.startContinuous();

  for (int i = 0; i < 20; i++) {
      Serial.print(sensor.readRangeContinuousMillimeters());
      if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }
      Serial.println();   
  }

  // stop continuous mode
  sensor.stopContinuous();
  delay(200);

  Serial.println(".");
}

Not sure how much it matters, but I switched from continuous mode to single mode in my project code and that seems to work fine and reliably. Unfortunately it takes about 48 ms to do the two readings (vs ~33 ms for continuous), even with the timing budget set to 20 ms.

At least now I can progress while hoping to at some point solve the problem with continuous mode.

Hello.

I was unable to recreate the failure you mention using the code you posted. When I run the code, the first measurement in the set of 20 is 8190/8191, but if I place a small delay (50ms) after sensor.startContinuous(); then all of the readings come back OK. It is worth noting that for my setup, The sensors and A-Star are powered from a set of batteries and disconnecting and reconnecting the A-Star from USB and re-launching the Arduino serial monitor does not reset the A-Star. If you are removing power from the A-Star, then you should also reset the sensors before using them.

How are you toggling the XSHUT pins? Those pins are not level-shifted and are not 5V tolerant, so if you are driving them high (5V) rather than setting the pins they are connected to high impedance and letting the sensor board pull them to VDD (2.8V) it could cause problems.

Also, you might try to add a small electrolytic capacitor to the power supply rail for your sensor boards to see if that helps.

-Nathan

I appreciate the quick answer. I realize the problem is difficult to recreate. Regarding the initial 8190/1 values, I just ignore them in this test. In my real project, I take a reading before starting “real” readings.

Regarding XSHUT – I have two sensors. I toggle XSHUT on only one of them and do not use XSHUT at all on the other. The theory is this: First make the GPIO pin an output and set it low, which takes the XSHUT of one sensor (in my case the left) to ground so the device is held in reset. The create a condition where for one sensor XSHUT is not controlled and pulled high by the pull-ups (the device is enabled) and for one sensor XSHUT is grounded (the device is held in reset). Send an I2C command to the default address to change the device address; this affects only the enabled device (in my case the right). Make the GPIO an input so that it now floats (high impedance?); the sensor pull-ups set the XSHUT voltage level; the device is enabled. At this point, the two sensors are both enabled and have different addresses. The code probably explains it better than I can. I put the sketch that uses both sensors below.

Interesting you should mention the power supply. While doing the testing I mentioned in my original post, the VL53LOX sensors were the only things connected to the A*. In my real project I also have two servos connected to the A*. The A* itself is powered by my laptop or a Raspberry Pi via the USB connector. The servos and the VL53LOX sensors are powered from the same 5V power bank. Of course they share a common ground. When I read one or both of the sensors, one of the servos “chatters”. I suspect noise on the 5V but have not yet proved it. Can you suggest a value for the capacitor? I have values from 2.2 μF to 47 μF.

#include <Wire.h>
#include <VL53L0X.h>

const int TOF_RIGHT_ADDR = 44; // programmed
const int XSHUT_PIN_L = 9;

VL53L0X sensorL;
VL53L0X sensorR;

void setup()
{
  Serial.begin(9600);
  Wire.begin();
  
  // make the GPIO an output pin so that it will drag XSHUT low for left sensor;
  // this leaves the left sensor at the default address (41)
  pinMode(XSHUT_PIN_L, OUTPUT);

  // set the address of the right sensor
  sensorR.setAddress(TOF_RIGHT_ADDR);

  // now make the GPIO an input pin so that XSHUT can float high for left sensor;
  // this allows communication with the left sensor at default address (41)
  pinMode(XSHUT_PIN_L, INPUT);
  delay(10); //For power-up procedure t-boot max 1.2ms "Datasheet: 2.9 Power sequence"

  sensorL.init();
  sensorL.setTimeout(500);
  sensorR.init();
  sensorR.setTimeout(500);

}

void loop()
{

  // take readings in continuous mode
  sensorL.startContinuous();
  sensorR.startContinuous();

  for (int i = 0; i < 20; i++) {
//    Serial.print(sensorL.readRangeContinuousMillimeters());
    Serial.print(sensorR.readRangeContinuousMillimeters());
    Serial.print("\t");
    if (sensorL.timeoutOccurred()) { Serial.print(" TIMEOUT"); }
//    Serial.print(sensorR.readRangeContinuousMillimeters());
    Serial.print(sensorL.readRangeContinuousMillimeters());
    if (sensorR.timeoutOccurred()) { Serial.print(" TIMEOUT"); }
    Serial.println();   
  }

  // stop continuous mode
  sensorL.stopContinuous();
  sensorR.stopContinuous();
  delay(200);

  Serial.println(".");
}

I tried that code and the way it operates seems to be OK. A 47uF capacitor should work well.

If you are still having problems, you might post a video that shows the issue.

-Nathan

Hi Nathanb, I have a question to you. How many measurement sensor will take per second, if i define VL53L0X_startContinuous(0).

The measurement frequency also depends on the timing budget (which can be changed), but it sounds like you might be talking about the “Continuous.ino” example sketch in our library, which will take about 33 measurements per second. By the way, there is no need to pass in a “0” inter-measurement period argument; if you use that example as written, the sensor will take measurements back to back.

You might look at the Ranging profile phases section of the VL53L0X datasheet for more about factors affecting the sampling frequency.

-Nathan

I mean if I write VL53L0X_startContinuous(100), how may measurements i will get per second, Is it 10 measurements per second?

Yes, it is 10 measurements per second.

-Nathan