How to Connect Multiple MCP23017s

For other supported Arduino products from Adafruit: Shields, accessories, etc.

Moderators: adafruit_support_bill, adafruit

How to Connect Multiple MCP23017s

Postby d7x » Wed May 02, 2012 10:18 pm

I need to be able to control 66 LEDs from an Arduino and am currently planning to use 4 MCP23017s to send a unique signal to each LED. I already have 1 MCP23017 working to control multiple LEDs but I'm not sure how to connect MCP23017 #2, 3 and 4.

1) Would I connect the 9 and 10 pins on #2, 3, and 4 to the Arduino A4 and A5 just as I would do on MCP23017 #1?

2) To set the address, it seems like #2 would be wired for pins 15 (High), 16 and 17 (Low). And #3 would simply be 15 (Low), 16 (High), 17 (Low)...

Question: what do you set in the code to indicate the address of each MCP23017?

3) Finally, I'm assuming that the MCP23017 #2 output pins would be addressed as 16-31, #3 would be addressed as 32-47. Is this correct, or would I need to address the outputs differently?
d7x
 
Posts: 43
Joined: Tue Oct 25, 2011 9:41 pm

Re: How to Connect Multiple MCP23017s

Postby adafruit_support_bill » Thu May 03, 2012 5:58 am

Code: Select all
// Basic pin reading and pullup test for the MCP23017 I/O expander
// public domain!

// Connect pin #12 of the expander to Analog 5 (i2c clock)
// Connect pin #13 of the expander to Analog 4 (i2c data)
// Connect pins #15, 16 and 17 of the expander to ground (address selection)
// Connect pin #9 of the expander to 5V (power)
// Connect pin #10 of the expander to ground (common ground)


9, 10, 12 & 13 are connected the same for all 3.
Wire the address lines as you described.

Finally, I'm assuming that the MCP23017 #2 output pins would be addressed as 16-31, #3 would be addressed as 32-47. Is this correct, or would I need to address the outputs differently?

No. Each instance of the Adafruit_MCP23017 supports only 16 pins. You need to create 3 instances of the Adafruit_MCP23017 object and specify their addresses in the "begin". (if no address is specified, 0 is assumed.)

Code: Select all
Adafruit_MCP23017 mcp0;
Adafruit_MCP23017 mcp1;
Adafruit_MCP23017 mcp2;

void setup() {
  mcp0.begin(0);
  mcp1.begin(1);
  mcp2.begin(2);
...
User avatar
adafruit_support_bill
 
Posts: 16617
Joined: Sat Feb 07, 2009 9:11 am

Re: How to Connect Multiple MCP23017s

Postby Twizted » Wed May 16, 2012 4:18 pm

Hello, I have a question in regards to the last question the original poster asked... Is there any way to combine the instances to work as he described? So you could access the pins as something like

Code: Select all
combinedMCP.digitalWrite(1, HIGH);
thru
combinedMCP.digitalWrite(64, HIGH);


I'm working on a project that is going to use two MCP23017's but I need to address them sequentially for 32 outputs in a while loop....

Code: Select all
      while(digitalRead(input)==1 && output < 31){
          output++;
          mcp.digitalWrite(output, HIGH);
          delay(100);
      }


I've not gotten my second MCP23017 yet but I'm researching how to possibly combine them for a continuous 0 thru 31 addressable output format....

Any tips or tricks you can share?
Twizted
 
Posts: 68
Joined: Tue Apr 28, 2009 2:35 pm

Re: How to Connect Multiple MCP23017s

Postby adafruit_support_rick » Wed May 16, 2012 4:36 pm

One way you could do it would be to declare an array of Adafruit_MCP23017 objects. Then, write an intermediate function that you call instead of mcp.digitalWrite(output, HIGH);

In the intermediate function, you can shift the output number right by 4 bits (i.e., divide by 16). That will give you the index to your array. Then you can perform a logical AND of the output with 0x0F to give you the local output address for the selected string.

So, your call to digitalWrite would look something like this:
Code: Select all
mcpArray[output>>4].digitalWrite((output & 0x0F), HIGH);
User avatar
adafruit_support_rick
 
Posts: 3139
Joined: Tue Mar 15, 2011 10:42 am
Location: Buffalo, NY

Re: How to Connect Multiple MCP23017s

Postby Twizted » Wed May 16, 2012 11:18 pm

driverblock wrote:One way you could do it would be to declare an array of Adafruit_MCP23017 objects. Then, write an intermediate function that you call instead of mcp.digitalWrite(output, HIGH);

In the intermediate function, you can shift the output number right by 4 bits (i.e., divide by 16). That will give you the index to your array. Then you can perform a logical AND of the output with 0x0F to give you the local output address for the selected string.

So, your call to digitalWrite would look something like this:
Code: Select all
mcpArray[output>>4].digitalWrite((output & 0x0F), HIGH);


Hmmm.... I'm slightly confused... I'm sure what you posted makes perfect sense but its just not clicking for me... Do you happen to know of any tutorials or examples I could check out...
Twizted
 
Posts: 68
Joined: Tue Apr 28, 2009 2:35 pm

Re: How to Connect Multiple MCP23017s

Postby adafruit_support_rick » Thu May 17, 2012 9:40 am

How are you at binary numbers? Think of it this way: You've got 32 outputs, numbered 0 through 31. 31 decimal = 0001 1111 binary.

Each MCP23017 controls 16 lights, 0 through 15. 15 decimal = 0000 1111 binary.

See the pattern? If you take your output number and split it up, the 4 bits on the right represent the 16 lights on each string. The four bits on the left represent the number of strings you have (in both cases, start counting from 0 instead of 1. So your two strings are numbered 0 and 1, and the 16 lights are numbered 0 .. 15).

When output = 15 = 0000 1111, you're addressing string 0, light 15
When output = 16 = 0001 0000, you're addressing string 1, light 0.

So, to split up the output number into string and light, you do a little simple arithmetic:
To get the string number, you divide by 16:
When output = 15, 15/16 = 0 = string 0
When output = 16, 16/16 = 1 = string 1.

To get the light, you want the remainder of dividing by 16:
When output = 15, 15/16 = 0, remainder 15 = light 15
When output = 16, 16/16 = 1, remainder 0 = light 0

Now, the reason that you keep seeing things like the MCP23017 having 8 or 16 or 32 of something is that those are all powers of 2, and there are handy shortcuts for doing arithmetic with powers of 2.

Instead of dividing 'output' by 16, we can shift 'output' right by 4 bits. That is, take the binary number and sort of slide it over 4 places to the right, so that those rightmost 4 bits just fall off the end and disappear. The right-shift operator is ">>" (the left-shift operator is "<<")
Example: 92 / 16 == (0101 1100 >> 4) == 0000 0101 == 5.

Instead of calculating the remainder of ('output'/16), we can keep the rightmost 4 bits and throw away the rest by using a bitwise AND operation. This operation compares two binary numbers bit by bit - if both numbers have a 1 in the same position, the result has a 1 in that position, otherwise the result has a 0 in that position. The AND operator is "&".
Example: 92 & 25:
92 == 0101 1100
25 == 0001 1001
------------
0001 1000 == 24

So, if dividing by 16 gets rid of the rightmost 4 bits, and the remainder of dividing by 16 is those same 4 bits, we can calculate the remainder by doing an AND with a number in which only the rightmost 4 bits are set to 1:
Example: remainder(92 / 16) == (0101 1100 & 0000 1111) = 0000 1100 = 12.
remainder(15 / 16) == (0000 1111 & 0000 1111) = 0000 1111 = 15
remainder(16 / 16) == (0001 0000 & 0000 1111) = 0000 0000 = 0
remainder(17 / 16) == (0001 0001 & 0000 1111) = 0000 0001 = 1

Okay. Enough pedantry. You've got 2 strings of 16 lights. You declare an array of 2 led-string objects like this:
Code: Select all
Adafruit_MCP23017 mcpArray[2];


You have 32 lights total, so you've got a counter that goes from 0 to 31. You use shift and AND to split the counter up into a string number and a light number:
Code: Select all
mcpArray[output>>4].digitalWrite((output & 0x0F), HIGH);


(0x0F is a hexadecimal, or base-16 number that is equal to binary 0000 1111)
User avatar
adafruit_support_rick
 
Posts: 3139
Joined: Tue Mar 15, 2011 10:42 am
Location: Buffalo, NY

Re: How to Connect Multiple MCP23017s

Postby Twizted » Thu May 17, 2012 10:26 am

Wow... that was a LOT of awesome information and I learned some new stuff ;)

Always a plus...

I suspect the MCP23017's should be delivered today by the time I get to my shop today so I will try to modify my sketch accordingly and see if I can't make this work and report back.

I really do appreciate your assistance and I certainly would not call your post pedantry... I found it very informative and while I did already know some of the basics of what you worked out in the post others may not and it could serve to help someone in the future :)

Also, Ladyada and/or Adabot if you are watching.... If you ever make a "Helper" or something similar badge... I would TOTALLY buy one to have it sent to Driverblock! :)
Twizted
 
Posts: 68
Joined: Tue Apr 28, 2009 2:35 pm

Re: How to Connect Multiple MCP23017s

Postby adafruit_support_rick » Thu May 17, 2012 11:11 am

Thanks for the vote! Sorry if it was a little too basic, but it's hard to know what level people are at, so I just tried to be thorough.
User avatar
adafruit_support_rick
 
Posts: 3139
Joined: Tue Mar 15, 2011 10:42 am
Location: Buffalo, NY

Re: How to Connect Multiple MCP23017s

Postby Twizted » Thu May 17, 2012 10:55 pm

driverblock wrote:Thanks for the vote! Sorry if it was a little too basic, but it's hard to know what level people are at, so I just tried to be thorough.


Very true... but, your post helped me out and I got it working thanks to you!... Thanks :)
Twizted
 
Posts: 68
Joined: Tue Apr 28, 2009 2:35 pm

Re: How to Connect Multiple MCP23017s

Postby Twizted » Wed May 23, 2012 9:56 pm

driverblock wrote:Thanks for the vote! Sorry if it was a little too basic, but it's hard to know what level people are at, so I just tried to be thorough.


Wanted to say thank you again to DriverBlock and the Adafruit forums...

Also, please forgive the slight thread hijack but I wanted to share the end results for which I was looking for the above information.

http://www.youtube.com/watch?v=i2Re-85lW0g
Twizted
 
Posts: 68
Joined: Tue Apr 28, 2009 2:35 pm


Re: How to Connect Multiple MCP23017s

Postby MetabolicCloth » Mon Apr 22, 2013 1:02 pm

could you explain the addressing in a bit more detail, i have an idea of how it works but would like a bit more information
MetabolicCloth
 
Posts: 6
Joined: Fri Jan 04, 2013 5:05 pm

Re: How to Connect Multiple MCP23017s

Postby Rahatmaini » Mon Apr 22, 2013 4:02 pm

3 pins are used to address different ICs, I believe it is 15,16, and 17 on the MCP23017. Using a combo of sending each pin either a high signal or low (5v or 0v), we can set an address. Do the math and you basically can think of it as a digit combo lock. That's basically it.

By the way if your only purpose is lighting up LEDs, I suggest skipping the MCP23017 in favor for a Shift register that are super easy to chain together and can together provide 100s of LEDs in chains, although Shift Registers are a little more complicated to use (SPI).
Rahatmaini
 
Posts: 154
Joined: Wed Aug 29, 2012 4:15 pm

Re: How to Connect Multiple MCP23017s

Postby adafruit_support_rick » Mon Apr 22, 2013 5:08 pm

Yes, on the PDIP, SOIC, and SSOP packages, pin 15 is A0, 16 is A1, and 17 is A2. (Adafruit sells the PDIP)
On the QFN package, pin 11 is A0, 12 is A1, and 13 is A2.

Together, A0, A1, and A3 are used to form a 3-bit binary number, by tying each pin to either GND or Vdd (5V or 3.3V).

This binary number is added to the base address of the MCP23017, which is fixed at 0x20. So, you can configure the MCP23017 with 8 possible addresses, meaning that up to 8 MCP23017's can share a single I2C bus.

Code: Select all
A2    A1    A0        I2C address
----------------       --------------
GND  GND  GND          0x20
GND  GND  Vdd          0x21
GND  Vdd  GND          0x22
GND  Vdd  Vdd          0x23
Vdd  GND  GND          0x24
Vdd  GND  Vdd          0x25
Vdd  Vdd  GND          0x26
Vdd  Vdd  Vdd          0x27
User avatar
adafruit_support_rick
 
Posts: 3139
Joined: Tue Mar 15, 2011 10:42 am
Location: Buffalo, NY


Return to Other Arduino products from Adafruit

Who is online

Users browsing this forum: No registered users and 5 guests

Stuff to buy from the Adafruit store and links to product documentation!


New Products [114]

Raspberry Pi[82]
 
FLORA[24]
 
Bunnie Studios[9]
 
FPGA[1]
 
mbed[12]
Arduino[60]
 
NETduino[14]
 
BeagleBone[23]
 
Android[6]
 
XBee[10]
More Dev Boards[30]


 
BoArduino[8]
 
SpokePOV[4]
 
TV-B-Gone[4]
 
MiniPOV[3]
 
SIM reader[3]
 
Microtouch[5]
 
Clocks & Watches[18]
 
Drawdio[4]
 
Brain Machine[1]
 
Game of Life[2]
 
MintyBoost[2]
More DIY Kits[16]


 
MaKey MaKey[3]
 
Tweet-a-Watt[5]
 
Young Engineers[39]
 
Discover Electronics[2]
 
Snap Circuits[4]
 
littleBits[3]
 
Project packs[9]


 
Breakout Boards[35]
LCDs & Displays[49]
Components & Parts[70]
Batteries & Power[54]
EL Wire/Tape/Panel[52]
LEDs[112]
 
Wireless[16]
Cables[66]
 
Lasers[6]
Sensors/Parts[147]
 
Enclosures/Cases[11]
 
Solar[11]
 
RFID / NFC[13]
Prototyping[70]
 
iDevices[13]
Tools[71]
 
Wearables[41]
 
CNC[37]
 
Robotics[29]
 
3D printing[1]
 
Materials[25]


 
Stickers[41]
 
Skill badges[55]
 
Books[26]
 
Circuit Playground[7]
 
Gift Certificates[4]