Using I²C Expander for SPI CS or any other Lib that asks for a Pin Number


I didn’t find a nice way (without changing Lirbarys) to use I²C expanders Pins as "Any"Library Pin definition.

I have a lot of IO’s and I don’t want to waste MCU pins for simple digitalWrite functions, so I installed a MCP23017 as I²C Expander to use those pins as CS Pins or for simple digital stuff.

What I didn’t thought about was the it is nessasary to use Ardunino Pin numbers for every Arduino Lib that asks for a Pin…

Lets have a example:

The MCP23017 needs called with:

#include "Adafruit_MCP23017.h"
Adafruit_MCP23017 binaryIO;          //Create Object

void setup()
binaryIO.begin(Addr_Binary_MCP23017);       //Give it a address

binaryIO.digitalWrite(PIN,HIGH)  //Set the Pin to HIGH

The SD Libary needs:

#include <SPI.h>
#include <SD.h>

void setup()
SD.begin(binaryIO.digitalWrite(PIN,HIGH/LOW)   //You get the idea...

So the question is: How do I manage to tell the (for example) SD Lib to use the digitalwrite function from the binaryIO object and not the arduino core function?

The only thing I found was a merge request for the arduino core functions that goes in the right direction.

Thanks :slight_smile:

Without modifying the library or the Arduino core (in ways that would significantly and negatively impact performance for the vastly-more-common case of not using a port expander), this is not possible. You must modify the libraries to call a different version of the pin-manipulation functions, or modify digitalRead()/digitalWrite(). Some libraries may use direct port manipulation - this would require even more work to convert, and the fact that they chose to use it indicates that they were concerned with execution speed so a port expander might not be appropriate in any case.

I would suggest instead adjusting your design so that pins on the actual microcontroller are reserved for things that need to be passed to libraries, and using the port expanders for pins that don't need to be interacted with by libraries.

I actually think it would be a very nice feature, for sure not for all libs but for a lot of them.

Custom changes on the used libs are not very a option if you like to keep them updated, same with the arduino core.

In my case a redesign with 30 IOs on a ESP32 is not possible.