VL53L0X and interrupts

Hi,

I have two VL53L0X sensors connected to an ESP32. I want to capture the time taken to break the two beams, one after the other. Actutal readings are not important. I also want to use interrupts for this to minimise the delays, as the time taken is critical to the project. The code posted below works but, if I put an object in front of both sensors, I was expecting to see a delay of microseconds. As it is, it ranges from about 7ms to 22ms and the time taken seems to ‘creep up’ until it hits the 22ms threshhold, when it then ‘resets’ to 7ms.

eg:

14:55:12.102 → start_usL1 = 12331959
14:55:12.102 → stop_usL1 = 12353657
14:55:12.102 → measured_usL1 = 21688
14:55:12.102 →
14:55:12.134 → start_usL1 = 12363824
14:55:12.134 → stop_usL1 = 12385882
14:55:12.134 → measured_usL1 = 22048
14:55:12.134 →
14:55:12.174 → start_usL1 = 12395970
14:55:12.174 → stop_usL1 = 12418109
14:55:12.174 → measured_usL1 = 22129
14:55:12.174 →
14:55:12.215 → start_usL1 = 12460044
14:55:12.215 → stop_usL1 = 12466478
14:55:12.215 → measured_usL1 = 6424
14:55:12.215 →
14:55:12.247 → start_usL1 = 12492195
14:55:12.247 → stop_usL1 = 12498619
14:55:12.247 → measured_usL1 = 6414
14:55:12.247 →
14:55:12.281 → start_usL1 = 12524254
14:55:12.281 → stop_usL1 = 12530696
14:55:12.281 → measured_usL1 = 6432
14:55:12.281 →
14:55:12.409 → start_usL1 = 12652469
14:55:12.409 → stop_usL1 = 12659905
14:55:12.409 → measured_usL1 = 7426

I’ve tried lots of permutations of this code but haven’t yet managed to get it below 7ms. Please can someone help?

Thanks.


#include <Wire.h>  //I2C library
#include <VL53L0X.h>

// Screen pins
#define TFT_DC 2  //AO
#define TFT_CS 5
#define TFT_RST 4

// Sensor Stuff
#define SENSOR_1_ADDRESS 0x30
#define SENSOR_2_ADDRESS 0x31
#define SENSOR_1_INTERRUPT 25
#define SENSOR_1_SHUTDOWN 19
#define SENSOR_2_INTERRUPT 16
#define SENSOR_2_SHUTDOWN 17
volatile byte sensor_1_State = LOW;
volatile byte sensor_2_State = LOW;
volatile unsigned long interruptMicrosS1;
volatile unsigned long interruptMicrosS2;

int sensor_distance = 60, minDistL1 = 80, maxDistL1 = 100;

//Calibration values
int sensor_1Range1, sensor_1Range2;
int sensor_2Range1, sensor_2Range2;
int sensor_1Offset = 50;
int sensor_2Offset = 50;

bool LR = false;
bool S1L1 = false;
bool S1L2 = false;

VL53L0X sensor_1;
VL53L0X sensor_2;

unsigned long start_usL1, stop_usL1, measured_usL1, waittime = 2000;
float m_per_sL1;
float km_per_hrL1;
float mi_per_hrL1 = 0.00, multiplier = 1.0;
unsigned long start_usL2, stop_usL2, measured_usL2, trigger_start_usL2;
float m_per_sL2;
float km_per_hrL2;
float mi_per_hrL2 = 0.00;


void setID() {
  // all reset
  digitalWrite(SENSOR_1_SHUTDOWN, LOW);
  digitalWrite(SENSOR_2_SHUTDOWN, LOW);
  delay(10);
  // all unreset
  digitalWrite(SENSOR_1_SHUTDOWN, HIGH);
  digitalWrite(SENSOR_2_SHUTDOWN, HIGH);
  delay(10);

  // activating sensor_1 and resetting sensor_2
  digitalWrite(SENSOR_1_SHUTDOWN, HIGH);
  digitalWrite(SENSOR_2_SHUTDOWN, LOW);

  // initiating sensor_1
  Serial.println("S1 start");
  sensor_1.init(true);
  Serial.println("01");
  delay(100);
  sensor_1.setAddress(SENSOR_1_ADDRESS);
  delay(10);

  // activating sensor_2
  digitalWrite(SENSOR_2_SHUTDOWN, HIGH);
  delay(10);

  //initiating sensor_2
  Serial.println("S2 start");
  sensor_2.init(true);
  Serial.println("02");
  delay(100);
  sensor_2.setAddress(SENSOR_2_ADDRESS);
  delay(10);
}

void VL53LOXISR1() {
  sensor_1_State = digitalRead(SENSOR_1_INTERRUPT);
  interruptMicrosS1 = micros();
}

void VL53LOXISR2() {
  sensor_2_State = digitalRead(SENSOR_2_INTERRUPT);
  interruptMicrosS2 = micros();
}

void setup() {

  Serial.begin(115200);
  Wire.begin();
  // wait until serial port opens for native USB devices
  while (!Serial) { delay(1); }
  pinMode(SENSOR_1_SHUTDOWN, OUTPUT);
  pinMode(SENSOR_2_SHUTDOWN, OUTPUT);
  pinMode(SENSOR_1_INTERRUPT, INPUT_PULLUP);
  pinMode(SENSOR_2_INTERRUPT, INPUT_PULLUP);
  attachInterrupt(SENSOR_1_INTERRUPT, VL53LOXISR1, CHANGE);
  attachInterrupt(SENSOR_2_INTERRUPT, VL53LOXISR2, CHANGE);
  Serial.println(F("Shutdown pins initiated..."));
  digitalWrite(SENSOR_1_SHUTDOWN, LOW);
  digitalWrite(SENSOR_2_SHUTDOWN, LOW);
  Serial.println(F("Both in reset mode...(pins are low)"));
  Serial.println(F("Starting..."));
  setID();
  Serial.println("addresses set");
  sensor_1.setTimeout(500);
  sensor_1.setMeasurementTimingBudget(18000);
  sensor_1.startContinuous();
  sensor_2.setTimeout(500);
  sensor_2.setMeasurementTimingBudget(18000);
  sensor_2.startContinuous();

}
void loop() 
{
    //Left to Right - First sensor triggered
    // Lane 1
    if (sensor_1_State == LOW && (sensor_1.readRangeContinuousMillimeters() - sensor_1Offset) < maxDistL1 && (sensor_1.readRangeContinuousMillimeters() - sensor_1Offset) > minDistL1) 
      {
        start_usL1 = interruptMicrosS1;
        S1L1 = true;
      }
    //Left to Right - Second sensor triggered
    if (S1L1 && sensor_2_State == LOW && (sensor_2.readRangeContinuousMillimeters() - sensor_2Offset) > minDistL1 && (sensor_2.readRangeContinuousMillimeters() - sensor_2Offset) < maxDistL1) 
      {
        stop_usL1 = interruptMicrosS2;
      }
    //Take measurements
    if (stop_usL1 != 0) //Lane 1
    {
      measured_usL1 = stop_usL1 - start_usL1 - 10UL;  // -10 microseconds to compensate for code delay
      Serial.print("start_usL1 = ");Serial.println(start_usL1);
      Serial.print("stop_usL1 = ");Serial.println(stop_usL1);
      Serial.print("measured_usL1 = ");Serial.println(measured_usL1);
      Serial.println();
      stop_usL1 = 0;
      S1L1 = false;
      //delay(1000);
    }
}


Hello.

Unfortunately, minimizing the delay between readings to consistently be on the order of microseconds is probably impractical with the VL53L0X. Even using a high speed range profile, each sensor will need around 17 ms at minimum to complete measurements (and you are using a timing budget of 18 ms, which is near the minimum), so it is just not very realistic to expect a time difference of microseconds to be reported consistently.

- Patrick

So, while the interrupts are monitoring the sensor in microseconds, because the VL53L0X is sending out the pulses every 18ms or so, the time captured is dependent on the VL53L0X?

And i guess the ‘drifting’ of the time between the sensors is due to the sensors during at slightly different intervals?

Yes, it sounds like you are understanding correctly.

In case it helps, here is an analogy. If two unsynchronized people are supposed to report whether or not a pot of water at the end of a long hallway is boiling, but it takes them each around one minute, give or take a few seconds, to go up and down the hallway, then both people reporting that the water is boiling within 1 second of each other is pretty unlikely.

- Patrick