pololu/vl53l0x-arduino

Using multiple sensors on the same i2c bus

steinerlein opened this issue · 23 comments

Thank you very much for your work so far. I am trying to use two sensors on the same i2c bus of an arduino. I do use the Satellite boards by ST, however I think there shouldn't be much difference.
My question is: Have you tried using to instances of the sensor at the same time? Maybe I am doing something wrong?
Here is the code I try to use ATM:
The XShut pins of the sensors are connected to pins 4 and 5 of the arduino.

#include <Wire.h>
#include <VL53L0X.h>

VL53L0X sensor;
VL53L0X sensor2;

void setup()
{

  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);

  delay(500);
  Wire.begin();


  Serial.begin (9600);

  digitalWrite(4, HIGH);
  delay(150);
  Serial.println("00");
  sensor.init(true);

  Serial.println("01");
  delay(100);
  sensor.setAddress((uint8_t)22);
  Serial.println("02");

  digitalWrite(5, HIGH);
    delay(150);
  sensor2.init(true);
  Serial.println("03");
  delay(100);
  sensor2.setAddress((uint8_t)25);
  Serial.println("04");

  Serial.println("addresses set");



}

void loop()
{
  Serial.println ("I2C scanner. Scanning ...");
  byte count = 0;


  for (byte i = 1; i < 120; i++)
  {

    Wire.beginTransmission (i);
    if (Wire.endTransmission () == 0)
    {
      Serial.print ("Found address: ");
      Serial.print (i, DEC);
      Serial.print (" (0x");
      Serial.print (i, HEX);
      Serial.println (")");
      count++;
      delay (1);  // maybe unneeded?
    } // end of good response
  } // end of for loop
  Serial.println ("Done.");
  Serial.print ("Found ");
  Serial.print (count, DEC);
  Serial.println (" device(s).");

  delay(3000);
}

It will stop after line 29, at the first init. If I only connect one sensor and change its address it works fine.
Any hints are highly appreciated! And again, thanks for the library!

I am looking into this, but I want to point out right away that you shouldn't drive the XSHUT pins high (they are not 5V tolerant). Instead, you can set the Arduino pin back to an input (pinMode(4, INPUT);) to allow the sensor board to pull XSHUT up to 2.8 V.

Edit: Sorry, I just noticed you said you're using ST satellite boards. It looks like those do have a level shifter on XSHUT, so you should be ok driving it high.

Hey Kevin, thanks for your response! The XSHUT pins on the satellite boards by ST are regulated, so that shouldn't be a problem. But still - can I pull them low when I declare the pin as an input?

I realized you were using the ST satellite boards, so I edited my comment above, in case you didn't see. The idea would be to still set the pins to outputs driving low at the start, like you're doing, but then set each pin to be an input and let the sensor board pull it high instead of leaving it an output and driving it high.

I tried running your program (but with the change I described, since I'm using two of our carrier boards) and it worked fine for me. I got this output, as expected:

00
01
02
03
04
addresses set
I2C scanner. Scanning ...
Found address: 22 (0x16)
Found address: 25 (0x19)
Done.
Found 2 device(s).

I also confirmed that I could get independent readings from the two sensors. I would suspect either you have a bad connection somewhere or the ST boards differ from our carriers in some unexpected way. Do both of your sensors work when you test them separately?

Thank you very much for taking the time to test it. I will try your suggestion asap and report back.

I have now tried everything that I could come up with on my own. It still does not work with two sensors.
As shown on page 3 of the datasheet of the ST satellite boards, there is a jumper possibility (R19) which can be used to bypass the voltage level shifter on the board. I have bridged these, too - still no luck. Everything still works fine when I connect only one sensor.
Kevin, could you maybe show me your wiring setup? I suspect I must be doing something wrong with that.

Here is the link to the datasheet mentioned above:
http://www.st.com/content/ccc/resource/technical/document/data_brief/group0/e2/8a/a0/9c/a7/cc/41/f3/DM00286872/files/DM00286872.pdf/jcr:content/translations/en.DM00286872.pdf

Here's a quick wiring diagram of my setup: vl53l0x-wiring

If you post a picture of your own setup, I could check if anything looks noticeably wrong.

Also, there are a few things you could try incrementally that should help us figure out the problem (you might have done some of these already):

  1. With only sensor A connected, can you change its address and communicate with it?
  2. Same as above, but with only sensor B.
  3. With both A and B connected, and XSHUT high on A but low on B, can you change A's address and communicate with it?
  4. Same as above, but with with the sensors switched - with only B enabled, can you talk to B?

Kevin, I ordered some of your/Pololus carrier boards, and everything works just fine with them.
I want to thank you for your help again.
For anyone coming here looking for answers, there is quite a bit of info in this google group:
https://groups.google.com/forum/#!topic/diyrovers/lc7NUZYuJOg

I'll close this issue now..

Hi Kevin,

Can you please share the sketch you use for two sensors? I cannot set the address of the second unit.
I'm trying to set it to 25 as above and it gets set to: 150 ????

I2C scanner. Scanning ...
I2C scanner, adresses found:
22 -- //returned by sensor.getAddress();
25 -- //returned by sensor2.getAddress();
Found address: 22 (0x16)
Found address: 150 (0x96)
Done.

Thanks a lot!

@steinerlein - I'm glad to hear that our boards worked for you, and it seems strange that the ST ones wouldn't work in the same setup. Thanks for letting me know.

@andreiBots - This version of steinerlein's code worked fine for me. It is exactly the same except that I changed some of the digitalWrite() calls to pinMode():

#include <Wire.h>
#include <VL53L0X.h>

VL53L0X sensor;
VL53L0X sensor2;

void setup()
{

  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);

  delay(500);
  Wire.begin();


  Serial.begin (9600);

  pinMode(4, INPUT);
  delay(150);
  Serial.println("00");
  sensor.init(true);

  Serial.println("01");
  delay(100);
  sensor.setAddress((uint8_t)22);
  Serial.println("02");

  pinMode(5, INPUT);
    delay(150);
  sensor2.init(true);
  Serial.println("03");
  delay(100);
  sensor2.setAddress((uint8_t)25);
  Serial.println("04");

  Serial.println("addresses set");



}

void loop()
{
  Serial.println ("I2C scanner. Scanning ...");
  byte count = 0;


  for (byte i = 1; i < 120; i++)
  {

    Wire.beginTransmission (i);
    if (Wire.endTransmission () == 0)
    {
      Serial.print ("Found address: ");
      Serial.print (i, DEC);
      Serial.print (" (0x");
      Serial.print (i, HEX);
      Serial.println (")");
      count++;
      delay (1);  // maybe unneeded?
    } // end of good response
  } // end of for loop
  Serial.println ("Done.");
  Serial.print ("Found ");
  Serial.print (count, DEC);
  Serial.println (" device(s).");

  delay(3000);
}

If you continue to have trouble and you're using our boards, please post on the Pololu forum, as that is a better place for us to help you troubleshoot. It would be helpful if you could give some details about your setup, including what kind of Arduino you are using and how you have everything connected. A picture showing your connections would be good too.

How can I retain address after power cut off??

@oleglyan You can't; when it powers up the slave address is always 0101001b. The code in this thread uses the XSHUT pins to setup the addresses each time it starts up.

Thanks for this! I got two sensors up and running right away.

Thanks a lot! It's very needful sketch for me!!

Hi guys, I would just like to confirm: I ran the above code with my two ST sensors (VL53L0X) and they both work fine.

I am trying to use two ST vl53l0x boards controlled by arduino uno but i am not able to get data , on serial monitor it is printing 65535.Please help.

@AnudeepNayakAntariksh As I wrote in my reply to your other comment, please post on the Pololu forum if you want additional help and do not post the same question in multiple GitHub issues.

Here's a quick wiring diagram of my setup: vl53l0x-wiring

If you post a picture of your own setup, I could check if anything looks noticeably wrong.

Also, there are a few things you could try incrementally that should help us figure out the problem (you might have done some of these already):

  1. With only sensor A connected, can you change its address and communicate with it?
  2. Same as above, but with only sensor B.
  3. With both A and B connected, and XSHUT high on A but low on B, can you change A's address and communicate with it?
  4. Same as above, but with with the sensors switched - with only B enabled, can you talk to B?

Hi Kevin,
Will this approach also work with the STMicroelectronics VL6180X Satellite Board? There doesn't seem to be an XSHUT input pin on it;
vl6180xboard

Thanks,
George

George,

The pin labeled GPIO on that board is probably equivalent to the XSHUT pin. From its datasheet, the VL6180X's GPIO0 pin is also CE (chip enable), and its GPIO1 is the interrupt output. If the pin labeled INT is GPIO1, the pin labeled GPIO should be GPIO0.

Kevin

Thanks Kevin,

I couldn't get this approach working on the VL53L1X, I have ordered some VL6180X and I will try it on them out of interest.

Although as far as my current project goes I think I'm gonna go down the route of increasing the number of i2c ports on the Arduino using an analogue multiplexer as I need to be able to detect if one of my sensors fails and identify which one has failed. I can't see how this could be done via the approach you outline here using the XSHUT pins, am I correct here?

Thanks again,
George

Using an I2C multiplexer should work fine, but I think whether it's necessary might depend on what kind of failures you are hoping to detect. If you'd like to discuss this more or try to troubleshoot your system with the VL53L1X sensors, please post on the Pololu forum, which would be a more suitable place for that type of discussion; the GitHub issues are intended for addressing problems with or changes to the library code itself.

Hey I was looking at this code because I am trying to get separate readings from both sensors. Using this code I can get a reading from sensor but sensor 2 just outputs like 65350 or something along those lines.

Sid4x commented

¡Gracias por esto! Tengo dos sensores en funcionamiento de inmediato.

Me ayudas a programar el mio ?