Following Nick Gammon's guide to Interrupts inside a class under "glue routines". I have tried creating a button class that uses interrupts. The hardware is perfectly debounced by an IC. I am working on an arduino Due.
class myButton {
private:
uint8_t pin = 255;
int timeout = 1;
int longPress = 2000;
bool currentState = 0;
unsigned long timePressed = 0;
unsigned long timeReleased = 0;
static myButton* instances [3];
static void stateChanged0() {
if (myButton::instances[0] != NULL )
myButton::instances[0]->stateChanged();
}
static void stateChanged1() {
if (myButton::instances[1] != NULL )
myButton::instances[1]->stateChanged();
}
static void stateChanged2() {
if (myButton::instances[2] != NULL )
myButton::instances[2]->stateChanged();
}
void attachPin(const uint8_t pin) {
switch (pin) {
case 31:
attachInterrupt (digitalPinToInterrupt(pin), stateChanged0, CHANGE);
instances [0] = this;
break;
case 0:
attachInterrupt (digitalPinToInterrupt(pin), stateChanged1, CHANGE);
instances [1] = this;
break;
case 61:
attachInterrupt (digitalPinToInterrupt(pin), stateChanged2, CHANGE);
instances [2] = this;
break;
}
}
public:
PATHFINDER_BUTTONS(uint8_t pinNum) {
pin = pinNum;
}
void begin() {
pinMode(pin, INPUT);
}
void stateChanged() {
if (digitalRead(pin)) {
timePressed = millis();
currentState = true;
timeReleased = 0;
}
else {
timeReleased = millis();
currentState = false;
}
}
bool isPressed() {
SerialUSB.print(timePressed);
SerialUSB.print('\t');
SerialUSB.print(timeReleased);
SerialUSB.print('\t');
SerialUSB.println(millis());
if ((timePressed > 0 && timeReleased > 0) && (timeReleased - timePressed < longPress) && (millis() - timeReleased > timeout) )
return true;
return false;
}
bool isLongPressed() {
SerialUSB.print(timePressed);
SerialUSB.print('\t');
SerialUSB.print(timeReleased);
SerialUSB.print('\t');
SerialUSB.println(millis());
if (currentState && (millis() - timePressed >= longPress ))
return true;
if ((timePressed >= 0 && timeReleased >= 0) && (timeReleased - timePressed > longPress) && (millis() - timeReleased > timeout) )
return true;
return false;
}
};
myButton* myButton::instances[3] = {NULL};
myButton middle = myButton(0);
void setup() {
SerialUSB.begin(9600);
middle.begin();
}
void loop() {
if (middle.isPressed())
SerialUSB.print("MIDDLE button is PRESSED");
}
It would seem that i cannot detect the button press. I have tried using only digitalRead(0) in the loop and it reads the button press just fine. and i have tested the pin (0) that i am able to indeed interrupt on that pin.
So in the code i added a serial debug that when an interrupts happens it goes into the statechange() function. This will then assign the current millis() to a variable. And i do not seet it storing into any variable. So i conclude that its not going inside the statechanged() function where the interrupt is attached
Am i doing something wrong?