MCP23017 I/O expander + PCA9685 pwm servo driver on same I2C bus?

Is it possible to combine the MCP23017 16 channel I/O expander and the PCA9685 16 channel 12 bit servo driver on the same I2C bus (with Uno, Mega or Pro Mini,…)?

The purpose is to read the 16 inputs from the MCP23017 and drive, on a one-to-one basis, the PCA9685 outputs. So if input1 reads “1”, then driver servo1 connected to PCA9685 output1 servo to position 0 degrees, and consequently, when the input1 reads “0”, then drive output1 servo to position 90 or whatever degrees (position is taken care of by the Adafruit library for this chip).

Are there special requirements to look after when doing this?

That should work fine. The entire point of i2c bus is to have several chips connected to the same wires. Each chip has a unique address on the bus and the Arduino talks to each chip individually using its address.

A warning: i2c bus wires are not meant to be very long. You may get away with 1~2 metres, but there's no guarantee.

Thank you very much for your reply. This is for proof-of-concept design, so before investing time I wanted to know its feasibility. The purpose is to design a "motherboard" with one Pro Mini, and on which to fit both stacks of the MCP23017 and stacks of adapted PCA9685 Adafruit boards. All I/O would be over 16 pole IDC connectors, one on each 16 channel I/O board. So indeed I2C will be very short, per their specs. Greetings, Erik

You can have up to 32 x PCA9685 on an i2c bus, more than you need. However, you can only have up to 8 x MCP23017 on a bus.

What are the inputs you wish to read? There may be more efficient ways to do that than one pin per input. For example if the inputs are switches, they can be made into a matrix, requiring fewer pins.

Hi PaulRB, thanks for your reply! The purpose is to read 16 parallel binary signals, just "0" or "1" (TTL level) and serially read them into a Pro Mini, either I2C or other. I had been reading about using interrupts from the MCP23017, and it seems a complicated task. Alternatives are most welcome, thank you! Erik

Using interrupts from 16 x MCP23017 would be tricky, but possible. These outputs are normally "open collector" so many of them can be connected to the same Arduino interrupt pin, with a pull-up resistor (or perhaps an internal pull-up). When an interrupt is received, it will be necessary to read all 16 x MCP23017 to figure out which input has changed. Alternatively, a 17th MCP23017 can be used to help with that.

Alternatively, your code could simply read all 16 x MCP23017 continuously to detect any change. Speed is not that important here because mechanical devices like servos are very slow to react compared to electronics.

But back to the problem: how to connect 16 x MCP23017 in the first place?

Hi PaulRB, thank you again for your answer. I may have been confusing: only 8 MCP23017 can be used on the same I2C bus.

Re. speed of response: this setup would be for a rather slow system. Per MCP23017 8 inputs need to be read, up to a maximum of 8x16. This is for manually changing input states (from buttons etc..) so indeed no interrupts may be needed. But for the kick of it I would like to get that to work.

The issue/challenge I may have is that the same Pro Mini will be used to drive PCA9685 IC's for servo control, on the same I2C bus. If you have any relevant literature anywhere I would be pleased to receive the link(s). Thanks!

brice3010: I may have been confusing: only 8 MCP23017 can be used on the same I2C bus.

Yes, I said that earlier. But I thought you wanted up to 16 x MCP23017 and 16 x PCA9685. I guess I misunderstood. If you limit the circuit to 8 x each chip, no problem.

brice3010: The issue/challenge I may have is that the same Pro Mini will be used to drive PCA9685 IC's for servo control, on the same I2C bus.

We're back to your original question, which I though I answered in post #1. What doubt are you having, specifically?

Hi PaulRB, yes indeed, that was back to your answer #1. I never before tried to use two different chipsets with their respective libraries on the same I2C bus. Your answer reassures me, I am sorry I had you give it to me twice. The flowchart I presume will be: function call #1: read MCP23017, when a input state has changed start function call #2: write output change to corresponding PCA9685 output. A few weeks of experimenting ahead. Greetings and thanks again for your help! Erik

Yes. As long as each chip has a different address, it should all work fine. MCP23017 has the more restricted set of possible addresses, a range of only 8. PCA9685 has a wide range of addresses, up to 128 apparently, so choose a range of addresses that won't clash with the other chips. You determine the address of each chip by connecting certain pins to either VCC or ground, each combination results in a different address. The PCA9685 modules have 6 or 7 pairs of pads which you can short with a blob of solder to set the address of that module.