problem with controlling a MCP23s17 chip with a UNO

Hi !

I’m working with an Arduino UNO + Ethernet Shield V3

I’m trying to add Digit IO pins to my project using a MPC23S17 chip (precisely I bought this one : MCP23S17 ) And I’m having hard times…

I’m novice with electronic and wiring, so I tried to look everywhere I can on internet to find a clue on where I did wrong but didn’t find anything yet.

So here is what I did :

#include <MCP23S17.h>

#include <SPI.h>
#include <Ethernet.h>
#include <OSCBundle.h>
#include <EthernetUdp.h>

MCP mcp01(0);

void setup() {

  Serial.begin(9600);  
  SPI.begin();   
  mcp01.pinMode(OUTPUT);
  mcp01.digitalWrite(HIGH);
  Serial.println(mcp01.digitalRead(1));


}

void loop() {
  

}

So this sketch should print a “1” from the pin 1 if i’m not wrong as I digitalWrite all the IO pins of the chip “HIGH”, but actually it only give me 0 for the moment.

  • my problem may probably come from my wiring so I made a shematic of it using Fritzing (fantastic tool by the way !).
    In fritzing, i used a MPC23017 because I didn’t find a MPC23S17 in the object librairy, but both of these chipset have the same number of pins if i’m not wrong so the schematic is the same as my “real” one.

First here is a MPC23S17 pin map :

and here is my shematic (I’m wiring it to the Ethernet Shield as I plugged the Ethernet Shield on the UNO already) :

here is a link to a bigger image if needed :


Does anyboady have an idea of what I did wrong ?

Are you sure that the Ethernet shield does not use pins 10 - 13 ?

you right ! thanks for the answer, I didn't carefully read the documentation, Ethernet Shield use pin 10 11 12 and 13 !
So i can't use both the ethernet shield and the MCP23S17, or could they share those pins ?

Use a different pin for CS.

crasse2:
you right ! thanks for the answer, I didn’t carefully read the documentation, Ethernet Shield use pin 10 11 12 and 13 !
So i can’t use both the ethernet shield and the MCP23S17, or could they share those pins ?

11, 12, and 13 can share. That’s the SPI bus. But you need a different chip select pin.

Hi ! Thanks for your answer !

using a different pin for CS won't cause problems, because it seems that CS should go to the Slave Select pin (10) of the arduino in order to be known as a slave (the chipset) of the main board ?

10 MUST be an output and therefore should be used as a slave select. But any pin can be slave select since it is your responsibility to set it low in code before writing to the SPI slave. Since the Ethernet shield is already using 10 as slave select for the Ethernet chip and 4 for slave select for the sd card if it has one, then you need to choose a different pin for the slave select for the port expander.

OK ! thanks, I begin to understand, so if i'm right, i need to change the port to for example (9) in the cpp class file of the MCP23S17 (here on line 50) :

and then just precise :

pinMode(9,OUTPUT);

SPI.begin();

with the chip's CS pin plugged into the 9 input of the Ethernet Shield ?

#define    SS            (10)          // SPI bus slave select output to pin 10 - READ ARDUINO SPI DOCS BEFORE CHANGING!!!

Probably this line too.

Ok, thanks ! that was the line I was talking about :slight_smile: (meaning I'm a bit less lost, and that's satisfaying)

just a question, why did the author of this class added a strong warning aside of this parameter (the SS pin number), can I damage the Arduino or the chipset if I do something wrong with it ?

Nope, he just wanted to make sure you know what you're doing. If you try to make 10 an input, it will put the SPI bus into slave mode and none of the SPI comms will work. That's about the only way you can mess up. It MUST be an output but it doesn't matter what you do with it. You could use it to drive an LED and use a different pin for SS if you want.

Hi ! Thanks for these useful informations !

unfortunately I didn’t manage to get the Arduino and the MCP23S17 communicating to each other.

I tried an older librairy of MCP23S17 (not provided anymore through Arduino Playground) called Mcp23s17 (not MCP23S17) and using an older version of SPI.h, called Spi.h, and didn’t get any results either, so I got back to the current one provided by the Arduino site.

I found another schematic, (in the librairy’s help/example files) of how to connect it to the Arduino :

the MCP23S17 (as the author of the schematic moved them) :

However I don’t understand why Ax pins and VSS pin are connected to 2 GND (what is the green GND ?)
Anyway I did that, trying to match the schematic (click to enlarge) :

So my chip address should be (1) as told here :

So now I’m using the Arduino pin 9 as SS/CS for the MCP chip, as the Ethernet Shield already use the 10. In order to do so I modified this line (line 50) in the MCP23S17.cpp, which was previously set on (10)

#define    SS            (9)          // SPI bus slave select output to pin 10 - READ ARDUINO SPI DOCS BEFORE CHANGING!!!

here the full cpp :

MCP23S17.cpp

and finally here is my sketch :

#include <MCP23S17.h>
#include <SPI.h>
#include <Ethernet.h>
#include <OSCBundle.h>
#include <EthernetUdp.h>

#define UDP_TX_PACKET_MAX_SIZE 60

byte mac[] = {
  0x90, 0xA2, 0xDA, 0x0F, 0x3B, 0x9D
};

int CS2= 9;

MCP mcp01(1); //With  A0 to 5V _ A1 to GND _ A2 to GND

void setup() {

  Serial.begin(9600);   
  
  pinMode (CS2, OUTPUT);
  SPI.begin();

  mcp01.pinMode(OUTPUT);
  mcp01.digitalWrite(HIGH);
  
  Serial.println(mcp01.digitalRead(1));
  //mcp01.pullupMode(HIGH); 


  Udp.begin(localPort);
}

void loop() {
}


  
}

So logically I should see both of the LED ON as I DigitalWrite(HIGH) every pins of the MCP chip, but they aren’t.

Does anybody have an idea of what is going on, or not going on here ?

Hi again !

I found some informations relative to adding an External SPI device (as the MCP23S17) while using an Ethernet Shield :

Basically, multiple SPI slave usage is the same as single SPI slave usage. One difference between other SPI slave devices compared to the W5100 is that the MISO output is continuously driven in the W5100 whether the /SCS is asserted as high or as low. As well, when the 5100 /SCS is asserted as high when using multiple slaves, other SPI devices cannot be read or written by the SPI master on the SPI BUS simultaneously. These problems will continue unless the recommendations listed below are followed.
Recommendations:
– When accessing another device on the SPI BUS rather than the W5100, assert the SEN pin in the W5100 as low first, then access the other devices.
– When accessing the W5100, the SEN pin should be high.

full content here :
http://john.crouchley.com/blog/archives/662

But looking more into those informations, I ended up on this product :
Freetronic Ethernet Shield

in the description there is this interesting, refering to officials Arduino Ethernet Shields :
SPI Fixes
Combining Ethernet with other SPI devices can be really tricky because the Wiznet chip doesn't relinquish the bus properly when it's deselected. To fix that problem we slaved the Wiznet's SEN (SPI Enable) line to the CS (Chip Select) line, which means that whenever your sketch deselects the Ethernet connection in order to talk to another SPI device it will work exactly the way it should.
No more messing around with cutting tracks and other nasty hacks you may have seen mentioned on the forums.

So, in conclusion, Do i have to think about buying another Ethernet Shield in order to add other SPI device to my project while using Ethernet Shield or is there a way to solve this problem with the current Ethernet Shield V3 ?

Hi again :slight_smile: !

So, I decided to get rid temporaly of the Ethernet Shield and to connect directly the MCP23S17 to the UNO.

And in fact it doesn’t work either… :confused:

I looked everywhere for different schematic of connection between this chip and the UNO, and applied everything I could find, and nothing worked.

So basicly here is what I got right now :

the wiring (based on the one here http://playground.arduino.cc/Main/MCP23S17 )


(click to enlarge)

I modified back the cpp librairy of the chip to put the CS pin on (10) as it was originally

and then here is my code (based on the examples also here http://playground.arduino.cc/Main/MCP23S17 )

#include <SPI.h>
#include <MCP23S17.h>
MCP mcp01(0);

void setup() {
  Serial.begin(9600);   

  pinMode(3,OUTPUT);
  digitalWrite(3,HIGH); 

  for (int i = 1; i <= 16; i++) {   
    mcp01.pinMode(i, OUTPUT);
      mcp01.digitalWrite(i,HIGH); 
  } 
  delay(10);

      for (int i = 0;i<=15;i++){
  Serial.println(String("MCP_01 : ")+mcp01.digitalRead(i));
  }
  Serial.println(String("pin03 : ")+digitalRead(3));
} 

void loop() {
}

and yet in the serial window i got this :

MCP_01 : 0
MCP_01 : 0
MCP_01 : 0
MCP_01 : 0
MCP_01 : 0
MCP_01 : 0
MCP_01 : 0
MCP_01 : 0
MCP_01 : 0
MCP_01 : 0
MCP_01 : 0
MCP_01 : 0
MCP_01 : 0
MCP_01 : 0
MCP_01 : 0
MCP_01 : 0
pin03 : 1

So basicly the communication between the UNO and the chip isn’t established yet and I really don’t understand why, does anybody have an idea of what could possibly go wrong ?

I am in the same exact situation as you except without the ethernet shield. I can not get this chip to work at all. Everyone says SPI is easier to work with than I2C, I don't see it. Here is my post at an external website, no answers so far.

I have tried two libraries with no luck, all I want to do is light up one led. How hard can this be? I don't understand how no one can help us. There are plenty of youtube videos on it working but not how to use it? I'm fairly new, but I have had no problem getting anything else somewhat advanced to work (SD Cards, WIFI, Shift Registers, 4x20 lcd). Why is this is so hard? It blows my mind how no one can help.

Okay I was finally able to get it to work, input and output, simply using just the SPI.h library. The other libraries I tried never worked and seemed to make it more complicated. Just using the SPI.h library actually taught me a lot and the code is actually fairly simple. Only about 50 line of code for a simple program.