Wire, Wire1, and working around I2C address conflicts?

I’m trying to wrap my head around the two sets of I2C pins on the Electron, and see if there is a way to use two sensors with the same hardwired I2C address without having to resort to bitbashing.

Here’s my setup:

Two TCS34725 color sensors: let’s call them SensorA and SensorB. They have identical I2C addresses.
I’ve connected SensorA to D0 and D1, and SensorB to C4 and C5 on an Electron.

I don’t need to use SensorA and SensorB at the same time, but would like for both of them to use hardware I2C.

Seems like I should be able to do something like:

Wire.begin(); // initialize Sensor A
// do some stuff like Wire.beginTransmission, Wire.read, Wire.write, etc.
Wire.end();

The last call should release pins D0 and D1, which should allow me to then do something like:

Wire1.begin(); // initialize Sensor B
// do some stuff like Wire1.beginTransmission, Wire1.read, Wire1.write, etc.
Wire1.end();

But when I actually try to do this, it doesn’t work. It appears both sensors stay active, and a .read() actually takes the higher of the two sensors, which is kinda weird but that’s what it’s doing.

Seems like because SensorA and SensorB are on separate pins, I should be able to flip back and forth between the two interfaces (Wire and Wire1). But maybe even though the pins are released, the sensor on the released pins is still connected so it won’t work. Is there a way to do this? I dunno.

Anyway, I hope this makes sense and that there is some way to switch back and forth between I2C pin pairs. Any help would be greatly appreciated.

Cheers,
L3

1 Like

Completely understand what you are trying to do, and it could work … if you add this after your end() calls

Wire.end();
pinMode(D0, INPUT);
pinMode(D1, INPUT);

Wire1.end();
pinMode(C4, INPUT);
pinMode(C5, INPUT);

The end() call disables the I2C peripheral, but doesn’t change the pinMode, so as soon as you re-enable the alternate pin configuration with begin() the I2C peripheral is re-enabled and if both sets of pins are set up as I2C open-drain, they will communicate at the same time. Interesting that the data seems to maybe be OR’ing together through two separate sets of pins.

I’ll add an issue to Github for Wire/Wire1.end() to propose restoring the pins as INPUTs. I can’t think of any reason why it shouldn’t do that already…

1 Like

@BDub,

That’s splendid. I actually did that, although I used INPUT_PULLUP instead of input, and it seemed to work (my hypothesis was that by driving the pins high, they’d never respond to any I2C action (since everything starts will pulling lines low). But I haven’t put it on a scope yet, so I’m not 100% sure my way is working. I’ll try INPUT and report back.

I think that it wasn’t so much a matter of ORing as just sort of luck of the draw. The more I ran test, the more random it appeared. Which makes sense, actually.

Thanks so much for the help. Y’all are doing great stuff, keep rocking!

Cheers,
L3

Addendum - I tried INPUT and it seemed to work fine. Thanks!

1 Like

Just to throw in a second option, since you know when you want to talk to the sensor and it is a externally powered sensor, you could try connecting the sensors Vdd pins to a digital output and swirch them on/off when you want to talk to a specific one - this only works if you don’t need the interrupt functionality tho’ (or limits is use - have both on, wait for trigger, switch off the not-triggering, read the one that triggered).

1 Like

@ScruffR,

That’s a good thought. Since we’ve already produced a batch of PCBs, it will have to wait until Rev(n+1). But that’s probably the best solution. Another possibility is that AMS produces an identical chip with a different I2C address - I think it’s the TCS34721. But your idea is better, since availability is unknown (our guys are going to check with AMS tomorrow to see how big a deal it is).

Really appreciate all the help and feedback. Cheers,

L3

2 Likes

I just want to add how enormously helpful this post was.

I was looking to power both a TCS34725 and an 128x64 OLED connected via I2C.

I managed to get them both working on the Electron - I never would have worked it out without this post - thank you!

2 Likes