cancel
Showing results for 
Search instead for 
Did you mean: 

Multiple VL53L0X sensor array intermittently returning bad (-1) distances

FPayn.1
Associate II

I have 7 VL53L0X sensors on a robot platform, all connected to a Teensy 3.5 via a very short I2C daisy-chain. I have all 7 configured for continuous measurement with a timing budget of 20mSec. The Teensy loops through all 7 sensors, retrieving distance data as fast as possible. The Teensy code that does this is shown here: (I couldn't put it in-line due to length constraints, but a representative portion is shown below)

In setup():
 
 
  //from Pololu forum post
  lidar_LR.setMeasurementTimingBudget(20000);
  lidar_LR.startContinuous();
 
  lidar_LR.setAddress(DEFAULT_VL53L0X_ADDR + 6);
  Serial.printf("lidar_LR address is 0x%x\n", lidar_LR.getAddress());
 
In Loop():
  LR_Dist_mm = lidar_LR.readRangeContinuousMillimeters();
 

When the Teensy code runs, I get the following output, which indicates that all 7 sensors are capable of reporting distance information very rapidly, as the loop repeat interval is on the order of 15-20 mSec.

Port closed
Uploading to I/O board
Opening port
Port open
lidar_RF address is 0x2a
lidar_RC address is 0x2b
lidar_RR address is 0x2c
lidar_LF address is 0x2d
lidar_LC address is 0x2e
lidar_LR address is 0x2f
lidar_Rear address is 0x30
Msec	LFront	LCtr	LRear	RFront	RCtr	RRear	LSteer	RSteer	Rear
5847	527	8191	598	312	391	365	-0.71	-0.53	951
5865	518	467	498	319	373	370	0.20	-0.51	903
5884	509	484	8191	318	381	356	-76.82	-0.38	942
5902	526	556	699	321	380	360	-1.73	-0.39	940
5920	526	595	589	325	390	360	-0.63	-0.35	956

The Teensy is a slave device up on a separate I2C bus managed by the main robot controller. The main controller requests distance information every 100mSec via a call to the Teensy's requestEvent() function. This function simply transmits the distance readings over the I2C bus to the main controller, as follows:

    //left side  
    I2C_writeAnything(LF_Dist_mm);
    I2C_writeAnything(LC_Dist_mm);
    I2C_writeAnything(LR_Dist_mm);
    I2C_writeAnything(LeftSteeringVal);
 
    //right side
    I2C_writeAnything(RF_Dist_mm);
    I2C_writeAnything(RC_Dist_mm);
    I2C_writeAnything(RR_Dist_mm);
    I2C_writeAnything(RightSteeringVal);
 
    //10/31/20 now also reporting rear sensor value
    I2C_writeAnything(Rear_Dist_mm);

When the main controller first starts up, it waits for VL53L0X data from the Teensy 3.5 to become valid, showing this:

Checking for Teensy 3.5 VL53L0X Controller at I2C addr 0x20
1375: VL53L0X Teensy Not Avail...
1461: VL53l0x - -1, -1, -1, -1, -1, -1, -1
1478: VL53L0X Teensy Not Avail...
1559: VL53l0x - -1, -1, -1, -1, -1, -1, -1
1579: VL53L0X Teensy Not Avail...

and then this:

Teensy setup() finished at 6059 mSec
Msec	LFront	LCtr	LRear	RFront	RCtr	RRear	Rear
6061: 559	540	541	313	393	354	934
VL53L0X Teensy Ready at 6063

During operation, the main controller requests distance information every 100 mSec via an interrupt timer. VL53L0X data is returned looking like this:

Msec	LF	LC	LR	RF	RC	RR
11324: VL53l0x - 513, 550, 553, 316, 392, 358, 912
11421: VL53l0x - 527, 587, 8191, 321, 386, 358, 900
11520: VL53l0x - 533, 585, 565, 314, 376, 362, 945
11618: VL53l0x - 542, 531, 595, 309, 370, 357, 950
11717: VL53l0x - 500, 588, 602, 319, 389, 369, 952
11814: VL53l0x - 522, 637, 642, 314, 379, 355, 926
11912: VL53l0x - 555, 8191, 552, 320, 388, 347, 906

However, under circumstances (and I'm not really sure yet what those are), I start getting bad data from the VL53L0X array. When this happens, one or more (usually all) of the VL53L0X sensors starts reporting '-1' for distance, like the following:

11324: VL53l0x - -1, -1, -1, -1, -1, -1, -1

Once the Teensy starts reporting bad data it usually stays bad forever (or until I reboot the robot). I've been tearing my hair (what's left, anyway) out over this, trying to figure out what is causing this, but haven't made much progress.

The only thing I have been able to come up with is that the I2C requests to the Teensy (via the 100 mSec request interval timer noted above) are interrupting the Teensy measurement loop at some point in the measurement cycle that intermittently causes that sensor (and all the following sensors) to report bad distance data, but I have no idea what that might be.

So, my question is - under what circumstances would a valid sensor measurement request via a 'lidar_RF.readRangeContinuousMillimeters()' call return -1 instead of the actual measurement data, assuming the sensor has been properly initialized and has been running fine for an essentially infinite amount of time.

Any thoughts/clues would be appreciated

TIA,

Frank

10 REPLIES 10
John E KVAM
ST Employee

Frank -

The VL53L0X sensor will not return a -1. The user manual does define a -1 error, but it states that this cannot happen.

What does return a -1 is an I2C timeout.

And I think that is what is killing you.

The I2C is notorius for being basically unreliable. And the major symptom of a dropped bit (the most likely failure), is that the bus is stuck low. (When nothing is being transmitted both the clock and data lines should be high.)

Philips designed the I2C bus and NXP bought Philips. So the NXP site has some documentation on how to tweek the bus. I'd read and understand that.

One other possibility is that one or more of the senors rebooted - perhaps due to power glitch.

If this happens the sensor will revert to it's base I2C address.

If you've changed all your addresses there should be nothing at address 0x29 (0x52/0x53).

You could occationaly ping the base address - and if you ever got an answer, you would would know you had a reboot of some kind.

  • john

If this or any post solves your issue, please mark them as 'Accept as Solution' It really helps. And if you notice anything wrong do not hesitate to 'Report Inappropriate Content'. Someone will review it.
John E KVAM
ST Employee

if you detect a I2C "Bus stuck low", clock a series of bits and the bus will eventually clear. It can take up to 8 clocks however.

the problem is that a sensor saw 8 bits and you only sent 7. The 'ghost' bit was simply a noise glitch on the line.

That extra bit means the master and slave are out of sync.

By sending a bunch of clocks from the master the sensor will eventally give up and quit trying to drive the bus.

At that point you can continue.


If this or any post solves your issue, please mark them as 'Accept as Solution' It really helps. And if you notice anything wrong do not hesitate to 'Report Inappropriate Content'. Someone will review it.
FPayn.1
Associate II

John,

Thanks for the quick and informative replies. I think you might be onto something with the 'stuck' I2C bus idea.

The problem *seems* to occur most often when the robot connects to it's charging station, which involves a fair bit of physical shock as it drives itself onto a charging probe. It's possible that the I2C bus daisy chain gets interrupted momentarily when this happens and causes one or more sensors to lose sync.

Let me try some things along those lines and I'll get back to you. I did move all the sensors off the default address, so I should be able to detect if one or more get rebooted. Would you care to hazard a guess as to what would happen with an I2C address 'ping' if two or more sensors wind up at the default address?

TIA,

Frank

John E KVAM
ST Employee

Lots of people accidentially end up with multiple sensors at the same address.

And the system seems to work.

For all those answers -like ChipID queries - you will never be able to tell that there are multiple chip answering. They put the same data on the bus.

For queries with different data, one chip always seems to 'win' and you get valid responses. Most of the time.

but in your case, I'd try asking for a chip ID on address 0x29.

If you ever get a response, you should shut them all down and start again.

Good luck,

  • john


If this or any post solves your issue, please mark them as 'Accept as Solution' It really helps. And if you notice anything wrong do not hesitate to 'Report Inappropriate Content'. Someone will review it.
FPayn.1
Associate II

John,

Thanks for the very informative reply. In the process of troubleshooting this problem, I realized that the daisy-chain wiring for the sensor arrays was a likely culprit, and so I set about eliminating as much of the hand-soldered wiring as possible (see this post if you are interested in the details). After installing the new boards, I was still experiencing occasional dropouts, but I was able to trace that down to a bad ground connection in one of the remaining 4-pin connectors. After fixing that, everything seems to be much more reliable.

After getting everything back to 'more-or-less' normal, I decided to experiment a bit with your idea of resetting all the sensors after detecting sensor response at the default address . At first I tried disconnecting the I2C connector momentarily, but this did not cause the sensor to shift addresses; everything came right back up properly as soon as the I2C connection was restored.

Next I tried momentarily disconnecting the +V line to the sensor arrays. This caused one or more of the sensors to show up at the default address, so I thought I was on the right track. However, I couldn't get the sensors to re-initialize - once they went off-track, they stayed that way. The only way I could get the sensors back on line was to remove and re-apply power from/to the microcontroller (a Teensy 3.5).

I can't post the entire code here due to length restrictions, so I put everything in my blog post, and attached the file below. Sorry for making you read through my blathering, but I couldn't see any other way to do it :sleepy_face:

Any thoughts?

FPayn.1
Associate II

John,

OK, I think I figured this out; the problem was that the software objects representing the sensors were statically allocated at global scope, and power cycling the sensor breaks that connection. When the InitAllSensors() routine is used the second time, the software objects are no longer connected to the actual sensors.

The solution is to use dynamic rather than static allocation for the software objects representing the sensors. Here's a snippet showing the technique (using just one sensor to prove the concept - the final code will of course use all seven sensors split over two different I2C busses):

At global scope:

VL53L0X* p_RF = 0;

In 'setup()':

//03/22/21 sensor init abstracted to function so can call from loop()
  bool bSensors1OK = InitWire1Sensors();
  Serial.printf("Just after InitWire1Sensors()\n");
 
  if (!bSensors1OK)
  {
    Serial.printf("Sensor initialization failed on Wire1 - quitting!\n");
    while (true)
    {
 
    }
  }
 
  bool bSensors2OK = InitWire2Sensors();
  Serial.printf("Just after InitWire2Sensors()\n");
 
  if (!bSensors2OK)
  {
    Serial.printf("Sensor initialization failed on Wire2 - quitting!\n");
    while (true)
    {
 
    }
  }

In InitWire1Sensors():

bool InitWire1Sensors()
{
  Serial.printf("Initializing VL53L0X Sensor Array Elements\n");
 
  //Put all sensors in reset mode by pulling XSHUT low
  digitalWrite(RF_XSHUT_PIN, LOW);
  digitalWrite(RC_XSHUT_PIN, LOW);
  digitalWrite(RR_XSHUT_PIN, LOW);
 
  digitalWrite(LF_XSHUT_PIN, LOW);
  digitalWrite(LC_XSHUT_PIN, LOW);
  digitalWrite(LR_XSHUT_PIN, LOW);
 
  //added 10/23/20 for rear sensor
  pinMode(Rear_XSHUT_PIN, OUTPUT);
  digitalWrite(Rear_XSHUT_PIN, LOW);
 
 
  //now bring lidar_RF only out of reset and set it's address
  //input w/o pullups sets line to high impedance so XSHUT pullup to 3.3V takes over
  pinMode(RF_XSHUT_PIN, INPUT);
  delay(10);
 
  bool retval = true;
 
  if (p_RF)
  {
    delete p_RF;
    p_RF = 0;
  }
  p_RF = new VL53L0X(&Wire1);
  Serial.printf("p_RF created at %x\n", p_RF);
  if (!p_RF->init())
  {
    Serial.println("Failed to detect and initialize RF sensor!");
    //while (1) {}
    retval = false;
  }
  else
  {
    Serial.printf("p_RF successfully initialized at %x\n", p_RF);
    p_RF->setMeasurementTimingBudget(20000);
    p_RF->startContinuous();
 
 
    p_RF->setAddress(DEFAULT_VL53L0X_ADDR + 1);
    Serial.printf("p_RF address is 0x%x\n", p_RF->getAddress());
 
  }
  return retval;
}

And the output from a representative run:

Opening port
Port open
Initializing VL53L0X Sensor Array Elements
p_RF created at 1fff1470
In VL53L0X::init() top; this = 1fff1470 In VL53L0X::init() after readReg with id = ee, In VL53L0X::init() after readReg/writeRegIn VL53L0X::init() bottom
p_RF successfully initialized at 1fff1470
p_RF address is 0x2a
Just after InitAllSensors()
Msec	LFront	LCtr	LRear	RFront	RCtr	RRear	LSteer	RSteer	Rear
p_RF dist = 370
p_RF dist = 371
p_RF dist = 375
p_RF dist = 372
p_RF dist = 374
p_RF dist = 370
p_RF dist = 368
p_RF dist = 371
p_RF dist = 370
p_RF dist = 367
p_RF dist = 370
p_RF dist = 372
p_RF dist = 374
p_RF dist = 374
p_RF dist = 377
p_RF dist = 65535  <<< power removed here
p_RF dist = 65535
p_RF dist = 65535
p_RF dist = 65535
p_RF dist = 65535
p_RF dist = 65535 <<< power restored here
Ooops! found a VL53L0X sensor at 29 on Wire1!
Initializing VL53L0X Sensor Array Elements
p_RF created at 1fff1470
In VL53L0X::init() top; this = 1fff1470 In VL53L0X::init() after readReg with id = ee, In VL53L0X::init() after readReg/writeRegIn VL53L0X::init() bottom
p_RF successfully initialized at 1fff1470
p_RF address is 0x2a
p_RF dist = 371
p_RF dist = 380
p_RF dist = 383
p_RF dist = 379
p_RF dist = 376
p_RF dist = 374
p_RF dist = 379
p_RF dist = 376
 
Port closed

Assuming I haven't designed in a memory leak, this should work fine for all seven sensors.

Any thoughts or comments?

TIA,

Frank

John E KVAM
ST Employee

Any design that can survive a power glitch has my seal of approval. I unfortunately did not have time to read your code in detail, but if you are willing to share it here, may I suggest you share it on GitHub. Lots of people look there for examples. It's a great resource.

My comments.

Two points to Pololu. Along with Sparkfun they have done a lot to get the ToF sensors into really small MCUs.

I thought it was interesting you started the sensors ranging and then changed the addresses. I would have done it the other way round, but there is no reason your logic would not work.

I think you are on solid footing here.

good luck,

  • john

If this or any post solves your issue, please mark them as 'Accept as Solution' It really helps. And if you notice anything wrong do not hesitate to 'Report Inappropriate Content'. Someone will review it.
FPayn.1
Associate II

John,

May have spoken too soon D:

Everything works as desired for one sensor (as shown above). However, when I add a second sensor, that second sensor fails to initialize properly after the power cycle; it fails on the following code in init():

bool VL53L0X::init(bool io_2v8)
{
  // check model ID register (value specified in datasheet)
  //if (readReg(IDENTIFICATION_MODEL_ID) != 0xEE) { return false; }
  uint16_t id = readReg(IDENTIFICATION_MODEL_ID);
  Serial.printf("In VL53L0X::init() after readReg with id = %x\n", id);
  if (id != 0xEE)
  {
    
    return false; 
  }
 

So it is getting 'ff' instead of 'ee' from the readReg(IDENTIFICATION_MODEL_ID) call. Here's the relevant output from m test program:

Opening port
Port open
At top of setup(), free mem = 256879
Initializing VL53L0X Sensor Array Elements on Wire1
p_RF created at 1fff1470
In VL53L0X::init() after readReg with id = ee
In VL53L0X::init() after readReg/writeReg
In VL53L0X::init() after getSpadInfo()
In VL53L0X::init() before performSingleRefCalibration()
In VL53L0X::init() before performSingleRefCalibration()
In VL53L0X::init() bottom
p_RF successfully initialized at 1fff1470
p_RF address is 0x2a
p_RC created at 1fff1490
In VL53L0X::init() after readReg with id = ee
In VL53L0X::init() after readReg/writeReg
In VL53L0X::init() after getSpadInfo()
In VL53L0X::init() before performSingleRefCalibration()
In VL53L0X::init() before performSingleRefCalibration()
In VL53L0X::init() bottom
p_RC successfully initialized at 1fff1490
p_RC address is 0x2b
Free Memory just after InitWire1Sensors() = 253879
Msec	LFront	LCtr	LRear	RFront	RCtr	RRear	LSteer	RSteer	Rear
5476	351	322	0	0	0	0	0
5578	337	328	0	0	0	0	0
5681	341	333	0	0	0	0	0
5783	346	327	0	0	0	0	0
5886	341	333	0	0	0	0	0
5989	346	330	0	0	0	0	0
10263	65535	65535	0	0	0	0	0
10423	65535	65535	0	0	0	0	0
10583	65535	65535	0	0	0	0	0
10743	65535	65535	0	0	0	0	0
Ooops! found a VL53L0X sensor at 29 on Wire1!
Initializing VL53L0X Sensor Array Elements on Wire1
p_RF created at 1fff1470
In VL53L0X::init() after readReg with id = ee
In VL53L0X::init() after readReg/writeReg
In VL53L0X::init() after getSpadInfo()
In VL53L0X::init() before performSingleRefCalibration()
In VL53L0X::init() before performSingleRefCalibration()
In VL53L0X::init() bottom
p_RF successfully initialized at 1fff1470
p_RF address is 0x2a
p_RC created at 1fff1490
In VL53L0X::init() after readReg with id = ff
Failed to detect and initialize RC sensor!
Free Memory just after InitWire1Sensors() = 253847
10942	322	65535	0	0	0	0	0
11044	320	65535	0	0	0	0	0
11146	324	65535	0	0	0	0	0
11248	322	65535	0	0	0	0	0
11350	264	65535	0	0	0	0	0
11452	324	65535	0	0	0	0	0
11554	323	65535	0	0	0	0	0
11656	267	65535	0	0	0	0	0

And here is the code that initializes both sensors:

bool InitWire1Sensors()
{
  Serial.printf("Initializing VL53L0X Sensor Array Elements on Wire1\n");
  bool retval = true;
 
  //Put all sensors in reset mode by pulling XSHUT low
  digitalWrite(RF_XSHUT_PIN, LOW);
  digitalWrite(RC_XSHUT_PIN, LOW);
  digitalWrite(RR_XSHUT_PIN, LOW);
 
  digitalWrite(LF_XSHUT_PIN, LOW);
  digitalWrite(LC_XSHUT_PIN, LOW);
  digitalWrite(LR_XSHUT_PIN, LOW);
 
  //added 10/23/20 for rear sensor
  pinMode(Rear_XSHUT_PIN, OUTPUT);
  digitalWrite(Rear_XSHUT_PIN, LOW);
 
 
  //now bring lidar_RF only out of reset and set it's address
  //input w/o pullups sets line to high impedance so XSHUT pullup to 3.3V takes over
  pinMode(RF_XSHUT_PIN, INPUT);
  delay(10);
 
  //right-front
  if (p_RF)
  {
    delete p_RF;
    p_RF = 0;
  }
 
  p_RF = new VL53L0X(&Wire1);
  Serial.printf("p_RF created at %x\n", p_RF);
  if (!p_RF->init())
  {
    Serial.println("Failed to detect and initialize RF sensor!");
    retval = false;
  }
  else
  {
    Serial.printf("p_RF successfully initialized at %x\n", p_RF);
    p_RF->setMeasurementTimingBudget(20000);
    p_RF->startContinuous();
 
 
    p_RF->setAddress(DEFAULT_VL53L0X_ADDR + 1);
    Serial.printf("p_RF address is 0x%x\n", p_RF->getAddress());
  }
 
  //right-center
  pinMode(RC_XSHUT_PIN, INPUT);
  delay(10);
 
  if (p_RC)
  {
    delete p_RC;
    p_RC = 0;
  }
 
  p_RC = new VL53L0X(&Wire1);
  Serial.printf("p_RC created at %x\n", p_RC);
  if (!p_RC->init())
  {
    Serial.println("Failed to detect and initialize RC sensor!");
    retval = false;
  }
  else
  {
    Serial.printf("p_RC successfully initialized at %x\n", p_RC);
    p_RC->setMeasurementTimingBudget(20000);
    p_RC->startContinuous();
 
 
    p_RC->setAddress(DEFAULT_VL53L0X_ADDR + 2);
    Serial.printf("p_RC address is 0x%x\n", p_RC->getAddress());
  }
 
  Serial.printf("Free Memory just after InitWire1Sensors() = %d\n", freeMemory());
 
  return retval;
}

So, at the moment I can get any number (well, up to 7 anyways) sensors to initialize on a static basis, but they can't survive a power cycle. I can get ONE to init and survive a power cycle, but I'm having trouble with getting a second one to init AND survive the power cycle.

I think I'm doing something obvious wrong, but for the life of me I can't see it <grrrr>

Thoughts?

Frank

FPayn.1
Associate II

After some further experimentation on the idea of fly-wheeling through a power cycle, I realized that at least one of the sensors responded at I2C address 29 just after the power was removed from the array, so re-initializing the array immediately after a default address detection wasn't going to work - the program would be attempting to re-initialize unpowered sensors.

So, I modified the program to accommodate default address detection "on the way down", followed by default address detection after power was restored to the array. Unfortunately I found that the sensors never stopped responding at the default address - they were apparently receiving enough power via the I2C bus to continue responding to I2C activity. The only way to get them to stop responding was to physically connect the power lead to ground - just interrupting the power line was not sufficient.

Here's the modified program, and the output from a run where I first disconnected the power, and then after a short period, connected the power lead physically to ground, then reconnected the power to the array:

The loop() function:

void loop()
{
  RF_Dist_mm = p_RF->readRangeContinuousMillimeters();
  RC_Dist_mm = p_RC->readRangeContinuousMillimeters();
 
  Serial.printf("%lu\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", 
    millis(), RF_Dist_mm, RC_Dist_mm, RR_Dist_mm, LF_Dist_mm, LC_Dist_mm, LR_Dist_mm, Rear_Dist_mm);
 
 
 
  delay(100);
 
  //03/25/21 see if any VL53L0X responds to a query at the default address
  Wire1.beginTransmission(DEFAULT_VL53L0X_ADDR);
  if (!Wire1.endTransmission() != 0)
  {
    Serial.printf("%lu: Ooops! found a VL53L0X sensor at %x on Wire1!\n", millis(), DEFAULT_VL53L0X_ADDR);
    delay(100);
 
    //this detection could have occurred while the power was going down, so we have to check
    bool bPowerDown = false;
    while (!bPowerDown)
    {
      Wire1.beginTransmission(DEFAULT_VL53L0X_ADDR);
      if (!Wire1.endTransmission() != 0)
      {
        Serial.printf("%lu: Ooops! found a VL53L0X sensor at %x on Wire1!\n", millis(), DEFAULT_VL53L0X_ADDR);
        delay(100);
      }
      else
      {
        Serial.printf("%lu: No longer finding a VL53L0X sensor at %x on Wire1!\n", millis(), DEFAULT_VL53L0X_ADDR);
        bPowerDown = true;
      }
    }
 
    //OK, we know the power is all the way down.  Now we wait for the power to come back up
      bool bPowerIsUP = false;
      while (!bPowerIsUP)
      {
        Wire1.beginTransmission(DEFAULT_VL53L0X_ADDR);
        if (!Wire1.endTransmission() != 0)
        {
          Serial.printf("%lu: Ooops! found a VL53L0X sensor at %x on Wire1!\n", millis(), DEFAULT_VL53L0X_ADDR);
          bPowerIsUP = true;
        }
        else
        {
          delay(100);
          Serial.printf("%lu: checking...\n", millis());
        }
      }
 
      Serial.printf("Waiting 5 sec for power to stabilize\n");
      delay(5000);
      InitWire1Sensors();
  }
}

The output:

Opening port
Port open
At top of setup(), free mem = 256883
Initializing VL53L0X Sensor Array Elements on Wire1
p_RC created at 1fff1470
p_RC successfully initialized at 1fff1470
p_RC address is 0x2b
p_RF created at 1fff1490
p_RF successfully initialized at 1fff1490
p_RF address is 0x2a
Free Memory just after InitWire1Sensors() = 253879
Msec	LFront	LCtr	LRear	RFront	RCtr	RRear	LSteer	RSteer	Rear
6567	343	318	0	0	0	0	0
6669	353	309	0	0	0	0	0
6772	336	319	0	0	0	0	0
6874	352	320	0	0	0	0	0
6977	338	320	0	0	0	0	0
9231	344	316	0	0	0	0	0
....
10460	329	315	0	0	0	0	0
10563	332	317	0	0	0	0	0
10665	340	320	0	0	0	0	0
10768	338	319	0	0	0	0	0
10870	337	312	0	0	0	0	0
10973	346	312	0	0	0	0	0
11073: Ooops! found a VL53L0X sensor at 29 on Wire1!  << power disconnected
11173: Ooops! found a VL53L0X sensor at 29 on Wire1!
11273: Ooops! found a VL53L0X sensor at 29 on Wire1!
11373: Ooops! found a VL53L0X sensor at 29 on Wire1!
11473: Ooops! found a VL53L0X sensor at 29 on Wire1!
11573: Ooops! found a VL53L0X sensor at 29 on Wire1!
11674: Ooops! found a VL53L0X sensor at 29 on Wire1!
11774: Ooops! found a VL53L0X sensor at 29 on Wire1!
...
37609: Ooops! found a VL53L0X sensor at 29 on Wire1!
37709: Ooops! found a VL53L0X sensor at 29 on Wire1!
37810: Ooops! found a VL53L0X sensor at 29 on Wire1!
37910: Ooops! found a VL53L0X sensor at 29 on Wire1!
38027: No longer finding a VL53L0X sensor at 29 on Wire1! << power line connected to GND
38132: checking...
38237: checking...
38342: checking...
38447: checking...
38552: checking...
41072: checking...
...
41177: checking...
41282: checking...
41387: checking...
41492: checking...
41492: Ooops! found a VL53L0X sensor at 29 on Wire1! << disconnected from GND
Initializing VL53L0X Sensor Array Elements on Wire1
Waiting 5 sec for power to stabilize  << need to get power reconnected within 5 sec
Initializing VL53L0X Sensor Array Elements on Wire1
p_RC created at 1fff1470
p_RC successfully initialized at 1fff1470
p_RC address is 0x2b
p_RF created at 1fff1490
p_RF successfully initialized at 1fff1490
p_RF address is 0x2a
Free Memory just after InitWire1Sensors() = 253831
25668	324	299	0	0	0	0	0
25770	338	299	0	0	0	0	0
25872	327	300	0	0	0	0	0
25975	325	297	0	0	0	0	0
26077	326	297	0	0	0	0	0
26180	330	295	0	0	0	0	0
26282	324	300	0	0	0	0	0
26385	317	299	0	0	0	0	0
26487	319	300	0	0	0	0	0
26590	333	295	0	0	0	0	0
26692	334	305	0	0	0	0	0
26795	326	297	0	0	0	0	0
26897	324	303	0	0	0	0	0
27000	329	297	0	0	0	0	0

So, it appears that detecting a sensor response at the default address is a necessary but not sufficient condition, as the module will continue to respond even with the power supply disconnected; re-initialization will fail unless the power interruption ceases before the re-init code runs. Even worse, the failure mode is an unrecoverable infinite hangup in the re-init code.

The only sure way to get the sensors to stop responding to address requests even with the power disconnected is to physically connect the power line to GND, but this is obviously an impractical way to handle an unplanned power interruption.

So, is there any way to determine if a sensor that is responding at the default I2C address is actually powered up or is just 'floating' on the I2C bus? I tried asking the 'sensor' (or whatever was out there responding at the default address) for a distance reading, and it was quite happy to give me a distance value of '65535', so that's not very helpful.

Ideas?

Frank