VL53L1X multisensor with two zones each

Good morning,
In my project i need to use two VL53L1X in order to count people walking trough two doors.
With your library (and example: ContinuesMultipleSensor) I’m able to use two sensor in full 16x16 SPAD.
I’m able also to configure just one sensor with two SPADS zones, and works.

But when I try to implement two sensors with two spads each, the sistem doesn’t work properly. It doesn’t seem to change zones as expected.

This is my code:

#include <SPI.h>
#include <Wire.h>
#include <VL53L1X.h>

const uint8_t sensorCount = 2;                   //numero sensori presenti
VL53L1X sensors[sensorCount];                    //array dei sensori
const int xshutPins[sensorCount] = {3, 4};       //array dei pins xShut dei sensori
const int ROICenters[2] = { 167, 223 };   //centri delle 2 zone di ogni sensore
int distances[4];                         //array contenente le misurazioni

void setup() {
  pinMode(1, INPUT);
  digitalWrite(1, HIGH);

  while (!Serial) {}
  Serial.begin(115200);
  Wire.begin();
  Wire.setClock(400000);  // use 400 kHz I2C

  // Disable/reset all sensors by driving their XSHUT pins low.
  for (int i = 0; i < 2; i++) {
    pinMode(xshutPins[i], OUTPUT);
    digitalWrite(xshutPins[i], LOW);
  }

   // Enable, initialize, and start each sensor, one by one.
  for (int i = 0; i < 2; i++) {
    // Stop driving this sensor's XSHUT low. This should allow the carrier
    // board to pull it high. (We do NOT want to drive XSHUT high since it is
    // not level shifted.) Then wait a bit for the sensor to start up.
    pinMode(xshutPins[i], INPUT);
    delay(10);
    sensors[i].setTimeout(500);
    if (!sensors[i].init()) {
      Serial.print("...ERROR failed to detect and initialize sensor ");
      Serial.print(i);
      Serial.println(" !");
      while (1);
    }
    // Each sensor must have its address changed to a unique value other than
    // the default of 0x29 (except for the last one, which could be left at
    // the default). To make it simple, we'll just count up from 0x2A.
    sensors[i].setAddress(0x2A + i);
    Serial.println(sensors[i].getAddress());                
    sensors[i].setDistanceMode(VL53L1X::Long);     // Measuring mode (Long, Medium, Short)
    sensors[i].setMeasurementTimingBudget(50000);  // Timing budget in us (microseconds) (min 33000 in Long mode)
    sensors[i].setROISize(8,16);                   // Dimensione della zona del sensore
    sensors[i].startContinuous(50);                // Start continuous readings at a rate of one measurement every 50 ms (must be at least as long as timebudget)
  }
  delay(2000);
}

void loop() {
  static int stV1;  // stato del varco porta 1
  static int stV2;  // stato del varco porta 1
  static int distdisplay[4];

  for (int i = 0; i < 2; i++) {
  sensors[0].setROICenter(ROICenters[i]);
        distances[0+i] = sensors[0].read();
  }

  for (int i = 0; i < 2; i++) {
    sensors[1].setROICenter(ROICenters[i]);
       distances[2+i] = sensors[1].read();
  }

  Serial.print (distances[0]);
  Serial.print (" : ");
  Serial.print (distances[1]);
  Serial.print (" -- ");
  Serial.print (distances[2]);
  Serial.print (" : ");
  Serial.println (distances[3]);
}

If I comment a “for cicle” of a sensor, the other works as expected.

Thanks for any help

Hello.

Can you try calling the getROICenter() function from our VL53L1X Arduino library in each of the for loops in the main loop() function and printing what they return? That should tell you if the region of interest (ROI) is actually changing between your distance measurements. Can you post a sample Serial Monitor output from that program?

- Patrick

Hi Patrick,
Thank you for your reply

With this code in the loop:

void loop() {
  static int distdisplay[4];

  for (int r = 0; r < 2; r++) {
    sensors[0].setROICenter(ROICenters[r]);
    Serial.println(sensors[0].getROICenter());
    distances[r] = sensors[0].read();
   }

  for (int r = 0; r < 2; r++) {
    sensors[1].setROICenter(ROICenters[r]);
    Serial.println(sensors[1].getROICenter());
    distances[2+r] = sensors[1].read();
   }

  Serial.print(distances[0]);
  Serial.print(" : ");
  Serial.print(distances[1]);
  Serial.print(" -- ");
  Serial.print(distances[2]);
  Serial.print(" : ");
  Serial.println(distances[3]);
}

the Serial prints:

167
223
167
223
2487 : 2497 – 2392 : 2393
167
223
167
223
2493 : 2510 – 2394 : 2395




ROI centers are changed as expected and the 4 measurements are performed.

Passing an obstacle in front of a sensor, this is detected only when it is perpendicular and the two measurements change simultaneously. as follow:
167
223
167
223
470 : 472 – 2392 : 2383
167
223
167
223
474 : 470 – 2387 : 2393
167
223
167
223
499 : 494 – 2390 : 2405


By excluding one sensor, the other works as expected.
Measure separately in the two areas
167
223
426 : 2441 – 0 : 0
167
223
424 : 2435 – 0 : 0
167
223
428 : 2446 – 0 : 0


I made a setup to tinker with your program here. What appears to happen is the read() function is returning a measurement that the sensor took before the setROICenter() function takes effect. The solution I prefer is to disable continuous mode (i.e. remove the sensors[i].startContinuous(50); line) and use the readSingle() function instead. Other work around methods that I found could include adding a delay between calling the setROICenter() and read() functions (a delay around the length of the sensor’s timing budget worked for me) or calling the read() function multiple times (I had to call it three times for it to work consistently).

By the way, I could not repeat the behavior where you are able to get readings from different ROI if you only use a single sensor unless I made one of the modifications I mentioned, so I am not sure why that was working for you.

- Patrick

Hi Patrick,

I used readSingle() instead ReadContinuos(), and it works very well !!!. I don’t know why I didn’t think of it myself…
The other two solutions slow down execution a lot.

Thank you so much for your support

1 Like

I am glad to hear that solution works for you! Thanks for letting us know.

- Patrick