I2C issues when using 2-VL6180X IR sensors

Hello guys,

I have experience in programming Matlab and Simulink and now decided to branch out in building a simple Arduino project, which immediately showed me my limitations. >:(

My objective is simple. Get the readings from 2 IR sensors (VL6180X - Breakout from Pololu). Then take the height delta and have a servo adjust to compensate. For 1 sensor I have a fully working progamme.

Anyways after consulting google I found some helpful leads regarding my problem with using 2 sensors (datasheet and I2C adressing), but it did not quite get everything working.
Following links proved helpful:

https://learn.sparkfun.com/tutorials/vl6180-hookup-guide/discuss

More specifically myquestions are:
1.) The Adafruit datasheet specifies that when using multiple breakouts the I2C pull up resistors need to be removed by soldering. Does this apply for the Pololu version too?
2.) Do I specifically have to write a high/low on the GPI00 pin at every step (see main part of program code below)?
3.) If connecting 2 IR sensors am I correct in connecting both Vin and GPI00? I seem to have read that only GPI00 is needed, but am not 100% sure.

I have written a simple version of the code to just get the output from the 2 sensors as I am comfortable with coding the rest and hopefully this makes debugging easier…

My apologies for writing such a long essay, but I hope it helps in explaining my issues. It has now been annoying me for quite a while…
I greatly appreciate your help! Thank you in advance!

#include <VL6180X.h>
#include <Wire.h>

// IR Sensor Definitions
VL6180X sensor1;                                     // Sensor that measures from Servo to plate
VL6180X sensor2;                                     // added, need to check I2C classes and directories. Servo that measures from Servo to top of air bearing.
int sensor1_pin = 50, sensor2_pin = 52;              // Digital Pins to set GPI00 High or low.



void setup() {

Serial.begin(9600);                                 // Run at the highest possible baud rate.
Wire.begin();                                       // Initialise the library to get analog readings from the different Pins.
  
  pinMode(sensor1_pin, OUTPUT);                     // IR sensor calibration and activation.
  pinMode(sensor2_pin, OUTPUT);
  digitalWrite(sensor1_pin, LOW);
  digitalWrite(sensor2_pin, LOW);
  Serial.begin(9600);                               // Begin serial transmission of data. 
  Wire.begin();                         

 // Sensor 1:
  digitalWrite(sensor1_pin, HIGH);                  // Switch on IR sensor 1.
  delay(50);                                        // 50ms second delay for sensor to come out of standby.
    sensor1.init();                                 // Initialise sensor 1.
    sensor1.configureDefault();                     // Load default configuration of sensor.
    sensor1.setTimeout(500);                        // Timeout time of sensor 0.5 seconds.
    sensor1.setAddress(0x54);                       // Set I2C adress as for memory allocation as 0x54.
  digitalWrite(sensor1_pin,LOW);
  
  // Sensor 2:
 digitalWrite(sensor2_pin, HIGH);                   // Switch on IR sensor 2.
  delay(50);                                        // 50ms second delay for sensor to come out of standby.
    sensor2.init();                                 // Initialise sensor 2.
    sensor2.configureDefault();                     // Load default configuration of sensor.
    sensor2.setTimeout(500);                        // Timeout time of sensor 0.5 seconds.
    sensor2.setAddress(0x56);                       // Set I2C adress as for memory allocation as 0x56.
  digitalWrite(sensor1_pin, LOW);

delay(1000);                                        // 1 second delay to ensure all set ups are complete.
}

void loop()                                           // Main Programme: 
{ 
  digitalWrite(sensor1_pin,HIGH);                     // Switch on Sensor 1.
  int dist1 = sensor1.readRangeSingleMillimeters();   // Store reading as int dist1.
  digitalWrite(sensor1_pin,LOW);                      // Put sensor 1 into standby.

  digitalWrite(sensor1_pin,HIGH);                     // Repeat above procedure.
  int dist2 = sensor2.readRangeSingleMillimeters();
  digitalWrite(sensor1_pin,LOW);

int height_delta = dist1-dist2;
   Serial.println(height_delta);
  delay(50);                             // Wait 50ms before beginning next loop.
}

"1.) The Adafruit datasheet specifies that when using multiple breakouts the I2C pull up resistors need to be removed by soldering. Does this apply for the Pololu version too? " Yes, there should ideally only be 1 set of pullup resistors at the end of the I2C chain of connections. You don't want to end up with so many resistors in parallel that the devices can't sink enough current to create a valid low signal. Resistors on each device end up being connected in parallel, with total resistance R = 1/(1/R2 + 1/R2 + 1/R3 + 1/R4) So say 4 devices each with a 4.7K pullup: 1/(1/4700 + 1/4700 + 1/4700 + 1/4700) = R = 1175 ohm, which may be kinda low for many devices, requiring 4.25mA of sink capability.

I don't know about 2 & 3, I haven't read the datasheets.

Ok, thank you Cross Roads!

I'll check with an oscilloscope to see if I get a good square wave between high and low and then remove a resistor if need be.

If anyone else has an idea about question 2 and 3 that'd be great. I've tried to compare with other I2C sensors, but not got far :(

I’ve figured it out now and maybe this thread can help other people in the future. See sample code below quote.

1.) see cross roads answer. I am working with an external power supply and only 2 IR sensors in parallel, which gives stable readings.

2.) No! In setup both GPI00 pins need to be set to low before setting each one high and initialising the sensor and setting an adress. After this the main programme or void loop in the arduino world, each reading can be made without changing the GPI00 pin (remains at high after initial set up).

3.) Yes. Vin and GPI00 both need to be connected. According to the datasheet 47k resistors are already inserted and no external ones are needed. E.g. my GPI00 pins are connected to ARduino Mega 50 and 52 pins.

CZeppe:
More specifically myquestions are:
1.) The Adafruit datasheet specifies that when using multiple breakouts the I2C pull up resistors need to be removed by soldering. Does this apply for the Pololu version too?
2.) Do I specifically have to write a high/low on the GPI00 pin at every step (see main part of program code below)?
3.) If connecting 2 IR sensors am I correct in connecting both Vin and GPI00? I seem to have read that only GPI00 is needed, but am not 100% sure.

I have written a simple version of the code to just get the output from the 2 sensors as I am comfortable with coding the rest and hopefully this makes debugging easier…

My apologies for writing such a long essay, but I hope it helps in explaining my issues. It has now been annoying me for quite a while…
I greatly appreciate your help! Thank you in advance!

#include <VL6180X.h>
#include <Wire.h>


// IR Sensor Definitions
VL6180X sensor1;                                     // Sensor that measures from Servo to plate
VL6180X sensor2;                                     
int sensor1_pin = 50, sensor2_pin = 52;    // Digital Pins to set GPI00 High or Low.


void setup() {

Serial.begin(9600);                                 // Run at the highest possible baud rate.
Wire.begin();                                      
  
  pinMode(sensor1_pin, OUTPUT);                     // IR sensor calibration and activation.
  pinMode(sensor2_pin, OUTPUT);
  digitalWrite(sensor1_pin, LOW);
  digitalWrite(sensor2_pin, LOW);
  Serial.begin(9600);                               // Begin serial transmission of data. 
  Wire.begin();                         

 // Sensor 1:
  digitalWrite(sensor1_pin, HIGH);                  // Switch on IR sensor 1.
  delay(50);                                        // 50ms second delay for sensor to come out of standby.
    sensor1.init();                                 // Initialise sensor 1.
    sensor1.configureDefault();                     // Load default configuration of sensor.
    sensor1.setTimeout(500);                        // Timeout time of sensor 0.5 seconds.
    sensor1.setAddress(0x54);                       // Set I2C adress as for memory allocation as 0x54.

  
  // Sensor 2:
 digitalWrite(sensor2_pin, HIGH);                   // Switch on IR sensor 2.
  delay(50);                                        // 50ms second delay for sensor to come out of standby.
    sensor2.init();                                 // Initialise sensor 2.
    sensor2.configureDefault();                     // Load default configuration of sensor.
    sensor2.setTimeout(500);                        // Timeout time of sensor 0.5 seconds.
    sensor2.setAddress(0x29);                       // Set I2C adress as for memory allocation as 0x56.
 

delay(1000);                                        // 1 second delay to ensure all set ups are complete.
}

void loop()                                           // Main Programme: 
{ 
                                             // Switch on Sensor 1.
  int dist1 = sensor1.readRangeSingleMillimeters();   // Store reading as int dist1.
 delay(20);
  int dist2 = sensor2.readRangeSingleMillimeters();
 

int height_delta = dist1-dist2;
   Serial.print(height_delta);
   Serial.print("\t");
   Serial.print(dist1);
    Serial.print("\t");
   Serial.print(dist2);
   Serial.print("\n");
  delay(1000);                             // Wait 1s before beginning next loop.
  
}

Regarding 1-->

I am working with 5 polulu VL6180x boards on single I2C line and I am using a Vin of 3.3 V. Polulu doesn't give an option to bypass the pull up resistors unlike sparkfun. So considering multiple pull up resistors (5 in my case) on each I2C line, I think the total pull up resistor (1/R1 + 1/R2 ...) should be such that the sensor is able to drive the I2C lines to 0 volts (considering there is a maximum current the sensor can sink). Thus R(total) > 3.3/ i_max (max current the sensor can sink).

Now an R(total) of around ~1.8 k ohm should work as sparkfun uses 2.2 K ohm resistors in its board and if you consider the Arduino or any other controller's pull up to be nominal 10 k ohm, then you get R (total) for sparkfun's case to be ~1.8 k ohm which obviously works.

Now, polulu uses 10 k ohm resistors, so if I use 5 boards and disable pull up resistors of my controller, R (total) in my case comes out to be ~ 2 k ohm which is greater than 1.8 k ohm and should work.

Also consider that the sparkfun board can be used with 5 v i2c lines also and I am using 3.3 v i2c lines. This also makes my assumption (that my setup should work reliably) safer as driving 3.3 v to 0 would require lesser current than doing the same for 5 v lines (considering a fixed value of pull up resistors).

Please comment if my assumption/ calculation is correct. I don't have an oscilloscope to check if the wave-forms are fine.