Closed thijstriemstra closed 2 years ago
An interesting thing about the mcp23s17 is that it is controlled by SPI but still uses addresses which you set with the three address pins. Therefor you have two options to connect three mcp23s17: 1) You use the same CS pin for all three mcp23s17, but set different addresses, like this:
#define CS_PIN 7
#define RESET_PIN 99 // 99 for software reset
#define MCP_ADDRESS_1 0x20 // (A2/A1/A0 = LOW)
#define MCP_ADDRESS_2 0x21 // A2,A1 = LOW, A0= HIGH
#define MCP_ADDRESS_3 0x22 // A2,A0 = LOW, A1 = HIGH
MCP23S17 myMCP_1 = MCP23S17(CS_PIN, RESET_PIN, MCP_ADDRESS_1);
MCP23S17 myMCP_2 = MCP23S17(CS_PIN, RESET_PIN, MCP_ADDRESS_2);
MCP23S17 myMCP_3 = MCP23S17(CS_PIN, RESET_PIN, MCP_ADDRESS_3);
2) You use different CS Pins and the same address, like this:
#define CS_PIN_1 7
#define CS_PIN_2 8
#define CS_PIN_3 9
#define RESET_PIN 99 // 99 for software reset
#define MCP_ADDRESS 0x20 // (A2/A1/A0 = LOW)
MCP23S17 myMCP_1 = MCP23S17(CS_PIN_1, RESET_PIN, MCP_ADDRESS);
MCP23S17 myMCP_2 = MCP23S17(CS_PIN_2, RESET_PIN, MCP_ADDRESS);
MCP23S17 myMCP_3 = MCP23S17(CS_PIN_3, RESET_PIN, MCP_ADDRESS);
Option 1 uses less pins, therefore I would prefer this option.
thanks for the clear explanation!
It seems this doesn't work as expected; with this setup:
#define CS_PIN 5
#define RESET_PIN 99 // 99 for software reset
#define MCP_ADDRESS_1 0x20 // (A2/A1/A0 = LOW)
#define MCP_ADDRESS_2 0x21 // A2,A1 = LOW, A0= HIGH
MCP23S17 myMCP_1 = MCP23S17(CS_PIN, RESET_PIN, MCP_ADDRESS_1);
MCP23S17 myMCP_2 = MCP23S17(CS_PIN, RESET_PIN, MCP_ADDRESS_2);
and a method like this:
void cycleLED(MCP23S17 *mcp) {
mcp->setPortMode(0b11111111, A); // Port A: all pins are OUTPUT
mcp->setPortMode(0b11111111, B); // Port B: all pins are OUTPUT
mcp->setAllPins(A, OFF); // Port A: all pins are LOW
mcp->setAllPins(B, OFF); // Port B: all pins are LOW
delay(wT);
mcp->setAllPins(A, ON); // Port A: all pins are HIGH
mcp->setAllPins(B, ON); // Port B: all Pins are HIGH
delay(wT * 3);
byte portValue = 0;
for (int i=0; i<8; i++){
portValue += (1<<i); // 0b00000001, 0b00000011, 0b00000111, etc.
mcp->setPort(portValue, A);
delay(wT);
}
portValue = 0;
for (int i=0; i<8; i++){
portValue += (1<<i); // 0b00000001, 0b00000011, 0b00000111, etc.
mcp->setPort(portValue, B);
delay(wT);
}
mcp->setAllPins(A, OFF); // Port A: all pins are LOW
mcp->setAllPins(B, OFF); // Port B: all pins are LOW
delay(wT);
mcp->setAllPins(A, OFF); // Port A: all pins are LOW
mcp->setAllPins(B, OFF); // Port B: all pins are LOW
delay(wT);
}
and then calling it for both MCPs in setup()
:
// cycle through leds
cycleLED(myMCP_1);
delay(1000);
cycleLED(myMCP_2);
results in the led sequence being shown twice on the _mcp1
instance, instead of first on _mcp1
and then on _mcp2
. So it ignores the second mpc it seems..
Have you tested it with 2 mcp23s17's @wollewald?
Hi @thijstriemstra , I thought I had replied to your last comment, but it seems I haven't. The problem was that the SPI hardware addressing needs to be enabled which I had not done. I have already corrected this in July. Not sure if you had tested it. However it worked after the change on my side.
I thought I had replied to your last comment, but it seems I haven't. The problem was that the SPI hardware addressing needs to be enabled which I had not done.
Oh my! That's good to hear, I'll give it a try asap and get back to you.
Reference to release notes for that change: https://github.com/wollewald/MCP23017_WE/releases/tag/1.5.4
ps. could you give this ticket the 'bug' label?
@wollewald I tested again and unfortunately it still doesn't seem to work. I have A0/A1=LOW and A2=HIGH on my 2nd MCP23S17 (which comes down to 0x24? I tried all addresses and still no luck though).
The all important question for me: have you tested using multiple MCP23S17 devices yourself?
I also looked at https://registry.platformio.org/libraries/robtillaart/MCP23S17 and that readme has the following note:
sharing select lines
(not tested) Technically two chips could use the same select pin and a different address. The constructors would allow to setup such a configuration. I assume that this is less used and IMHO not recommended.
Which makes me wonder if I should add a separate ESP32 pin for each MCP23S17 CS pin instead of sharing one for multiple MCP23S17?
I opened https://github.com/RobTillaart/MCP23S17/issues/15 to clarify why it's not recommended.
@thijstriemstra, I have just tried it again and it works on my side. I took an Arduino Nano and applied the following sketch:
#include <SPI.h>
#include <MCP23S17.h>
#define CS_PIN 7
#define RESET_PIN 5
#define MCP_ADDRESS_1 0x20 // (A2/A1/A0 = LOW)
#define MCP_ADDRESS_2 0x24 // (A2=HIGH, A1/A0 = LOW)
MCP23S17 myMCP_1 = MCP23S17(CS_PIN, RESET_PIN, MCP_ADDRESS_1);
MCP23S17 myMCP_2 = MCP23S17(CS_PIN, RESET_PIN, MCP_ADDRESS_2);
void setup(){
Serial.begin(9600);
SPI.begin();
myMCP_1.Init();
myMCP_2.Init();
myMCP_1.setPortMode(0b11111111, A); // Port A: all pins are OUTPUT except pin 1
myMCP_2.setPortMode(0b11111111, A); // Port B: all pins are OUTPUT
for(int i=0; i<8; i++){
uint8_t portValue = 1<<i;
myMCP_1.setPort(portValue,A);
delay(200);
}
for(int i=0; i<8; i++){
uint8_t portValue = 1<<i;
myMCP_2.setPort(portValue,A);
delay(200);
}
}
void loop(){
}
And as expected first all LEDs of port A on the first MCP23S17 (MCP_1) flashed and then the same on the second one.
Both MCP23S17 were attached to the same CS, MISO, MOSI, SCK pins and I used pin 5 as reset pin.
I tried the same with the only difference that I chose pin 99 as RESET_PIN and connected the reset pin of both MCP23S17 modules to VCC and it also worked.
Hmm, strange...
So, the question is what is different on your side. You used an ESP32 - anything else different?
So, the question is what is different on your side. You used an ESP32 - anything else different?
Yes, the reset pin. Could you also try it with reset pin 99 that I'm using?
Oh you already tested that..
I chose pin 99 as RESET_PIN and connected the reset pin of both MCP23S17 modules to VCC and it also worked.
I'll have to double-check that I connected the reset pin of both MCP23S17 modules to VCC.
Check.
Just for information: I have now also tried an ESP32 development board and it also worked. Same sketch, except CS_PIN which was 5. RESET_PIN = 99, MISO = 19, MOSI = 23, SCK = 18.
thanks for the confirmation. I think there's something wrong with my 2nd mcp23s17 board/setup so I switched that 2nd to a MCP23017 (for now).
I'd like to use 3 MCP23S17 devices to control 40 LEDs in total. How would this work? How do I configure these 3 instances? Do they all need a different CS pin?