ebmm_luke:
Wäre hier eine Leseverzögerung sinnvoll, Stichwort millis?
Ja, ich denke schon.
ebmm_luke:
Diese Verzögerung ist dann aber je nachdem wieder lästig. Die Anwendung ist zwar nicht zeitkritisch (Pedalboard), aber je nachdem kann das trotzdem störend sein.
Andere Variante wäre eine sofortige Reaktion auf den Interrupt, und dann ein Ignorieren weiterer Interrupts für eine bestimmte Zeit. Finde ich sympathischer...
Für "interrupt-on-change from register value" habe ich leider keine Lösung gefunden, daher verwende ich "interrupt-on-pin change".
Die Verzögerung habe ich durch Lesen von INTFA (ohne Löschen des Interrupts) und Merken des letzten Zustandes von INTCAPA eleminiert. Hier mein Testsketch:
#include <Wire.h>
// MCP23017 registers (everything except direction defaults to 0) Author: Nick Gammon
#define IODIRA 0x00 // IO direction (0 = output, 1 = input (Default))
#define IODIRB 0x01
#define IPOLA 0x02 // IO polarity (0 = normal, 1 = inverse)
#define IPOLB 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 // same as 0x0A
#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
#define MCP_I2C_ADRESSE 0x20
volatile byte state = 0;
void setup() {
Serial.begin(9600);
Serial.println("Anfang");
Wire.begin();
expanderWrite(MCP_I2C_ADRESSE, IODIRA, 0x07); //bank A inputs
expanderWrite(MCP_I2C_ADRESSE, IODIRB, 0x0); //bank B outputs
expanderWrite(MCP_I2C_ADRESSE, IPOLA, 0x0); //alle pins normal gepolt
expanderWrite(MCP_I2C_ADRESSE, GPINTENA, 0x07); //pins on interrupt
expanderWrite(MCP_I2C_ADRESSE, DEFVALA, 0x07); //normal state 1
//expanderWrite(MCP_I2C_ADRESSE, INTCONA, 0x07); //interrupt when pin differenet to DEFVALA
expanderWrite(MCP_I2C_ADRESSE, INTCONA, 0x00); //interrupt when pin differenet against the previous value
expanderWrite(MCP_I2C_ADRESSE, IOCON, 0b00011000); //
expanderWrite(MCP_I2C_ADRESSE, GPPUA, 0x07); //Pull-up resistor (0 = disabled, 1 = enabled)
expanderWrite(MCP_I2C_ADRESSE, GPPUA, 0x07); //Pull-up resistor (0 = disabled, 1 = enabled)
expanderRead(MCP_I2C_ADRESSE, GPIOA); //Clear Interrupt
pinMode(13, OUTPUT);
attachInterrupt(0, hoppla, FALLING); // Interrupt an Pin 2
expanderWrite(MCP_I2C_ADRESSE, GPIOB, 0b00000000); //LED off
delay(1000);
}
void hoppla() {
state = 2;
}
void interruptReceived() {
const byte intervall = 30;
unsigned long aktMillis = millis();
static unsigned long altMillis = aktMillis;
static bool ledStatus = 0;
byte portA;
static byte intcapA = 0xFF;
switch (state) {
case 2:
digitalWrite(13, HIGH);
portA = expanderRead(MCP_I2C_ADRESSE, INTFA); //Interrupt flag (read only) : (0 = no interrupt, 1 = pin caused interrupt)
Serial.print("\tINTFA: ");
Serial.print(portA, BIN);
if (portA & intcapA) {
if (ledStatus) {
expanderWrite(MCP_I2C_ADRESSE, GPIOB, 0b00000000); //LED off
} else {
expanderWrite(MCP_I2C_ADRESSE, GPIOB, 0b00000001); //LED on
}
ledStatus = !ledStatus;
}
state = 1;
altMillis = aktMillis;
break;
case 1:
if (aktMillis - altMillis >= intervall) {
intcapA = expanderRead(MCP_I2C_ADRESSE, INTCAPA); //Interrupt capture (read only) : value of GPIO at time of last interrupt
Serial.print("\tINTCAPA: ");
Serial.println(intcapA, BIN);
digitalWrite(13, LOW);
state = 0;
}
break;
}
}
void loop() {
if (state > 0) {
interruptReceived();
}
}
void expanderWrite (const byte I2Cadr, const byte reg, const byte data )
{
Wire.beginTransmission (I2Cadr);
Wire.write (reg);
Wire.write (data);
Wire.endTransmission ();
} // end of expanderWrite
byte expanderRead (const int I2Cadr, const int reg)
{
Wire.beginTransmission (I2Cadr);
Wire.write (reg);
Wire.endTransmission ();
Wire.requestFrom (I2Cadr, 1);
return Wire.read();
} // end of expanderRead
Was meinst Du dazu?