If you're willing to add one extra piece of hardware (e.g. the PCA9548, an 8 channel I2C multiplexer) to your setup then you're comfortable to have 8 (!!!) extra I2C buses "for free" with the newer Raspberry Pi distros. That is a total of 9 I2C buses (including the original one) with one and the same set of standard I2C pins: pin 3 for SDA and pin 5 for SCL. No need to "steel" the other I2C pins.
That means, you will be able to connect 8 x 9 = 72 MCP23017 devices to the RPi. That is a whopping total of 72 x 16 = 1152 extra IO pins for the RPi!!! Don't tell me you need more... :-)
Since the Jessie distro, IIRC, the kernel now contains an extra module typically used for different types of I2C multiplexers. Two popular ones are the PCA9544 (which adds 4 extra I2C buses to the RPi) and the PCA9548 (which adds 8 extra I2C buses to the RPi). Or compatible types (e.g. TCA9548 from Texas Instruments).
You only have to add one line to the file /boot/config.txt
. At the end of that file, add the following line (in case you're using a PCA9548):
dtoverlay=i2c-mux,pca9548,addr=0x70
The first I2C address of the PCA9548 is 0x70
, so make sure you connect the 3 address lines to ground. But since you already have used other I2C devices, I'm sure you know what I mean.
Once you reboot, you should have something like this when running the command sudo i2cdetect -l
:
pi@rpi3bplus:~ $ sudo i2cdetect -l
i2c-3 i2c i2c-1-mux (chan_id 0) I2C adapter
i2c-1 i2c bcm2835 I2C adapter I2C adapter
i2c-8 i2c i2c-1-mux (chan_id 5) I2C adapter
i2c-6 i2c i2c-1-mux (chan_id 3) I2C adapter
i2c-4 i2c i2c-1-mux (chan_id 1) I2C adapter
i2c-9 i2c i2c-1-mux (chan_id 6) I2C adapter
i2c-10 i2c i2c-1-mux (chan_id 7) I2C adapter
i2c-7 i2c i2c-1-mux (chan_id 4) I2C adapter
i2c-5 i2c i2c-1-mux (chan_id 2) I2C adapter
To run i2cdetect
, make sure you have installed i2ctools
(sudo apt-get install i2c-tools
).
Needless to say that this won't work if you don't connect the mux to the RPi prior to rebooting the device...
The only thing you have to do now, is to select the correct /dev/i2c-x
as I2C bus for your different MCP's in your I2C command that you send out. No need to control the PCA itself to set the muxes in the right position since the kernel will do this "transparent" for you, based on the I2C dev
you've given...
Depending on the language you're using, the name of the /dev
file might be different. For instance, if you would use Pi4J (Java) and you want to access an IO expander connected to, say, bus 9 you would give something like this:
sGpio01 = new MCP23017GpioProvider(I2CBus.BUS_9, 0x20, mPollingTime);
The important part here is I2CBus.BUS_9
, since that's a define for /dev/i2c-9
. But I guess you get the picture, right?
Another very important advantage of using the PCA9548 mux is that you can drive the mux directly from the 3V3 lines of the RPi and you can attach 5V devices to the 8 I2C output buses!!! Just make sure you power the mux with the 3V3 coming from the RPi...
See the respective datasheets for more detailed information. There's a nice "Application design-in information" chapter in the NXP datasheet (PCA9548).
You get a level converter for free on top of all the extra IO pins you already have...
If that's not a nice nifty little extra thingie...