How to drive SPI MAX7219 7-segment led module using MCP23S17 extender I have used Nick Gammon's (MAX7219) and (bitBangedSPI) libraries to drive SPI 7-segment 8 digit led modules successfully from the Arduino Uno.  I would like to extend the number of Slave Select (CS) choices by using the MCP23S17 chip.  The Mcp23s17 libraries to use might be https://github.com/dreamcat4/Mcp23s17 or https://github.com/MajenkoLibraries/MCP23S17.  I have found the stackExchange entry How do you use SPI on an Arduino? to be helpful and this entry to be helpful http://www.ermicro.com/blog/?p=1050, but all the examples just turn on LED lights, not digits of 7-segment led modules.

I realize I might have to modify the MAX7219 and bitBangedSPI libraries where the digitalWrite command is used.  However, I'm not sure how to modify or drive these 7-segement modules using the MCP23S17 chip.

A skeleton script to display PI selected on pin 6 on the Uno and address 0x0 of the MCP23S17 is shown below.  I would like to choose which pinout to utilize as well but am not sure how this would be coded.


#include &lt;SPI.h&gt;
#include &lt;bitBangedSPI.h&gt;
#include &lt;MAX7219.h&gt;
// Mcp23s17 library available from https://github.com/dreamcat4/Mcp23s17
#include &lt;Mcp23s17.h&gt;

// Wire up the SPI Interface common lines:
// #define SPI_MOSI             7 //arduino   &lt;-&gt;   SPI Master Out Slave In   -&gt; SI  (Pin 13 on MCP23S17 DIP)
// #define SPI_MISO   not used 12 //arduino   &lt;-&gt;   SPI Master In Slave Out   -&gt; SO  (Pin 14 on MCP23S17 DIP)
// #define SPI_CLOCK            8 //arduino   &lt;-&gt;   SPI Slave Clock Input     -&gt; SCK (Pin 12 on MCP23S17 DIP)

// Then choose any other free pin as the Slave Select (pin 10 if the default but doesn't have to be)
#define MCP23S17_SLAVE_SELECT_PIN  6 //arduino   &lt;-&gt;   SPI Slave Select           -&gt; CS  (Pin 11 on MCP23S17 DIP)
// MULTIPLE DEVICES
// Up to 8 MCP23S17 devices can share the same SPI bus and slave select pins.
// Assign each chip a unique 3-bit device address (by setting the A2,A1,A0 pins)
// Then below, device address is optional 2nd parameter to the constructor fn...
// MCP23S17 Mcp23s17_0 = MCP23S17(MCP23S17_SLAVE_SELECT_PIN,0x0);
// ...
// MCP23S17 Mcp23s17_7 = MCP23S17(MCP23S17_SLAVE_SELECT_PIN,0x7);

// SINGLE DEVICE
// Instantiate a single Mcp23s17 object
MCP23S17 Mcp23s17_0 = MCP23S17(MCP23S17_SLAVE_SELECT_PIN,0x0);
const byte chips = 1;
static char outputBuffer[20]; // outputBuffer[] likely 2x the size it needs to be.

 // 1 chip, bit banged SPI on pins 6, 7, 8

MAX7219 display(chips, 6, 7, 8);  // Chips / LOAD / DIN / CLK
void setup()
{
    // Set all pins to be outputs (by default they are all inputs)
    Mcp23s17_0.pinMode(OUTPUT);

    display.begin();
    display.setIntensity(1);
    float pi = PI;
    dtostrf(pi, 7, 7, outputBuffer);
    display.sendString(outputBuffer);

}  // end of setup

void loop() { }


An example of the 8-digit 7-segment display.  They are available on Amazon, Ebay, AliExpress etc. This one has 0.33 inch digits; other modules are 0.56 inch digits.
I'm not 100% on what you want to do but I have used both the chips you seem to want to do it with.

The MAX7219 can control 8 7Segment displays.
I don't remember it being an SPI device, you just set the pattern you want in the registers and off it goes.  (It could be that is used such a high level abstraction that I didn't realise it was SPI)

The IOX chip you are referring to is quite similar in behaviour, you setup the registers and away it goes.

On the surface it appears you can do what you want, but I suspect you will hit timing issues unless you want very static displays (maybe &lt; 1FPS).  The time it takes you to establish the correct settings on the IOX chips will be the limiting factor.

You might want to look at the I2C version of the IOX which will require just 2 pins to connect to up to 7 ICs.

Alternatively use a network of microprocessors to each drive the maximum number of MAX7219s that they can, such as Nanos, ESP8266-12/NodeMCU, etc.