[RESOLVIDO] Não consigo mudar o status da interrupção do MCP23017

Galera, me ajudem por gentileza. Tenho um Arduino MEGA 2560 conectado a um MCP23017. Conectei o pino 19 do MCP23017 - INTB - ao pino digital 2 do Arduino. Quando vou ler a saída na serial do pino 2 do Arduino, ele dá status = 1, independente do que eu mude nas entradas/saídas do MCP23017. Tentei colocar tanto GPIOA quanto GIPOB com todas portas = 0. Não funcionou. Resolvi deixá-lo no status default, como mostra o datasheet na tabela 1-6 da página 11. E continua dando status = 1 no pino 2 do Arduino. Se eu retiro a conexão do pino 19 do MCP23017 o pino 2 do Arduino dá status = 0. Ou seja, a interrupção do MCP23017 sempre sai igual a 1. Alguém sabe o que pode ser? Segue o código com a única função de deixar o MCP23017 no status default apresentado no datasheet.

#include "Wire.h"

int interrupt = 0;

#define mcp_address 0x20
#define IODIRA   0x00   // IO direction  (0 = output, 1 = input (Default))
#define IODIRB   0x01
#define IOPOLA   0x02   // IO polarity   (0 = normal, 1 = inverse)
#define IOPOLB   0x03
#define GPINTENA 0x04   // Interrupt on change (0 = disable, 1 = enable)
#define GPINTENB 0x05
#define DEFVALA  0x06   // Default comparison for interrupt on change (interrupts on opposite)
#define DEFVALB  0x07
#define INTCONA  0x08   // Interrupt control (0 = interrupt on change from previous, 1 = interrupt on change from DEFVAL)
#define INTCONB  0x09
#define IOCON   0x0A   // IO Configuration: bank/mirror/seqop/disslw/haen/odr/intpol/notimp
// #define IOCON   0x0B   // IO Configuration: bank/mirror/seqop/disslw/haen/odr/intpol/notimp
#define GPPUA    0x0C   // Pull-up resistor (0 = disabled, 1 = enabled)
#define GPPUB    0x0D
#define INTFA   0x0E   // Interrupt flag (read only) : (0 = no interrupt, 1 = pin caused interrupt)
#define INTFB   0x0F
#define INTCAPA  0x10   // Interrupt capture (read only) : value of GPIO at time of last interrupt
#define INTCAPB  0x11
#define GPIOA    0x12   // Port value. Write to change, read to obtain value
#define GPIOB    0x13
#define OLATA   0x14   // Output latch. Write to latch output.
#define OLATB   0x15

void setup() {
  Serial.begin(9600);
  pinMode(2, INPUT);
  Wire.begin(); // iniciar I2C

  // IOCON.BANK defaults to 0 which is what we want.
  // So we are using Table 1-4 on page 9 of datasheet  

  Wire.beginTransmission(mcp_address);
  Wire.write((byte) IODIRA); // IODIRA register
  Wire.write((byte) 0xFF); // set all of bank A to outputs
  Wire.endTransmission();

  Wire.beginTransmission(mcp_address);
  Wire.write((byte) IODIRB); // IODIRA register
  Wire.write((byte) 0xFF); // set all of bank A to outputs
  Wire.endTransmission();

  Wire.beginTransmission(mcp_address);
  Wire.write((byte) IOPOLA);
  Wire.write((byte) 0x00);
  Wire.endTransmission();

  Wire.beginTransmission(mcp_address);
  Wire.write((byte) IOPOLB);
  Wire.write((byte) 0x00);
  Wire.endTransmission();

  Wire.beginTransmission(mcp_address);
  Wire.write((byte) GPINTENA);
  Wire.write((byte) 0x00);
  Wire.endTransmission();

  Wire.beginTransmission(mcp_address);
  Wire.write((byte) GPINTENB);
  Wire.write((byte) 0x00);
  Wire.endTransmission();

  Wire.beginTransmission(mcp_address);
  Wire.write((byte) DEFVALA);
  Wire.write((byte) 0x00);
  Wire.endTransmission();

  Wire.beginTransmission(mcp_address);
  Wire.write((byte) DEFVALB);
  Wire.write((byte) 0x00);
  Wire.endTransmission();

  Wire.beginTransmission(mcp_address);
  Wire.write((byte) INTCONA);
  Wire.write((byte) 0x00);
  Wire.endTransmission();

  Wire.beginTransmission(mcp_address);
  Wire.write((byte) INTCONB);
  Wire.write((byte) 0x00);
  Wire.endTransmission();

Wire.beginTransmission(mcp_address);
  Wire.write((byte) IOCON);
  Wire.write((byte) 0x00);
  Wire.endTransmission();

  Wire.beginTransmission(mcp_address);
  Wire.write((byte) GPPUA);
  Wire.write((byte) 0x00);
  Wire.endTransmission();

  Wire.beginTransmission(mcp_address);
  Wire.write((byte) GPPUB);
  Wire.write((byte) 0x00);
  Wire.endTransmission();

  Wire.beginTransmission(mcp_address);
  Wire.write((byte) INTFA);
  Wire.write((byte) 0x00);
  Wire.endTransmission();

  Wire.beginTransmission(mcp_address);
  Wire.write((byte) INTFB);
  Wire.write((byte) 0x00);
  Wire.endTransmission();

  Wire.beginTransmission(mcp_address);
  Wire.write((byte) INTCAPA);
  Wire.write((byte) 0x00);
  Wire.endTransmission();

  Wire.beginTransmission(mcp_address);
  Wire.write((byte) INTCAPB);
  Wire.write((byte) 0x00);
  Wire.endTransmission();

  Wire.beginTransmission(mcp_address);
  Wire.write((byte) GPIOA);
  Wire.write((byte) 0x00);
  Wire.endTransmission();

  Wire.beginTransmission(mcp_address);
  Wire.write((byte) GPIOB);
  Wire.write((byte) 0x00);
  Wire.endTransmission();

  Wire.beginTransmission(mcp_address);
  Wire.write((byte) OLATA);
  Wire.write((byte) 0x00);
  Wire.endTransmission();

  Wire.beginTransmission(mcp_address);
  Wire.write((byte) OLATB);
  Wire.write((byte) 0x00);
  Wire.endTransmission();

}

void loop() {
  Serial.print("interrupcao = ");
  interrupt = digitalRead(2);
  Serial.println(interrupt);
  delay(500);
}

Ola amigo
O que te deve estar a acontecer é que o pino efectivamente muda mas muda mais rapido do que quando tu o vais ler.
Sempre que alguns dos estados nos GPIO do MCP23017 muda o pino de interrupçao deve fazer uma transição de High para Low muito rapidamente.Para que tu dês conta dessa mudança nao podes usar um digitalRead ja que quando tentares ler o pino ele ja mudou á muito...
A solução é usares interrupções.
Na documentaçao do arduino tens este exemplo:

int pin = 13;
volatile int state = LOW;

void setup()
{
  pinMode(pin, OUTPUT);
  attachInterrupt(0, blink, CHANGE);
}

void loop()
{
  digitalWrite(pin, state);
}

void blink()
{
  state = !state;
}

Podes pegar nele e adaptar para o teu pino.Nota que neste exemplo é usado a Interrupt0 logo tens de colocar o pino da interrupção do MCP23017 no pino 2 do Mega.
para testares se alterares qualquer estado no MCP deves ver o led 13 a acender ou a apagar.

HugoPT, obrigado pela ajuda, mas infelizmente não deu certo. Continua dando sempre sinal alto na saída da interrupção. Tentei até por um LED direto na saída do INTB do MCP23017 pra ver se piscava e nada. Acho que deve haver alguma configuração pra que esta interrupção ocorra. O ruim está sendo descobrir a configuração correta.

Para que elas funcionem tens de as activar.Tenta assim:

{
  Wire.beginTransmission (mcp_address );
  Wire.send (0x04);
  Wire.send (0xFF);  // port A
  Wire.send (0xFF);  // port B
  Wire.endTransmission ();
}

Funcionou!!! Depois que vi sua solução alterei apenas pra porta que eu queria, que no caso ficou assim:

  Wire.beginTransmission(mcp_address);
  Wire.write((byte) GPINTENB);
  Wire.write(B00100000); 
  Wire.endTransmission();

Agora a interrupção é gerada e eu só percebo que está funcionando a interrupção porque estou usando a primeira solução que você forneceu, através do LED, porque realmente pela serial parece que nada ocorre. Ou seja, antes mesmo de eu vir aqui com outra dúvida você já respondeu antecipadamente, rs.

HugoPT, muito obrigado!!!

Inda bem que funcionou.
O método de polling não é eficaz para detectares interrupções como ja te tinha dito anteriormente.AInda bem que fizeste o teste e viste o problema após saberes a solução.Foram dois tiros com uma só bala :grin: :grin:
Bons estudos