VL53L1X retuning '0 TIMEOUT'

I am trying to use the Pololu library and example code to run 7 VL53L1X sensors on two different I2C busses (Wire1 & Wire2 on a Teensy 3.5).

I have tested all the sensors by themselves and in combinations, but I can’t get the final setup to work.

Here’s the code:

/*
    Name:       VL53L1X_Pololu_V1.ino
    Created:	4/14/2023 4:55:00 PM
    Author:     FRANKNEWXPS15\Frank
*/

/*
This example shows how to set up and read multiple VL53L1X sensors connected to
the same I2C bus. Each sensor needs to have its XSHUT pin connected to a
different Arduino pin, and you should change sensorCount and the xshutPins array
below to match your setup.

For more information, see ST's application note AN4846 ("Using multiple VL53L0X
in a single design"). The principles described there apply to the VL53L1X as
well.

04/22/23 - this example was modified to connect three sensors (RF, RC, RR) to I2C Wire1, and
            four sensors (LF, LC, LR & Rear) to I2C Wire2.  This mimics the hardware arrangment
            used on the actual robot.
*/

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

// The number of sensors in your system.
const uint8_t Wire1sensorCount = 3;
const uint8_t Wire2sensorCount = 4;

// The Arduino pin connected to the XSHUT pin of each sensor.
const uint8_t Wire1xshutPins[Wire1sensorCount] = {23,22,21};//04/14/23
const uint8_t Wire2xshutPins[Wire2sensorCount] = {5,6,7,8};//04/22/23

VL53L1X Wire1sensors[Wire1sensorCount];
VL53L1X Wire2sensors[Wire2sensorCount];

void setup()
{
  while (!Serial) {}
  Serial.begin(115200);
  delay(2000); //04/14/23 needed for Teensy
  Wire.begin();
  Wire1.begin();
  Wire2.begin();

  //move some sensors to Wire1
  for (uint8_t i = 0; i < Wire1sensorCount; i++)
  {
    //sensors[i].setBus(&Wire2);
    Wire1sensors[i].setBus(&Wire1);
  }
  for (uint8_t i = 0; i < Wire2sensorCount; i++)
  {
    //sensors[i].setBus(&Wire2);
    Wire2sensors[i].setBus(&Wire2);
  }

  // Disable/reset all sensors by driving their XSHUT pins low.
  for (uint8_t i = 0; i < Wire1sensorCount; i++)
  {
    pinMode(Wire1xshutPins[i], OUTPUT);
    digitalWrite(Wire1xshutPins[i], LOW);
    Serial.printf("Set pin %d LOW\n", Wire1xshutPins[i]);
  }
  for (uint8_t i = 0; i < Wire2sensorCount; i++)
  {
    pinMode(Wire2xshutPins[i], OUTPUT);
    digitalWrite(Wire2xshutPins[i], LOW);
    Serial.printf("Set pin %d LOW\n", Wire2xshutPins[i]);
  }

  // Enable, initialize, and start each sensor, one by one.
  for (uint8_t i = 0; i < Wire1sensorCount; 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);
    pinMode(Wire1xshutPins[i], INPUT);
    Serial.printf("Set pin %d to INPUT\n", Wire1xshutPins[i]);
    delay(10);

    Wire1sensors[i].setTimeout(500);
    if (!Wire1sensors[i].init())
    {
      Serial.print("Failed to detect and initialize sensor ");
      Serial.println(i);
      while (1);
    }
    else
    {
      Serial.printf("init() succeeded for sensor %d\n", i);
    }

    // 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.
    Wire1sensors[i].setAddress(0x2A + i);

    Serial.printf("sensor %d I2C address set to 0X%X\n",i, Wire1sensors[i].getAddress());

    Wire1sensors[i].startContinuous(50);
  }

  for (uint8_t i = 0; i < Wire2sensorCount; 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);
    pinMode(Wire2xshutPins[i], INPUT);
    Serial.printf("Set pin %d to INPUT\n", Wire2xshutPins[i]);
    delay(10);

    Wire2sensors[i].setTimeout(500);
    if (!Wire2sensors[i].init())
    {
      Serial.print("Failed to detect and initialize sensor ");
      Serial.println(i);
      while (1);
    }
    else
    {
      Serial.printf("init() succeeded for sensor %d\n", i);
    }

    // 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.
    Wire2sensors[i].setAddress(0x2A + i);

    Serial.printf("sensor %d I2C address set to 0X%X\n", i, Wire2sensors[i].getAddress());

    Wire2sensors[i].startContinuous(50);
  }
}

void loop()
{
  Serial.printf("%lu\t", millis());
  for (uint8_t i = 0; i < Wire1sensorCount; i++)
  {
    Serial.print(Wire1sensors[i].read());
    if (Wire1sensors[i].timeoutOccurred()) { Serial.print(" TIMEOUT"); }
    Serial.print('\t');
  }
  for (uint8_t i = 0; i < Wire2sensorCount; i++)
  {
    Serial.print(Wire2sensors[i].read());
    if (Wire2sensors[i].timeoutOccurred()) { Serial.print(" TIMEOUT"); }
    Serial.print('\t');
  }
  Serial.println();
}

And here is the output:

Port closed
Opening port
Port open
Set pin 23 LOW
Set pin 22 LOW
Set pin 21 LOW
Set pin 5 LOW
Set pin 6 LOW
Set pin 7 LOW
Set pin 8 LOW
Set pin 23 to INPUT
init() succeeded for sensor 0
sensor 0 I2C address set to 0X2A
Set pin 22 to INPUT
init() succeeded for sensor 1
sensor 1 I2C address set to 0X2B
Set pin 21 to INPUT
init() succeeded for sensor 2
sensor 2 I2C address set to 0X2C
Set pin 5 to INPUT
init() succeeded for sensor 0
sensor 0 I2C address set to 0X2A
Set pin 6 to INPUT
init() succeeded for sensor 1
sensor 1 I2C address set to 0X2B
Set pin 7 to INPUT
init() succeeded for sensor 2
sensor 2 I2C address set to 0X2C
Set pin 8 to INPUT
init() succeeded for sensor 3
sensor 3 I2C address set to 0X2D
2588	266	251	172	0 TIMEOUT	694	723	831	
3126	287	277	204	0 TIMEOUT	774	800	833	
3645	286	277	205	0 TIMEOUT	763	791	831	
4165	288	275	209	0 TIMEOUT	672	655	832	
4685	287	278	211	0 TIMEOUT	570	584	836	
5205	290	277	207	0 TIMEOUT	638	670	832	
5725	286	278	208	0 TIMEOUT	660	682	832	
6245	290	277	209	0 TIMEOUT	582	637	831	
6765	287	276	207	0 TIMEOUT	560	614	

As you can see, all 7 sensors were initialized properly, but only 6 respond with real distance values. The first sensor on Wire2 returns ‘0 TIMEOUT’.

Any ideas what I’m doing wrong here?

TIA,

Frank

It turned out the problem was caused by a broken connection INSIDE a 4-pin female header - oops!

Also, I realized that I had copy/pasted an old version of the program I am using. The program started off as one of the Pololu examples, and then I further modified it to handle my left, right, or both 3-element VL53L1X sensor arrays. Here is the updated version:

/*
    Name:       VL53L1X_Pololu_V2.ino
    Created:	4/25/2023 5:34:52 PM
    Author:     FRANKNEWXPS15\Frank
*/


/*
    Name:       VL53L1X_Pololu_V1.ino
    Created:	4/14/2023 4:55:00 PM
    Author:     FRANKNEWXPS15\Frank
*/

/*
This example shows how to set up and read multiple VL53L1X sensors connected to
the same I2C bus. Each sensor needs to have its XSHUT pin connected to a
different Arduino pin, and you should change sensorCount and the xshutPins array
below to match your setup.

For more information, see ST's application note AN4846 ("Using multiple VL53L0X
in a single design"). The principles described there apply to the VL53L1X as
well.

04/22/23 - this example was modified to connect three sensors (RF, RC, RR) to I2C Wire1, and
            four sensors (LF, LC, LR & Rear) to I2C Wire2.  This mimics the hardware arrangment
            used on the actual robot.
*/

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

#define LEFT_SIDE
//#define RIGHT_SIDE

// The number of sensors in your system.
const uint8_t Wire1sensorCount = 3;
//const uint8_t Wire2sensorCount = 4;
const uint8_t Wire2sensorCount = 3;

// The Arduino pin connected to the XSHUT pin of each sensor.
const uint8_t Wire1xshutPins[Wire1sensorCount] = { 23,22,21 };//04/14/23
const uint8_t Wire2xshutPins[Wire2sensorCount] = {5,6,7};//04/22/23, post soldering fix
//const uint8_t Wire2xshutPins[Wire2sensorCount] = { 5,6,7,8 };//04/22/23, post soldering fix
//const uint8_t Wire2xshutPins[Wire2sensorCount] = { 6,7,5 };//04/22/23, post soldering fix

VL53L1X Wire1sensors[Wire1sensorCount];
VL53L1X Wire2sensors[Wire2sensorCount];

void setup()
{
  while (!Serial) {}
  Serial.begin(115200);
  delay(2000); //04/14/23 needed for Teensy
  Wire.begin();
  //Wire1.begin();
  //Wire2.begin();
  Wire1.begin(400000);
  Wire2.begin(400000);

#ifdef RIGHT_SIDE
  InitRightSideSensors();
#endif

#ifdef LEFT_SIDE
  InitLeftSideSensors();
#endif


}

void loop()
{
  Serial.printf("%lu\t", millis());
#ifdef RIGHT_SIDE
  for (uint8_t i = 0; i < Wire1sensorCount; i++)
  {
    Serial.print(Wire1sensors[i].read());
    if (Wire1sensors[i].timeoutOccurred()) { Serial.print(" TIMEOUT"); }
    Serial.print('\t');
  }
#endif

#ifdef LEFT_SIDE
  for (uint8_t i = 0; i < Wire2sensorCount; i++)
  {
    Serial.print(Wire2sensors[i].read());
    if (Wire2sensors[i].timeoutOccurred()) { Serial.print(" TIMEOUT"); }
    Serial.print('\t');
  }
#endif
  Serial.println();
}

void InitLeftSideSensors()
{
  //move left-side sensors to Wire2
  for (uint8_t i = 0; i < Wire2sensorCount; i++)
  {
    Wire2sensors[i].setBus(&Wire2);
  }

  // Disable/reset all sensors by driving their XSHUT pins low.
  for (uint8_t i = 0; i < Wire2sensorCount; i++)
  {
    pinMode(Wire2xshutPins[i], OUTPUT);
    digitalWrite(Wire2xshutPins[i], LOW);
    Serial.printf("Set pin %d LOW\n", Wire2xshutPins[i]);
  }

  for (uint8_t i = 0; i < Wire2sensorCount; 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);
    pinMode(Wire2xshutPins[i], INPUT);
    Serial.printf("Set pin %d to INPUT\n", Wire2xshutPins[i]);
    delay(10);

    Wire2sensors[i].setTimeout(500);
    if (!Wire2sensors[i].init())
    {
      Serial.print("Failed to detect and initialize sensor ");
      Serial.println(i);
      while (1);
    }
    else
    {
      Serial.printf("init() succeeded for sensor %d\n", i);
    }

    // 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.
    Wire2sensors[i].setAddress(0x2A + i);

    Serial.printf("sensor %d I2C address set to 0X%X\n", i, Wire2sensors[i].getAddress());

    Wire2sensors[i].startContinuous(50);
  }

}

void InitRightSideSensors()
{
  //move right-side sensors to Wire1
  for (uint8_t i = 0; i < Wire1sensorCount; i++)
  {
    //sensors[i].setBus(&Wire2);
    Wire1sensors[i].setBus(&Wire1);
  }

  // reset all sensors by driving their XSHUT pins low.
  for (uint8_t i = 0; i < Wire1sensorCount; i++)
  {
    pinMode(Wire1xshutPins[i], OUTPUT);
    digitalWrite(Wire1xshutPins[i], LOW);
    Serial.printf("Set pin %d LOW\n", Wire1xshutPins[i]);
  }

  // Enable, set address for and start each sensor
  for (uint8_t i = 0; i < Wire1sensorCount; 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);
    pinMode(Wire1xshutPins[i], INPUT);
    Serial.printf("Set pin %d to INPUT\n", Wire1xshutPins[i]);
    delay(10);

    Wire1sensors[i].setTimeout(500);
    if (!Wire1sensors[i].init())
    {
      Serial.print("Failed to detect and initialize sensor ");
      Serial.println(i);
      while (1);
    }
    else
    {
      Serial.printf("init() succeeded for sensor %d\n", i);
    }

    // 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.
    Wire1sensors[i].setAddress(0x2A + i);

    Serial.printf("sensor %d I2C address set to 0X%X\n", i, Wire1sensors[i].getAddress());

    Wire1sensors[i].startContinuous(50);
  }

}

void GetRightSideDistances()
{

}

void GetLeftSideDistances()
{

}

Cheers,

Frank

2 Likes

Hello.

I am glad to hear that you figured out the problem and that your setup is working now! Thanks for letting us know.

- Patrick

And I was going to suggest that you check the continuity between pin 5 and the XSHUTDOWN pin on the sensor giving you the issues :slight_smile: