41
\$\begingroup\$

I want to connect multiple I2C slave devices to a micro controller all on the same set of pins but the I2C devices all share the same address. The addresses are fixed in the hardware.

Is there any way to connect multiple devices with the same address?

Perhaps some kind of I2C address translation module with each device with an configurable address so I can assign my own addresses to each one.

\$\endgroup\$
26
\$\begingroup\$

There is nothing built into I2C to do this, normally slave devices will have some externals pins that can be set to 0 or 1 to toggle a couple of the address bits to avoid this issue. Alternatively I've dealt with a few manufacturers that have 4 or 5 part numbers for a part, the only difference being its I2C address.

Most devices have specific hardware that handles the I2C communication, that is the slave ACK is in hardware so you really can't hack around it.

As for the translation module, you could buy some $0.50 PIC's with 2 I2C buses and write some quick code to make them act as address translators i guess.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks. Yeah, these devices do have an address select, but only between two addresses and I want to connect 5+ devices, so I'd still end up with clashes. I hadn't thought of using a PIC. That should work. Is there nothing off the shelf that does this kind of thing? \$\endgroup\$ – Simon P Stevens Oct 11 '10 at 15:19
  • 12
    \$\begingroup\$ NXP makes a bunch of multiplexers / switches for I2C, you may be able to rig something up out of those: ics.nxp.com/products/i2cmuxes for instance you could create in your case 3 sub branches, each with 2 devices on it, and use one of NXP's switches to achieve your goal. \$\endgroup\$ – Mark Oct 11 '10 at 16:12
  • \$\begingroup\$ Great, that's exactly the kind of thing I was looking for. I just didn't know the name. Thanks. \$\endgroup\$ – Simon P Stevens Oct 11 '10 at 18:11
  • \$\begingroup\$ This answer is 7 years old, so I believe that it could have been the best at the time it was offered. For others coming through now, however, some of the much newer answers (currently lower ranked on the list) offer potentially better approaches based on newer components that are now on the market. \$\endgroup\$ – Brick Apr 21 '17 at 15:59
8
\$\begingroup\$

I've just run into this problem with multiple I2C devices with a fixed address. Our solution was to use I/O lines on the microcontroller to force the SDA lines high on the devices that we don't want to address, while the I/O line for the device we're targeting is set as input (high impedance). This means that only the targeted device matches it's I2C address and the others ignore any subsequent data.

Multiple I2C devices with same address

The resistors on the SDA line for the inactive devices end up acting as pull-ups for the bus, so the exact value will depend on how many devices you have and what pull-up you need for your bus. So if you choose 10K resistors, then 3 inactive devices gives a 3K3 pullup.

The schottky diodes ensure that the device can still pull the SDA line low enough when transmitting data back to the host.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I appreciate that you've followed up and posted this. This is a pretty ingenious solution, I'm certain it will be helpful to others. \$\endgroup\$ – Simon P Stevens Aug 22 '18 at 8:23
  • \$\begingroup\$ A nice niche that can be used on some applications. I like it a lot. \$\endgroup\$ – Harry Svensson Aug 22 '18 at 11:07
  • \$\begingroup\$ isnt this a workaround for wrong HW design ? What if we dont have extra IO pins to spare ? \$\endgroup\$ – a k May 21 at 3:05
6
\$\begingroup\$

If none of the I2C devices use clock stretching (handshaking), and if you're bit-banging the I2C master, a simple hack is to have some of the devices swap the clock and data pins. During the transmission of a byte, the device which has the clock and data pins swapped will see each "0" bit as a non-event (data rising and falling with no clock) and will see each "1" bit as an I2C stop and start (clock rising while data is low, fallowed by data rising and falling, followed by clock falling). Intentional stop and start conditions for one device may be seen as data bits by the other, but unless one device has an excessive number of start and stop conditions between "1" bits, it would be unlikely that any device would "accidentally" see a start condition followed by eight data bits without an intervening stop condition.

| improve this answer | |
\$\endgroup\$
  • 6
    \$\begingroup\$ I'm not downvoting, but this seems a bit risky to me. My experience with I2C is that it's noise-prone enough with just the usual connection. You do, however, use the word "hack" and mention the caveat "if none of the i2c devices use clock stretching", so if it can work for someone, then more power to them. \$\endgroup\$ – Jason S Dec 12 '11 at 22:12
5
\$\begingroup\$

I'd consider using bus switches to multiplex the I2C bus among the devices with conflicting addresses. Bus switches are very low capacitance and resistance, and unlike buffers/drivers, they are true switches that connect or disconnect two circuit nodes.

Bus switches usually have one odd characteristic, that doesn't matter for I2C because it uses open-drain devices: a bus switch has low on-resistance when tying together voltages near 0 (Vss), but the resistance rises dramatically as the voltages approach the power supply Vdd. (This is because they're basically MOSFETs with gate voltages at the power supply when they turn on, so as the switched voltages approach Vdd, the available Vgs is much lower)

| improve this answer | |
\$\endgroup\$
4
\$\begingroup\$

I had two TCS3414 color-light sensors that I wanted to compare (The FN and CS packages, which have different filters). The I2C address is hardwired. After looking at how I2C works in terms of the SCL(clock) and SDA(data) lines, it seemed that turning off the SDA line would prevent the chip from getting a start or stop bit and thus leave it dormant. So used a CMOS analog switch (4066B) to switch on or off the SDA line to each device. This worked just fine for switching between the two devices. I know it's a hack, and the PCA9548 would be much better, but I didn't have one handy.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Actually, this isn't a hack at all, and I'd argue this should be the accepted answer. I've seen this used in several commercial products, and I can't think of a better solution (unless you have no GPIO available and thus need a pure I2C solution such as the I2C-specific muxes). Good ol' analog muxes have plenty of bandwidth and are crazy-cheap. \$\endgroup\$ – Jay Carlson Jan 16 '17 at 6:10
4
\$\begingroup\$

There is now an answer- Linear Tech has the LTC4316/17/18 series of address translators. They are relatively new, and availability is uncertain.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Very interesting component. Most I2C devices have 2 fixed addresses and this can LTC4316 could be potentially double the addressing in a reasonable cost. \$\endgroup\$ – Mehrad Feb 16 '16 at 6:53
4
\$\begingroup\$

Several manufacturers offer I2C bus multiplex- and switch ICs.

A mux can activate one channel at a time; a switch can enable multiple ones in parallel.

Check for example the offerings of NXP, TI and Maxim.

For experimentation, Adafruit has a TCA9548a board.

If you have 8 target chips with identical addresses, select an 8-to-one MUX. Before accessing any of the target chips, configure the MUX to activate the correct I2C bus.

Advantages

  • Requires no programming (vs microcontroller based approach)
  • Can support the I2C features and speeds you need (vs regular analog / digital bus muxes). For example, a regular (non-I2C) MUX will not pass general call addresses to all its channels.
| improve this answer | |
\$\endgroup\$
-1
\$\begingroup\$

Use a simple demux chip (e.g. 74HC139 afaik) and connect I2C CLK pin to input (since I2C CLK pin is output only). Use GPIO pins to control desired output. Then I2C data pin can be shared between all slaves.

| improve this answer | |
\$\endgroup\$
  • 6
    \$\begingroup\$ SCL is not output only. A slave may stretch the clock if it needs to slow it down. \$\endgroup\$ – stevenvh Apr 7 '12 at 15:59
  • \$\begingroup\$ You can use an analog multiplexer (which is bidirectional) but a decoder may not work for the reason stated by stevenh. If you use multiplexer you will need a weak pulp on the slave side to ensure it is kept inactive. Also only change the multiplexer selection when the bus is idle. \$\endgroup\$ – Kevin White Jun 25 '15 at 2:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.