How to link 2x MCP23017 together ?

Jon Chandler

Joined Jun 12, 2008
1,055
Actually, each MCP23017 has 16 port pins, which can be independently set to be an input or an output.

Each chip will have 4 common connections:

● Ground, which is common to the Adruino

● +5v, which can come from the same supply as the Arduino or a separate 5 volt supply – all the grounds are connected together.

● SCL

● SDA

The ADDRESS pins A0 – A2 of each chip must be connected to ground or +5v, and no chips can have the same pattern.
 

Ya’akov

Joined Jan 27, 2019
9,170
Actually, each MCP23017 has 16 port pins, which can be independently set to be an input or an output.

Each chip will have 4 common connections:

● Ground, which is common to the Adruino

● +5v, which can come from the same supply as the Arduino or a separate 5 volt supply – all the grounds are connected together.

● SCL

● SDA

The ADDRESS pins A0 – A2 of each chip must be connected to ground or +5v, and no chips can have the same pattern.
Thanks for correcting that error, I was confusing the chip itself with the configuration of one of the common breakout boards for it. I actually knew it had 16 ports. Thanks for spotting that!
 

Thread Starter

q12x

Joined Sep 25, 2015
1,694
The ADDRESS pins A0 – A2 of each chip must be connected to ground or +5v, and no chips can have the same pattern.
5V? or you want to say 3.3V? Or they can actually be 5V? If is allowed 5V, will simplify greatly the circuit.
I know 5V is usually the normal logic high , but if it is mentioned 3.3V in the address pins, Im thinking is for some reason.
Also thank you oficially mister Jon, for that table, that saved my ass, it cleared the mystery fog very well.
 

Ian0

Joined Aug 7, 2020
9,846
5V? or you want to say 3.3V? Or they can actually be 5V? If is allowed 5V, will simplify greatly the circuit.
It's a logic input - connect it to logic high, which, if you read the datasheet, you will see is any voltage between (0.25.Vdd+0.8) and Vdd.
 

Thread Starter

q12x

Joined Sep 25, 2015
1,694
I connected 3.3V as logic high for A0 for the second chip
A2=0V, A1=0V,A0=3.3V (as logical 1) and I get no response.
The new 3.3V negative wire goes as well in common with the other ones.
These are the connections I made so far:
zzzbad  MCP23017-series connections.jpg
And here is the code I used:

Code:
#include "Adafruit_MCP23017.h"
Adafruit_MCP23017 mcp; //Instantiate mcp object
void setup()
{
  Serial.begin(19200);
  Serial.println("Ready");
  mcp.begin();

/* configuring ALL GPIO as output. */
  for(int i = 0; i <= 31; i++)
  {
    mcp.pinMode(i, OUTPUT);
  }
}

int dly = 100;
void loop()
{
  for(int i = 8; i <=31; i++)
  {
    mcp.digitalWrite(i, HIGH);
    delay(dly);
    mcp.digitalWrite(i, LOW);
    delay(dly);
  }
}
The new yellow wire is the 3.3V:
20220708_133941.jpg
 
Last edited:

Capernicus

Joined Jun 24, 2022
87
I bet a one way connection is easier than a 2 way, so they only write one way, and read the other, sometimes that is ok to do, just say if your making a robot, and u make it one way pipe for his head.

For example, you do the computer vision on the ESP32, then u send that to the next computer which then works out the motors, then that sends off to the arduino to connect to all the motors directly.

One way connection is probably easier to do, but u might need 2 way...
 

Ya’akov

Joined Jan 27, 2019
9,170
So, you need to instantiate as many mcp objects as devices: mcp1, mcp2, etc. (line 2 in youit code0 and pass the address in the begin() one for each, like line 7 repeated.
 

Ya’akov

Joined Jan 27, 2019
9,170
I bet a one way connection is easier than a 2 way, so they only write one way, and read the other, sometimes that is ok to do, just say if your making a robot, and u make it one way pipe for his head.

For example, you do the computer vision on the ESP32, then u send that to the next computer which then works out the motors, then that sends off to the arduino to connect to all the motors directly.

One way connection is probably easier to do, but u might need 2 way...
The chip supports bidirectional use of each port. It is controlled in the software.

But I don’t understand how pipelining is relevant here, could you clarify that?

[EDIT: No change to content, just fixed confused formatting.]
 
Last edited:

Thread Starter

q12x

Joined Sep 25, 2015
1,694
just say if your making a robot, and u make it one way pipe for his head.
Im concentrated fully only on making a 128 I/O pins from my PC. That's the whole reason/project. Later on, I will see what robots I can make with it, but until then, I have to break it down and make it work "normally", if possible. Using multiple computers, thats an interesting idea indeed. We'll see.
 

Thread Starter

q12x

Joined Sep 25, 2015
1,694
So, you need to instantiate as many mcp objects as devices: mcp1, mcp2, etc. (line 2 in youit code0 and pass the address in the begin() one for each, like line 7 repeated.
You are of GREAT help mister @Ya’akov ! Truly.
I understand this part very well: "instantiate as many mcp objects as devices: mcp1, mcp2, etc. " (this is similar as making new objects in my C#)

like this?:
#include "Adafruit_mcp23017.h"
Adafruit_mcp23017 mcp1; //Instantiate mcp1 object
Adafruit_mcp23017 mcp2; //Instantiate mcp2 object
Adafruit_mcp23017 mcp3; //Instantiate mcp3 object
Adafruit_mcp23017 mcp4; //Instantiate mcp4 object
Adafruit_mcp23017 mcp5; //Instantiate mcp5 object
Adafruit_mcp23017 mcp6; //Instantiate mcp6 object
Adafruit_mcp23017 mcp7; //Instantiate mcp7 object
Adafruit_mcp23017 mcp8; //Instantiate mcp8 object

void setup()
{
//V.A?
  Serial.begin(19200);
  mcp1.begin();
  Serial.begin(19200);
  mcp2.begin();
  Serial.begin(19200);
  mcp3.begin();
  Serial.begin(19200);
  mcp4.begin();
  Serial.begin(19200);
  mcp5.begin();
  Serial.begin(19200);
  mcp6.begin();
  Serial.begin(19200);
  mcp7.begin();
  Serial.begin(19200);
  mcp8.begin();

  //or V.B?
  Serial.begin(19200);
  mcp1.begin();
  mcp2.begin();
  mcp3.begin();
  mcp4.begin();
  mcp5.begin();
  mcp6.begin();
  mcp7.begin();
  mcp8.begin();
 

Ya’akov

Joined Jan 27, 2019
9,170
First, do not use Serial.begin() multiple times. It is unrelated to the mcp objects.

Second, you have to put an address in mcp.begin() so mcpX.begin(0x20) through 0x27 where X is the unique for each should work. I believe that will be the correct format but start with just the two addresses you have assigned and on the bus.

Edited to clarify the names of the objects.
 

Thread Starter

q12x

Joined Sep 25, 2015
1,694
First, do not use Serial.begin() multiple times. It is unrelated to the mcp objects.

Second, you have to put an address in mcp.begin() so mcpX.begin(0x20) through 0x27 where X is the unique for each should work. I believe that will be the correct format but start with just the two addresses you have assigned and on the bus.

Edited to clarify the names of the objects.
ahaaaa, now is way more clear, I understand now !!! Thank you !
 

Thread Starter

q12x

Joined Sep 25, 2015
1,694
...you have to put an address in mcp.begin() so mcpX.begin(0x20) through 0x27 ...
like this: (also I understand I will make for only these 2 I have right now)
Code:
void setup()
{
  Serial.begin(19200);
  mcp1.begin(0x20);
  mcp2.begin(0x21);
  mcp3.begin(0x22);
  mcp4.begin(0x23);
  mcp5.begin(0x24);
  mcp6.begin(0x25);
  mcp7.begin(0x26);
  mcp8.begin(0x27);
 

Ya’akov

Joined Jan 27, 2019
9,170
like this: (also I understand I will make for only these 2 I have right now)
Code:
void setup()
{
  Serial.begin(19200);
  mcp1.begin(0x20);
  mcp2.begin(0x21);
  mcp3.begin(0x22);
  mcp4.begin(0x23);
  mcp5.begin(0x24);
  mcp6.begin(0x25);
  mcp7.begin(0x26);
  mcp8.begin(0x27);
Yes that's right but if the hex notation doesn't seem to work try decimal 32-39.
 

Thread Starter

q12x

Joined Sep 25, 2015
1,694
As you can see I commented out some lines to bring it back to the basics so to speak.
First of all, I got a bunch of errors, and it turned out to be case sensitive for "Adafruit_MCP23017 " where before I had it Adafruit_mcp23017, probably mess it up with the chat here. Thats no big deal, is resolved now.
Then I have this code I post now, and WITH 0x20 inside mcp1.begin(0x20); nothing works. THere is no error on compilation, but in reality, nothing moves. Then, I revert it back and discovered that mcp1.begin(); as it was before, works fine , but only for the first IC, as before, and not for the second. So this is the difference.
I try the decimals as you suggested. I put in: mcp1.begin(32); And still the same, nothing blinks.

the code so far:
#include "Adafruit_MCP23017.h"
Adafruit_MCP23017 mcp1; //Instantiate mcp1 object
//Adafruit_MCP23017 mcp2; //Instantiate mcp2 object

void setup()
{
  Serial.begin(19200);
  mcp1.begin(0x20);
//  mcp2.begin(0x21);
 
 /* configuring ALL GPIO as output. */
  for(int i = 0; i <= 15; i++)
  {
    mcp1.pinMode(i, OUTPUT);
  }
}



int dly = 100;
void loop()
{
  for(int i = 8; i <=31; i++)
  {
    mcp1.digitalWrite(i, HIGH);
    delay(dly);
    mcp1.digitalWrite(i, LOW);
    delay(dly);
  }
}
 

Ya’akov

Joined Jan 27, 2019
9,170
As you can see I commented out some lines to bring it back to the basics so to speak.
First of all, I got a bunch of errors, and it turned out to be case sensitive for "Adafruit_MCP23017 " where before I had it Adafruit_mcp23017, probably mess it up with the chat here. Thats no big deal, is resolved now.
Then I have this code I post now, and WITH 0x20 inside mcp1.begin(0x20); nothing works. THere is no error on compilation, but in reality, nothing moves. Then, I revert it back and discovered that mcp1.begin(); as it was before, works fine , but only for the first IC, as before, and not for the second. So this is the difference.
I try the decimals as you suggested. I put in: mcp1.begin(32); And still the same, nothing blinks.

the code so far:
#include "Adafruit_MCP23017.h"
Adafruit_MCP23017 mcp1; //Instantiate mcp1 object
//Adafruit_MCP23017 mcp2; //Instantiate mcp2 object

void setup()
{
  Serial.begin(19200);
  mcp1.begin(0x20);
//  mcp2.begin(0x21);

/* configuring ALL GPIO as output. */
  for(int i = 0; i <= 15; i++)
  {
    mcp1.pinMode(i, OUTPUT);
  }
}



int dly = 100;
void loop()
{
  for(int i = 8; i <=31; i++)
  {
    mcp1.digitalWrite(i, HIGH);
    delay(dly);
    mcp1.digitalWrite(i, LOW);
    delay(dly);
  }
}

Wait, what exactly only works for the first one?
 

Ya’akov

Joined Jan 27, 2019
9,170
As you can see I commented out some lines to bring it back to the basics so to speak.
First of all, I got a bunch of errors, and it turned out to be case sensitive for "Adafruit_MCP23017 " where before I had it Adafruit_mcp23017, probably mess it up with the chat here. Thats no big deal, is resolved now.
Then I have this code I post now, and WITH 0x20 inside mcp1.begin(0x20); nothing works. THere is no error on compilation, but in reality, nothing moves. Then, I revert it back and discovered that mcp1.begin(); as it was before, works fine , but only for the first IC, as before, and not for the second. So this is the difference.
I try the decimals as you suggested. I put in: mcp1.begin(32); And still the same, nothing blinks.

the code so far:
#include "Adafruit_MCP23017.h"
Adafruit_MCP23017 mcp1; //Instantiate mcp1 object
//Adafruit_MCP23017 mcp2; //Instantiate mcp2 object

void setup()
{
  Serial.begin(19200);
  mcp1.begin(0x20);
//  mcp2.begin(0x21);

/* configuring ALL GPIO as output. */
  for(int i = 0; i <= 15; i++)
  {
    mcp1.pinMode(i, OUTPUT);
  }
}



int dly = 100;
void loop()
{
  for(int i = 8; i <=31; i++)
  {
    mcp1.digitalWrite(i, HIGH);
    delay(dly);
    mcp1.digitalWrite(i, LOW);
    delay(dly);
  }
}
You can only ever access 16 ports for any object. You have to loop through mcp2 for the second 16.
 
Top