Problem with I2C Temporary addresses for VL53L0X distance sensor

I'm using two VL53L0X distance sensors with an arduino nano 33 IoT, which seem to work just great when using the adafruit library and the DUAL example provided by the library. I noticed that when i disconnected the USB cable from the computer and reconnect it, the sensors would stop working.

I ran an I2C scanner to see what was going on. I noticed that after the two sensors succesfully worked, the adresses saved we're indeed the ones i specified for each sensors: 0x30, 0x31. After disconnecting the USB cable and reconnect it, the only address that was detected was 0x29, the default address for the VL53L0X sensor. After this, i reuploaded the code that was perfectly working with the sensors just moments ago, and noticed that the message "Sensor 2 failed to boot" popped up in the serial monitor. After running an I2C adress scanner i noticed that the only adress that was saved was that of the first sensor, 0x30. The "solution" for this problem (i.e for the sensors to work again) i need to swap the adresses, that and reupload the code again. My goal is for the sensors to always work, even after disconnecting and reconnecting the USB cable. I understand that upon disconnecting the USB cable, the adresses are set to default, but in my code i specify which address each sensor needs to have. Any ideas of how it is possible to mantain the addresses even after reconnecting the USB cable? Or is it not possible at all?

This is the code used (It's fairly similar or if not, identical to the DUAL example from the adafruit library addresed in this post).

#include "Adafruit_VL53L0X.h"

// address we will assign if dual sensor is present
#define LOX1_ADDRESS 0x31
#define LOX2_ADDRESS 0x30

// set the pins to shutdown
#define SHT_LOX1 A1
#define SHT_LOX2 A3

// objects for the vl53l0x
Adafruit_VL53L0X lox1 = Adafruit_VL53L0X();
Adafruit_VL53L0X lox2 = Adafruit_VL53L0X();

// this holds the measurement
VL53L0X_RangingMeasurementData_t measure1;
VL53L0X_RangingMeasurementData_t measure2;

void setID() {
  // all reset
  digitalWrite(SHT_LOX1, LOW);    
  digitalWrite(SHT_LOX2, LOW);
  delay(100);
  // all unreset
  digitalWrite(SHT_LOX1, HIGH);
  digitalWrite(SHT_LOX2, HIGH);
  delay(100);

  // activating LOX1 and resetting LOX2
  digitalWrite(SHT_LOX1, HIGH);
  digitalWrite(SHT_LOX2, LOW);
  delay(100);

  // initing LOX1
  if(!lox1.begin(LOX1_ADDRESS)) {
    Serial.println(F("Failed to boot first VL53L0X"));
    while(1);
  }
  delay(100);

  // activating LOX2
  // digitalWrite(SHT_LOX1, LOW);
  digitalWrite(SHT_LOX2, HIGH);
  delay(100);

  // initing LOX2
  if(!lox2.begin(LOX2_ADDRESS)) {
    Serial.println(F("Failed to boot second VL53L0X"));
    while(1);
  }
  // digitalWrite(SHT_LOX1, HIGH);
  }

  void read_dual_sensors() {
  lox1.rangingTest(&measure1, false); // pass in 'true' to get debug data printout!
  lox2.rangingTest(&measure2, false); // pass in 'true' to get debug data printout!

  // print sensor one reading
  Serial.print(F("1: "));
  if(measure1.RangeStatus != 4) {     // if not out of range
    Serial.print(measure1.RangeMilliMeter);
  } else {
    Serial.print(F("Out of range"));
  }

  Serial.print(F(" "));

  // print sensor two reading
  Serial.print(F("2: "));
  if(measure2.RangeStatus != 4) {
    Serial.print(measure2.RangeMilliMeter);
  } else {
    Serial.print(F("Out of range"));
  }

  Serial.println();
  }

  void setup() {
  Serial.begin(115200);

  // wait until serial port opens for native USB devices
  while (! Serial) { delay(1); }

  pinMode(SHT_LOX1, OUTPUT);
  pinMode(SHT_LOX2, OUTPUT);

  Serial.println(F("Shutdown pins inited..."));

  digitalWrite(SHT_LOX1, LOW);
  digitalWrite(SHT_LOX2, LOW);

  Serial.println(F("Both in reset mode...(pins are low)"));

  Serial.println(F("Starting..."));
  setID();
  }

  void loop() {
  read_dual_sensors();
  delay(100);
  }

I have seen this caused by hardware problems. Post an annotated schematic showing exactly how you wired it. A frizzy is a wiring diagram but lousy for troubleshooting. Be sure to show all components, capacitors, resistors, diodes etc.Show all power sources and note any leads over 10"/25cm in length.

Thank you very much for reaching out. Unfortunately, I dont have the Fritzing software to make a schematic, but on the other side, the wiring and hardware are very easy to describe (I'll make a brief description here on this topic and also include a picture. )
Hardware:

  • Nano screw terminal: Nano Screw Terminal Adapter — Arduino Online Shop
  • Nano ethernet Shield (enc28j60)
  • Nano 33 IoT
    Hardware connections description:
  • Nano 33 IoT connected to ethernet shield and shield connected to the screw terminal
    Wiring:
  • Both SDA / SCL wires connected to the same I2C bus on the arduino Nano (pins: A4, A5)
  • Both Vin wires connected to the same pin (3.3V)
  • Both GND wires conneceted to the same pin (GND)
  • XSHUT1 and XSHUT2 connected to analog pins A1 and A3
  • Micro USB cable connected to my computer
    Additional comments:
  • In the picture you can see an ethernet cable, but its not connected to anything. This problem still happens even without the ethernet shield and just the Nano 33 IoT and the screw terminal.

    I hope this helps and please let know if i can provide any other type of info.

Great, that software only creates pictures of items and colored lines. KiCad is a great package and it is free and it does schematics, not makeshift wiring diagrams that frizzy does.

Where are your pull up resistors and what is the total load in ohms on SCL and SDA? Double check your solder connections.

Sorry for getting back to you late. I didn't have the sensors with me until now. I'm new to the I2C communication protocol, but I just measured the resistance between the SDA/SCL and the VIN separately, and both of them range between 5k - 6k Ohms. Apparently, there are pull-up resistors integrated into the sensors, but I'm not quite sure if I need to add more resistors.

The sensors need to be reset and their I2C addresses reassigned every time the Arduino starts up. This ensures they always work correctly, even after a power cycle.
Also add delays between reset and reactivation.

#include "Adafruit_VL53L0X.h"

// Address we will assign if dual sensor is present
#define LOX1_ADDRESS 0x31
#define LOX2_ADDRESS 0x30

// Set the pins to shutdown
#define SHT_LOX1 A1
#define SHT_LOX2 A3

// Objects for the vl53l0x
Adafruit_VL53L0X lox1 = Adafruit_VL53L0X();
Adafruit_VL53L0X lox2 = Adafruit_VL53L0X();

// This holds the measurement
VL53L0X_RangingMeasurementData_t measure1;
VL53L0X_RangingMeasurementData_t measure2;

void setID() {
  // All reset
  digitalWrite(SHT_LOX1, LOW);    
  digitalWrite(SHT_LOX2, LOW);
  delay(100);

  // Activate LOX1 and deactivate LOX2
  digitalWrite(SHT_LOX1, HIGH);
  digitalWrite(SHT_LOX2, LOW);
  delay(100);

  // Initialize LOX1
  if(!lox1.begin(LOX1_ADDRESS)) {
    Serial.println(F("Failed to boot first VL53L0X"));
    while(1);
  }
  delay(100);

  // Activate LOX2
  digitalWrite(SHT_LOX2, HIGH);
  delay(100);

  // Initialize LOX2
  if(!lox2.begin(LOX2_ADDRESS)) {
    Serial.println(F("Failed to boot second VL53L0X"));
    while(1);
  }
}

void read_dual_sensors() {
  lox1.rangingTest(&measure1, false); // Pass in 'true' to get debug data printout!
  lox2.rangingTest(&measure2, false); // Pass in 'true' to get debug data printout!

  // Print sensor one reading
  Serial.print(F("1: "));
  if(measure1.RangeStatus != 4) {     // If not out of range
    Serial.print(measure1.RangeMilliMeter);
  } else {
    Serial.print(F("Out of range"));
  }

  Serial.print(F(" "));

  // Print sensor two reading
  Serial.print(F("2: "));
  if(measure2.RangeStatus != 4) {
    Serial.print(measure2.RangeMilliMeter);
  } else {
    Serial.print(F("Out of range"));
  }

  Serial.println();
}

void setup() {
  Serial.begin(115200);

  // Wait until serial port opens for native USB devices
  while (! Serial) { delay(1); }

  pinMode(SHT_LOX1, OUTPUT);
  pinMode(SHT_LOX2, OUTPUT);

  Serial.println(F("Shutdown pins inited..."));

  // Start with sensors in reset mode
  digitalWrite(SHT_LOX1, LOW);
  digitalWrite(SHT_LOX2, LOW);

  Serial.println(F("Both in reset mode...(pins are low)"));
  Serial.println(F("Starting..."));

  setID(); // Reassign addresses after reset
}

void loop() {
  read_dual_sensors();
  delay(100);
}

1 Like

Thank you very much for also reaching out. This unfortunatley doesn't work, even after adding longer and more delays to ensure that everything is well set-up, it still wouldn't work. I tried this a couple of days ago since Chat-GPT 4 was only giving me this response, just adding more and more delays code after code. I'm leaning more towards the fact that as @gilshultz said, this could be a hardware problem, such as the cables not being well soldered or missing pull-up resistors. Thank you very much for the response though.

I'm pretty sure it was a hardware thing, i bought two vl53l1x sensors and they worked perfectly fine. Still don't know what it is, maybe it was just missing some pull up resistors.