Go Down

Topic: MCP23S17 does not work with Mega2560 (Read 501 times) previous topic - next topic


Hi all,

for my step sequencer project I will use 8 MCP23S17 SPI Port Expander to interface all the switches an LEDs. It operates with the Arduino UNO as exected and shown here: http://hartgeloetet.blogspot.de/2013/03/musik-schritt-fur-schritt-teil-2.html

In my sketches I use the MCP23S17 Class von Cort Buffington: http://playground.arduino.cc/Main/MCP23S17

Than I tried to do the same job with an Arduino Mega2560. Due to the other SPI-pins of the Mega (50...53) I build a new cable from my SPI-Board to the Arduino Mega. The cable is tested and it is ok. The Mega and the SPI-Board are powered up and the power levels are also ok.

But after uploading this test code:

Code: [Select]
#include <SPI.h>             
#include <MCP23S17.h>         

MCP inputchip(5);             
MCP outputchip(0);           

void setup() {
  for (int i = 1; i <= 16; i++) {   
    inputchip.pinMode(i, HIGH);     
    inputchip.pullupMode(i, HIGH);   
    inputchip.inputInvert(i, HIGH); 
    outputchip.pinMode(i, LOW);     

void loop() {
  for (int i = 1; i <=16; i++) {       
    int value;                         
    value = inputchip.digitalRead(i); 
    outputchip.digitalWrite(i, value);

If I push a switch, the appropriate LED lights up, when I use the UNO. But with the Mega, no reaction.

After that I thought it was something wrong with the hardware an I double-checked the board an made some test with a single MCP23S17 on a breadboard. The result was the same: UNO works, Mega don't work. The SPI pins are working correctly, because a test with a MicroSD card breakout board was successful.

Any idea what 's going on there? Is there maybe a problem with the library?
A web research was unsuccessful. A lot of people used the MCP with the UNO but it seems no one used one with the Mega.

Any help appreciated. Thanks in advance.

Nick Gammon

Did you change this?

Code: [Select]

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

Or this:

Code: [Select]

// GENERIC BYTE WRITE - will write a byte to a register, arguments are register address and the value to write

void MCP::byteWrite(uint8_t reg, uint8_t value) {      // Accept the register and byte
  PORTB &= 0b11111011;                                 // Direct port manipulation speeds taking Slave Select LOW before SPI action
  SPI.transfer(OPCODEW | (_address << 1));             // Send the MCP23S17 opcode, chip address, and write bit
  SPI.transfer(reg);                                   // Send the register we want to write
  SPI.transfer(value);                                 // Send the byte
  PORTB |= 0b00000100;                                 // Direct port manipulation speeds taking Slave Select HIGH after SPI action

Port manipulation is always fraught when changing processors. That is almost certainly the problem.

I did some stuff with this port expander a while back (using I2C). Someone did an SPI version:


The code there may help.


Hi Nick,

thanks for the hint at:

Code: [Select]
PORTB &= 0b11111011;
PORTB |= 0b00000100;   

I didn't realize the impact of this code. Now I learned how to use it and I changed it to

Code: [Select]
PORTB &= 0b11111110;
PORTB |= 0b00000001;   

for Pin 53 which is Pin B0 at the ATmega2560.
The first entry you adives to I changed to

Code: [Select]
#define    SS            (53)

before, which didn't work without the other changes.
Now it is done and it works well.

Thanks a lot!

Go Up