Sensor pins in use

I have a Mega Arduino, my problem is that the SDA and SCL pins are already in use with the MPU6050 sensor, but, in addition to the previous one I want to use other distance sensors (VL53L0X), both use those same pins. It is possible to share it or assign others pinoput, because I have more than 5 VL53L0X sensors.

This is the official library: GitHub - pololu/vl53l0x-arduino: Pololu Arduino library for VL53L0X time-of-flight distance sensor

That’s OK, I2C is a bus and you can have multiple compliant devices connected. Each device has an address and so will respond when it sees a communication sent to its address.

1 Like

Let’s see if I understood, I can connect more than 10 sensors to the SDA and SCL pins, and obviously to 5V and GND. That is, I can share exactly the same pins (respectively) as if of a single sensor it would be? (I do not know if I understood badly).

I apologize if my question is basic, I am new with Arduino, as you can notice.

Can I see some tutorial or documentation where do they do it? I do not want to burn a sensor or my Arduino.

I assume you live somewhere and you have a street address. The name of the street is the same for all residents but their housing number differs. Think of I2C as the street name. The arduino will say “I want to to send a letter to I2C street, apartment 3F and everyone on the bus sees the letter passing by but only the tenant in 3F reads it (they are all well behaved :))

So Yes, as long as they have different addresses (and compatible electric requirements)

Tons of info online if you do an I2C arduino search

And more…

1 Like

Electric requirements compatible with Arduino or the sensors between them? I want to know compatibility on my own.

For example those two sensors that I tell you: 10 sensors VL53L0X and 1 sensor MPU6050

I added a couple links above

1 Like

When you say: ''as long as they have different addresses (and compatible electric requirements)".
Can you explain a little more, please? That is, if I connect the same sensor it will not work because it has the same address?

compatible electric requirements?

Thank you very much, I’ll start reading them.

Some sensors offer a way to set different addresses by connecting some address pins in different ways.

The VL53L0X has a default I2C address of 0x29 and You can change it, but only in software. That means you have to wire the SHUTDOWN pin and hold all but one sensor in reset while you reconfigure one sensor at a time (see this Application note)

If this is not your case or require more sensors than addresses you can configure, then you need an I2C multiplexer You can find some 8 or 16 ways

See this

Another solution is to power off devices you don’t need and keep only one live so that they don’t conflict. Again, not always possible due to various constraints but an option

1 Like

Let’s see if I understood, correct me if I’m wrong, please.

If I have many sensors equal and I want to share I2C to read one I have to turn off the others, right?

An alternative is to buy the “i2c multiplexer” which is basically an extension of the pins, right?

Not quite correct.

At the start of your sketch, in setup(), your sketch must enable the sensors one at a time. As each one is enabled, the sketch can then change the newly enabled sensor’s address so that once all the sensors are enabled, they each have a different address. Then your sketch can leave them all enabled after that. The sketch can use each sensor as desired because they all have different addresses.

You can use spare Mega pins to enable the sensors. But the sensor breakout boards you use must have the reset pin available.

1 Like

Exactly!

1 Like

I just connected two sensors sharing the one MPU6050 pins and another VL53L0X (works well. I do not want to connect other VL53L0X until I have it all clear).

I’m going to show you my code. I use libraries and by default uses the assigned pins (SDA and SCL).

#include <Wire.h>
#include <MPU6050.h>

MPU6050 mpu;

#include "Adafruit_VL53L0X.h"

Adafruit_VL53L0X lox = Adafruit_VL53L0X();

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

  while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G)) {
    Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
    delay(500);
  }
  if (!lox.begin()) {
    Serial.println(F("Failed to boot VL53L0X"));
    while(1);
  }
}

void loop() {
  mpu6050();
  vl53l0x();
}

void mpu6050() {
  // Gyro
  Vector rawGyro = mpu.readRawGyro();
  Vector normGyro = mpu.readNormalizeGyro();
  Serial.print(" Gyro_Xraw = ");
  Serial.print(rawGyro.XAxis);
  Serial.print(" Gyro_Yraw = ");
  Serial.print(rawGyro.YAxis);
  Serial.print(" Gyro_Zraw = ");
  Serial.println(rawGyro.ZAxis);

  Serial.print(" Gyro_Xnorm = ");
  Serial.print(normGyro.XAxis);
  Serial.print(" Gyro_Ynorm = ");
  Serial.print(normGyro.YAxis);
  Serial.print(" Gyro_Znorm = ");
  Serial.println(normGyro.ZAxis);
  
  // Accel
  Vector rawAccel = mpu.readRawAccel();
  Vector normAccel = mpu.readNormalizeAccel();
  Serial.print(" Accel_Xraw = ");
  Serial.print(rawAccel.XAxis);
  Serial.print(" Accel_Yraw = ");
  Serial.print(rawAccel.YAxis);
  Serial.print(" Accel_Zraw = ");
  Serial.println(rawAccel.ZAxis);

  Serial.print(" Accel_Xnorm = ");
  Serial.print(normAccel.XAxis);
  Serial.print(" Accel_Ynorm = ");
  Serial.print(normAccel.YAxis);
  Serial.print(" Accel_Znorm = ");
  Serial.println(normAccel.ZAxis);

  // Temp
  float temp = mpu.readTemperature();
  Serial.print(" Temp_C = ");
  Serial.print(temp);
  delay(500);
}

void vl53l0x() {
  VL53L0X_RangingMeasurementData_t measure;
  lox.rangingTest(&measure, false);

  if (measure.RangeStatus != 4) {
    Serial.print("Distance (mm): "); 
    Serial.println(measure.RangeMilliMeter);
  } else {
    Serial.println(" out of range ");
  }

  delay(500);
}

Honestly all that you have told me I do not have 100% clear, so I ask you: that you recommend me doing? (Note: I am reading on the subject, but you can guide me, please).

The Adafruit library has an example sketch for use with multiple sensors:

1 Like

Hi,
Look at this YouTube clip, it shows how to use more than one of the TOF units using the XSHUT pin.

Tom… :grinning: :+1: :coffee: :australia:

1 Like

@PaulRB @TomGeorge Thank you very much for both the sample code and for the video.

It is not necessary to respond, I already resolve it. I comment below (in case someone else serves such information).

(1)
The video uses this sample code, which is to use only 2 VL53L0X sensors (I think, if I did not understand bad, I do not know if it can use more than 2): Adafruit_VL53L0X/vl53l0x_dual.ino at master · adafruit/Adafruit_VL53L0X · GitHub

(2)
This other is to use more than 2: Adafruit_VL53L0X/vl53l0x_multi_extended.ino at master · adafruit/Adafruit_VL53L0X · GitHub

This are my questions:
A) In the case of the 1st code, how can I identify the address of each sensor?

B) In the case of the 2nd code, only the name is defined, that is, it does not specify anything else. How can I identify each sensor?

C) It is necessary to use the shutdown pin?

To set the new address you can do it one of two ways. During initialization, instead of calling lox.begin(), call lox.begin(0x30) to set the address to 0x30. Or you can, later, call lox.setAddress(0x30) at any time.

This is the solution?

It is not necessary for you to respond as above (I apologize for asking without first trying the code, I just did not want to burn anything, but, I see that it was simpler than I thought). I connect 4 sensors, everything works well, but, I still have a question.

The code that I use was this: Adafruit_VL53L0X/vl53l0x_dual.ino at master · adafruit/Adafruit_VL53L0X · GitHub

I add one more to have 3 sensors of it, my final code is this:

#include "Adafruit_VL53L0X.h"

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

// set the pins to shutdown
#define SHT_LOX1 7
#define SHT_LOX2 6
#define SHT_LOX3 5

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

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

/*
    Reset all sensors by setting all of their XSHUT pins low for delay(10), then set all XSHUT high to bring out of reset
    Keep sensor #1 awake by keeping XSHUT pin high
    Put all other sensors into shutdown by pulling XSHUT pins low
    Initialize sensor #1 with lox.begin(new_i2c_address) Pick any number but 0x29 and it must be under 0x7F. Going with 0x30 to 0x3F is probably OK.
    Keep sensor #1 awake, and now bring sensor #2 out of reset by setting its XSHUT pin high.
    Initialize sensor #2 with lox.begin(new_i2c_address) Pick any number but 0x29 and whatever you set the first sensor to
 */
void setID() {
  // all reset
  digitalWrite(SHT_LOX1, LOW);    
  digitalWrite(SHT_LOX2, LOW);
  digitalWrite(SHT_LOX3, LOW);
  delay(10);
  // all unreset
  digitalWrite(SHT_LOX1, HIGH);
  digitalWrite(SHT_LOX2, HIGH);
  digitalWrite(SHT_LOX3, HIGH);
  delay(10);

  // activating LOX1 and reseting LOX2
  digitalWrite(SHT_LOX1, HIGH);
  digitalWrite(SHT_LOX2, LOW);
  digitalWrite(SHT_LOX3, LOW);

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

  // activating LOX2
  digitalWrite(SHT_LOX2, HIGH);
  delay(10);

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


  // activating LOX3
  digitalWrite(SHT_LOX3, HIGH);
  delay(10);

  //initing LOX3
  if(!lox3.begin(LOX3_ADDRESS)) {
    Serial.println(F("Failed to boot 3 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!
  lox3.rangingTest(&measure3, 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();

  // print sensor 3 reading
  Serial.print(F("3: "));
  if(measure3.RangeStatus != 4) {
    Serial.print(measure3.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);
  pinMode(SHT_LOX3, OUTPUT);

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

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

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

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

My question is, if I have 10 sensors, I just have to place the address in the following way:

#define LOX1_ADDRESS 0x30
#define LOX2_ADDRESS 0x31
#define LOX3_ADDRESS 0x32
#define LOX4_ADDRESS 0x33
#define LOX5_ADDRESS 0x34
#define LOX6_ADDRESS 0x35
#define LOX7_ADDRESS 0x36
#define LOX8_ADDRESS 0x37
#define LOX9_ADDRESS 0x38
#define LOX10_ADDRESS 0x39

Correme if I’m wrong, please.

I ask you to know if I should buy something more.

Well, I think that should work, but your code is getting really long and ugly. You should use some arrays to hold the Adafruit_VL53L0X objects and maybe the pin numbers for the XSHT pins and for the i2c addresses. But if you can allocate 10 consecutive pins (should not be a problem on Mega) and 10 consecutive addresses (also not a problem because the MPU6050 is 0x68 I think), you don’t really need arrays for those.

1 Like

Can you give me some example to improve the code? What is in programming in Arduino is little.

Ok, but later. Writing code on my phone is not fun.

1 Like