FlyingEaglE
28.02.2015, 01:48
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:
#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
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:
#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