Last week, I covered some of the bitter details of an interesting hack that lets us split up the I²C clock line into multiple outputs with a demultiplexer, effectively giving us “Chip Selects” for devices with the same address.
This week, I figured it’d be best to layout a slightly more practical method for solving the same problem of talking to I²C devices that each have the same address.
I actually had a great collection of comments mention the same family of chips I’m using to tackle this issue, and I’m glad that we’re jumping off the same lead as we explore the design space.
Recalling the Work of Our Predecessors
Before figuring out a clever way of hacking together our own solution, it’s best to see if someone before us has already gone through all of the trouble to solve that problem. In this case–we’re in luck–so much that the exact bus-splitting behavior we want is embedded into a discrete IC, known as the PCA9547.
It’s worth remembering that our predecessors have labored tirelessly to create such a commodity piece of silicon.
The PCA9547 (PDF) is an octal, I²C bus multiplexer, and I daresay, it’s probably the most practical solution for this scenario. Not only does the chip provide 8 separate buses, up to seven more additional PCA9547s can be connected to enable communication with up to 64 identical devices! What’s more, the PCA9547 comes with the additional benefit of being compatible with both 3.3V and 5V logic-level devices on separate buses. Finally, as opposed to last week’s “hack,” each bus is bidirectional, which means the PCA9547 is fully compliant with the I²C spec.
Selecting one of the eight I²C buses is done via a transfer on the I²C bus itself. It’s worth mentioning that this method does introduce a small amount of latency compared to the previous clock-splitter solution from last week. Nevertheless, if you’re planning to read multiple devices sequentially from a single bus anyway, then getting as close-as-possible to a simultaneous read/write from each device isn’t likely a constraint on your system.
With a breakout board to expose the pads, I mocked up a quick-n-dirty Arduino Library to get the conversation started and duplicated last week’s demo.
Happily enough, with a single function to change the bus address, the PCA9547 is pretty much a drop-in solution that “just works.” It’s definitely reassuring that we can stand on the shoulders of our chip designers to get the job done quickly. (They’ve also likely done quite a bit more testing to ensure their device performs as promised.) Just like last week, feel free to check out the demo source code up on Github.
Until next time–cheers!
Short version: If you can think of a generally useful logic function, someone makes a chip that does that thing and Digikey carries it.
This is not a hack, it is valuable information for me, thanks to the fine folks who run Hackakday. ‘Possible to tag it with “engineering info” tag?
Huzzah! Huzzah! for Hackaday!
I love these posts. Yeah, it’s not a hack, it’s how to do it.
Let’s call these “HackADos”
;-)
You can have 8 on the top bus for 64 devices, or nested 8 deep for 16,777,216 busses.
OR…
You can fit up to 153 MILLION busses:
http://mindbleach.com/words/i2c-and-device-limits/
Does the Arduino even have I2C? I guess that is a Teensy or something, which actually has some peripherals.
Yes. Yes it does.
So, what’s the best Arduino solution for getting anything done? Teensy + sparkfun arduino form factor adapter?
The zero is $50 … unclear if the Freedom boards actually have Arduino IDE support …
Is there some problem with an Uno R3? Adafruit is manufacturing them for the US market now, $25.
MicroCenter sells their own clone for $5 USD.
Yes. It’s a 2K/32K part that runs at 16 Mhz … the Teensy is a 64K/256K part at 72Mhz, and has a ton of redundant peripherals, and is $5 cheaper.
Everything has i2c. I can build a 6809 board with I2C. It’s very easy to add to anything.
The Atmega chips used in Arduinos have hardware support for I2c. The Arduino libraries make using it easy. It’s not quite the same thing as bit-banging I2c on an old CPU.
For articles like this it would be so great if we could save to these in some collection on hackaday.io, like a favorites tab or something. I bookmark so many things from here my bookmarks are getting bloated.
Get yourself a “folder” in your bookmarks. I say “folder” cos the dirty little things are trying to replace “directories” in certain not-very-good operating systems of the last couple of decades. Butanyway. Do that. Organising your bookmarks is easy.
That’s the biggest reason I never wrote longer-form articles. It’s depressing, from an author’s point of view, to put time into educating people, when your efforts are ultimately, beyond 2 days, disposable. Archived, but generally undiscoverable. Hackaday does news + context for hackers fairly well, but, there’s no home for the better quality stuff like this.
I wish I could “favorite” articles directly on HAD too, as on instructables.
Oh yes, maybe call it hackaday engineering notes, or such.
I think that the best current 100% Arduino IDE compatible is Adafruit’s Metro. It takes those olde timey Ardu shields and such, has hardware serial COM (2), I2C, and SPI, and looks like a solid $19.95 piece of hardware (Mine was just delivered)
My data acq work simply can’t have holes in it and bit banging might cause latency issues. So, I can COM to the IDE console, COM data from the DMM, I2C GPS data for perfect timestamps, I2C data for storage on SD card, and SPI my hdw. up/down counter. It’s a perfect fit for my app!
This is how digital model trains run (the clock stretching part), it’s called DCC protocol. The only thing you are missing is an error/parity bit/byte. Great article! ;)
I actually have a patent on doing exactly this. Instead of an I2C bus splitter, I used an I2C IO expander. Each expander output can act as a chip enable for one of a group of I2C peripherals with the same address.
https://www.google.com.ar/patents/US6301623
As shown in the patent, you can also use a CMOS analog mux to split an I2C bus
*had* a patent:
17 mei 2013 REMI Maintenance fee reminder mailed
9 okt 2013 LAPS Lapse for failure to pay maintenance fees
26 nov 2013 FP Expired due to failure to pay maintenance fee
When I said “I” had a patent…what I really meant, was that I did the work, then sold it to my employer for $1.
The employer is no longer in business, at least, no longer in the same business under the same name, having been bough/sold and/or traded to other companies.
Still, it looks good on the resume.
:-)