Problème d'interruption avec un expandeur de GPIO MCP23S17

Bonjour !

Pour un projet j'ai besoin d'un expander de GPIO, utilisé avec un clone de Pro Micro 5V.
Je fais avec ce que j'ai sous la main, en l'occurrence un MCP23S17, donc sur bus SPI.
Dans mon projet final, j'aurais besoin d'utiliser une partie des broches en sortie et une autre en entrée, j'ai donc fait un circuit sur breadboard avec d'une part 10 leds et de l'autre 4 boutons.

Les leds forment un chenillard, cette partie fonctionne sans problème, c'est avec mes boutons que j'ai un souci.

Plutôt que de constamment tester leur état, je souhaite utiliser une des deux sorties d'interruption du MCP23S17.
Les boutons sont sur le port B, configurés comme entrées avec pull-up et interruption sur FALLING, la broche 19 (INTB) du MCP23S17 est reliée à la D3 de l'Arduino (INT0). Quand une interruption intervient sur le MCP23S17, INTB doit passer à l'état LOW, ce qui doit déclencher un interrupt sur l'Arduino qui est en mode FALLING.

Mon problème est que ça ne fonctionne qu'une fois, la broche du MCP23S17 reste à l'état LOW, même après lecture du port B. De ce que je comprends de la documentation de la librairie et du datasheet de la puce, l'interrupt devrait être "nettoyé" après la lecture des valeurs du port et donc la broche revenir à l'état HIGH, mais ça n'arrive pas.
Si je débranche et rebranche le fil qui va à D3, ça déclenche une nouvelle interruption (alors qu'on passe de LOW à HIGH, on serait donc plutôt sur un mode CHANGE ou RISING ???) et la broche du MCP23S17 revient à l'état HIGH.

Je pense que l'erreur vient de moi et doit être toute bête, mais j'avoue que je sèche...
Merci d'avance d'éclairer ma lanterne !

Le script utilise actuellement la bibliothèque de Majenko, j'ai essayé aussi avec celles d'Adafruit et de Rob Tillaart, avec à chaque fois le même résultat.

Voici mon code et le schéma du circuit:

#include <MCP23S17.h>

// SPI Chip Select
#define CS_PIN 10
// MCP23S17 Reset pin
#define MCP_RESET 9
// Arduino's external interrupt pin (INT0)
#define INTERRUPT_PIN 3

MCP23S17 mcp(&SPI, CS_PIN, 0);  // address 0: Pins A0,A1,A2 grounded
volatile uint8_t flagMCPB = 0;

int theLeds = 1;


void isr();
void handleKeyPressed();

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

  pinMode(MCP_RESET, OUTPUT);
  // Reset MCP23S17
  digitalWrite(MCP_RESET, LOW);
  delay(100);
  digitalWrite(MCP_RESET, HIGH);

  mcp.begin();

  // set Port Expander Interrupt configuratons
  mcp.setMirror(false);
  mcp.setInterruptOD(false);
  mcp.setInterruptLevel(LOW);
  // clear all interrupts on MCP23S17
  mcp.getInterruptValue();
  mcp.getInterruptPins();
  // uint16_t mcpReading = mcp.getInterruptValue();
  // uint16_t mcpPins = mcp.getInterruptPins();

  // Arduino's Interrupt
  pinMode(INTERRUPT_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), isr, FALLING);

  // configure pins for 10 leds
  // GPA0..7, GPB0, GPB1
  for (uint8_t i = 0; i < 10; i++) {
    mcp.pinMode(i, OUTPUT);
  }
  // configure pins for buttons
  // GPB2, GPB3, GPB4, GPB5
  for (uint8_t i = 10; i < 14; i++) {
    mcp.pinMode(i, INPUT_PULLUP);
    mcp.enableInterrupt(i, FALLING);
  }

  Serial.println();
  Serial.println("-------------------------------------------");
  Serial.println("MCP23S17 Ready!");
  Serial.println("-------------------------------------------");
  Serial.println();
}

void loop() {
  // Btns interrupts
  if (flagMCPB == 1) {
    handleKeyPressed();
  }

  // Blinking leds
  theLeds = theLeds << 1;
  if (theLeds == 1024) theLeds = 1;
  mcp.writePort(0, theLeds);  // Port, Val
  mcp.writePort(1, (int)theLeds >> 8);
  delay(80);
}

void isr() {
  flagMCPB = 1;
}

void handleKeyPressed() {
  // read port B (and hopefully clears the interrupt)
  uint8_t mcpBReading = mcp.getInterruptBValue();  // reads PORTB
  mcpBReading = mcpBReading >> 2;                  // first btn is GPB2
  mcpBReading = ~mcpBReading;                      // flip the bits (PORTB is 0b1111 by default, due to pullups)

  Serial.print("InterruptPins: 0b");
  Serial.println(mcp.getInterruptPins(), 2);
  Serial.print("InterruptValue: 0b");
  Serial.println(mcp.getInterruptValue(), 2);
  Serial.print("B Pins: 0b");
  Serial.println(mcp.getInterruptBPins(), 2);
  Serial.print("B Values: 0b");
  Serial.println(mcp.getInterruptBValue(), 2);

  if ((int)(mcpBReading & 0b1000) == 8) {
    Serial.println("Bouton 1");
  }
  if ((int)(mcpBReading & 0b0100) == 4) {
    Serial.println("Bouton 2");
  }
  if ((int)(mcpBReading & 0b0010) == 2) {
    Serial.println("Bouton 3");
  }
  if ((int)(mcpBReading & 0b0001) == 1) {
    Serial.println("Bouton 4");
  }

  delay(100);    // de-bounce before we re-enable interrupts
  flagMCPB = 0;  // Ready for next interrupt
  mcpBReading = 0;
}

Bonjour essayez de supprimer la possibilité d'interruption pendant le traitement du code d'interruption et réactivez le a la fin.
je parle du mcp pas de l'interuption arduino.

Bonjour,

A mon avis il faut que tu lises le port dans isr() sinon tu reprends la même interruption dès que tu sort de isr().