Fehler im Code oder Hardware
Hallo,
ich hatte die Tage schon mal wegen Interruptproblemen beim MCP23017 gefragt, aber keine antworten erhalten, daher habe ich mich nochmal hingesetzt und den code auf das m.e. wesentliche reduziert:
Code:
#include <Wire.h>
#define Mcp_Reg_IODIRA 0x00 // IO direction (0 = output, 1 = input (Default))
#define Mcp_Reg_IODIRB 0x01
#define Mcp_Reg_IOPOLA 0x02 // IO polarity (0 = normal, 1 = inverse)
#define Mcp_Reg_IOPOLB 0x03
#define Mcp_Reg_GPINTENA 0x04 // Interrupt on change (0 = disable, 1 = enable)
#define Mcp_Reg_GPINTENB 0x05
#define Mcp_Reg_DEFVALA 0x06 // Default comparison for interrupt on change (interrupts on opposite)
#define Mcp_Reg_DEFVALB 0x07
#define Mcp_Reg_INTCONA 0x08 // Interrupt control (0 = interrupt on change from previous, 1 = interrupt on change from DEFVAL)
#define Mcp_Reg_INTCONB 0x09
#define Mcp_Reg_IOCON 0x0A // IO Configuration: bank/mirror/seqop/disslw/haen/odr/intpol/notimp
//#define Mcp_Reg_IOCON 0x0B // same as 0x0A
#define Mcp_Reg_GPPUA 0x0C // Pull-up resistor (0 = disabled, 1 = enabled)
#define Mcp_Reg_GPPUB 0x0D
#define Mcp_Reg_INFTFA 0x0E // Interrupt flag (read only) : (0 = no interrupt, 1 = pin caused interrupt)
#define Mcp_Reg_INFTFB 0x0F
#define Mcp_Reg_INTCAPA 0x10 // Interrupt capture (read only) : value of GPIO at time of last interrupt
#define Mcp_Reg_INTCAPB 0x11
#define Mcp_Reg_GPIOA 0x12 // Port value. Write to change, read to obtain value
#define Mcp_Reg_GPIOB 0x13
#define Mcp_Reg_OLLATA 0x14 // Output latch. Write to latch output.
#define Mcp_Reg_OLLATB 0x15
#define mcp 0x21
#define MCPResetPin 4 // hier hängt der MCP mit seinem Reset-Pin dran
#define MCPInterruptA 0 // hier hängt der MCP mit seinem Interrupt-Pin 19 dran
#define MCPInterruptB 1 // hier hängt der MCP mit seinem Interrupt-Pin 19 dran
#define LEDOnBoard 13 // pin 13, LED aufm Arduino-Board
byte WireTransmitResult = 0;
boolean SwitchPressed = false;
boolean isInInit = false;
byte inputStateA = 0;
byte inputStateB = 0;
void setup()
{
Serial.begin(9600);
Serial.println("Start");
Wire.begin();
initiic();
pinMode (LEDOnBoard, OUTPUT);
digitalWrite (LEDOnBoard, LOW);
attachInterrupt(MCPInterruptA, ISRSwitchPressed, FALLING);
// attachInterrupt(MCPInterruptB, ISRSwitchPressed, FALLING);
Serial.println("Bereit");
}
void loop()
{
if (SwitchPressed)
{
inputStateA = readiicbyte(mcp, Mcp_Reg_INTCAPA);
inputStateB = readiicbyte(mcp, Mcp_Reg_INTCAPB);
Serial.print("LOOP inputStateA: ");
Serial.println(inputStateA, BIN);
Serial.print("LOOP inputStateB: ");
Serial.println(inputStateB, BIN);
digitalWrite (LEDOnBoard, LOW);
SwitchPressed = false;
}
}
void ISRSwitchPressed ()
{
Serial.println("ISRSwitchPressed");
digitalWrite (LEDOnBoard, HIGH);
inputStateA = readiicbyte(mcp, Mcp_Reg_INTCAPA);
inputStateB = readiicbyte(mcp, Mcp_Reg_INTCAPB);
Serial.print("ISR inputStateA: ");
Serial.println(inputStateA, BIN);
Serial.print("ISR inputStateB: ");
Serial.println(inputStateB, BIN);
if (SwitchPressed || isInInit)
{
/*
Serial.println(inputState, BIN);
Serial.print("ISR SP: ");
Serial.println((String)isInInit);
Serial.print("ISR iI: ");
Serial.println((String)SwitchPressed);
Serial.println("ISR returned");
*/
digitalWrite (LEDOnBoard, LOW);
}
else
{
SwitchPressed = true;
}
}
void writeiic(uint8_t adr, uint8_t port, byte value)
{
Wire.beginTransmission( adr );
Wire.write( port );
Wire.write( value );
WireTransmitResult = Wire.endTransmission();
// String t = "writeiic: ";
// t += " Adr: " + String(adr) + " Port: " + String(port) + " Value: " + String(value);
// Serial.println(t);
}
byte readiicbyte(uint8_t adr, uint8_t port)
{
Serial.println("IIC Lesen");
byte returnword = 0x00;
Wire.beginTransmission(adr);
Wire.write(port);
Wire.endTransmission();
Wire.requestFrom((int)adr, 1);
int c = 0;
if (Wire.available())
{
returnword = Wire.read();
}
return returnword;
}
void initiic()
{
Serial.println("Init Wire");
isInInit = true;
SwitchPressed = false;
pinMode(MCPResetPin, OUTPUT);
digitalWrite(MCPResetPin, LOW);
delay(5);
digitalWrite(MCPResetPin, HIGH);
writeiic(mcp, Mcp_Reg_IODIRA, 0x00); // Alles auf Output setzen
writeiic(mcp, Mcp_Reg_GPIOA, 0x00); // Alle Pins auf 0 setzen
writeiic(mcp, Mcp_Reg_IODIRB, 0x00); // Alles auf Output setzen
writeiic(mcp, Mcp_Reg_GPIOB, 0x00); // alle Pins auf 0 setzen
byte inputMaskA = 0xFF;
byte inputMaskB = 0xFF;
byte polA = 0xFF;
byte polB = 0xFF;
writeiic(mcp, Mcp_Reg_IODIRA, inputMaskA); // Richtung (Ein-/Ausgang) einstellen
writeiic(mcp, Mcp_Reg_IODIRB, inputMaskB); // Richtung (Ein-/Ausgang) einstellen
writeiic(mcp, Mcp_Reg_GPPUA, inputMaskA); // Pull-Up Widerstände einrichten
writeiic(mcp, Mcp_Reg_GPPUB, inputMaskB); // Pull-Up Widerstände einrichten
writeiic(mcp, Mcp_Reg_IOPOLA, polA); // Polarität einstellen (für Eingänge 0 oder 1)
writeiic(mcp, Mcp_Reg_IOPOLB, polB); // Polarität einstellen (für Eingänge 0 oder 1)
writeiic(mcp, Mcp_Reg_GPINTENA, inputMaskA); // Interrupt aktivieren
writeiic(mcp, Mcp_Reg_GPINTENB, inputMaskB); // Interrupt aktivieren
writeiic(mcp, Mcp_Reg_DEFVALA, inputMaskA); // Interrupt Default-Wert festlegen
writeiic(mcp, Mcp_Reg_DEFVALB, inputMaskB); // Interrupt Default-Wert festlegen
writeiic(mcp, Mcp_Reg_INTCONA, inputMaskA); // Interrupt Vergleich einstellen, 0 = Änderung zum Vorgänger, 1 = Änderung zum DEFVAL-Wert
writeiic(mcp, Mcp_Reg_INTCONB, inputMaskB); // Interrupt Vergleich einstellen, 0 = Änderung zum Vorgänger, 1 = Änderung zum DEFVAL-Wert
readiicbyte(mcp, Mcp_Reg_INTCAPA); // Interrupts lesen und dadurch löschen
readiicbyte(mcp, Mcp_Reg_INTCAPB); // Interrupts lesen und dadurch löschen
Serial.println("Init Fertig");
isInInit = false;
}
Leider tuts das nicht, alle Serial-angaben sind nur zu debugzwecken drin!
Schon beim Start gehts los, es kommt gerade noch das "I" von "Init fertig" und dann passiert nix mehr.
Lasse ich die Zeile: attachInterrupt(MCPInterruptA, ISRSwitchPressed, FALLING); weg startet er wie gewünscht, klar logisch, ISR ist dann nicht mehr.
schaltung ist nicht spannend, spannungsversorgung an den mcp, adress-pins (die stimmen), reset und interrupts an die im code beschriebenen pins.
gedanke ist (später) beliebigen port als input/output schalten, interrupts auf a und/oder b legen, dass ich nur einen abfragen muss.
pull-ups aktiviert bei input. hier im test hängt nix weiter dran, daher alle pins auf input und pull-up.
plattform: arduino uno r3
das ist mittlerweile der 4 mcp den ich teste, alle anderen gehen aber noch!
jemand ne idee?
danke & grüße