Due External Interrupts

I have isolated a problem I am having with interrupts on the Due board to the below code:

volatile boolean a = false;
volatile boolean b = false;

void setup() {
    int a_pin = 51;
    int b_pin = 49;
    Serial.begin(9600); 
    Serial.println("0");    
    attachInterrupt(a_pin, a_func, RISING);
    Serial.println("1");    
    attachInterrupt(b_pin, b_func, FALLING);
    Serial.println("2");
}
void loop(){
    Serial.println("3");
    if(b==true){
        Serial.println("b true");
        delay(750);
    }
    Serial.println("4");
    if(a==true){
        Serial.println("a true");
        delay(750);
    }
    Serial.println("5");
}

void a_func(){
    Serial.println("a interrupt");
    a = true;
}

void b_func(){
    Serial.println("b interrupt");
    b = true;
}

The above code is supposed to work in conjunction with the simple circuit here. :


I am confident the button is properly debounced, verified through the oscilloscope.

From the circuit, the normally high output of the voltage divider goes to pin 49 (associated with 'b' boolean and function) on the Due which is set to receive interrupts from FALLING signals (i.e. HIGH to LOW). The capacitor is to filter out any noise. The interrupt prints 'b interrupt' and sets 'b' = true, which causes the print statement 'b true' to print repeatedly in the loop().

The problem is that the interrupt is happening before the button is pushed, i.e. pin 49 must see a FALLING signal before I actually do anything. To determine the order of events I added a number of print statements and the output is as seen here:

0
1
b interrupt
2
3
b true
4
5
3
b true
4
5

As you can see, the 'b interrupt' happens between the prints of '1' and '2', setting 'b'=true, causing the 'b true' statement to print. Pushing the button associated with 'b' causes the 'b interrupt' print statement as expected, but I do not understand why the interrupt initially occurs before I physically do anything. I have watched the voltages on pin 49 with an oscilloscope to check if the pin defaults to HIGH and then goes low on program execution (thus triggering the interrupt), but as far as I can see, the pin always reports ~2.5V, unless I push the button, which causes it go to 0V as expected.

I added the interrupts associated with 'a' and simply grounded pin 51. I have no problems with the interrupt happening unexpectedly, as seen in the Serial output by lack of statements related to 'a'.

Is this some kind of weird system thing where the interrupt is called when I attach a function with a FALLING mode or am I getting a falling signal I can't see?

Update: I connected pin 51 to a normally closed debounced button in a similar circuit to the one in the original post. This means the output of the voltage divider is normally LOW and goes to HIGH on button push. Attaching an interrupt on such a RISING logic change does not produce the problems seen in the original post and the interrupt never occurs unless the button is actually pushed. While I realize I could just always use a normally closed button and use RISING interrupt triggers, it would still be nice to know what is causing my original problem.

I haven't got a Due board, so Im guessing.

Is the 2.5V well within the specs for a high ?, maybe try 3V

Are the other pins floating, try tying high or low

Have you tried on another board, ie 8 bit, whats the result ?

Also on the output shown, is that without pressing the button at all ? like never pressing the button

I have no datasheets to link, but the board's maximum input voltage is 3.3V, so 2.5V should sensibly be enough for HIGH. But more than that, I can say with certainty from other projects I have done that 2.5V is enough to trigger HIGH.

The other pins are not connected nor initialized in the setup() function.

I have no other board to try this with.

The output corresponds to the button never being pushed.

On the 8bit Arduino boards I have, the firmware appears to be doing something strange at each startup, so could be tied up with that.
I will try to run your code on another board when I get home tonight.

You properly should not do anything like serial.print inside the ISR.
Just set a flag and print elsewhere.
I think print is buffered or something as the code locks up on a mega when triggering the interrupt.

You're totally correct. The prints inside the interrupt functions are purely for demonstrative purposes for this post to show when the interrupt happens in order of events. My actual code only has the boolean value changes. Regardless, if you take the prints out you can still see that 'b==true' is set by an unexpected interrupt from the 'b true' prints.

I think that capacitor value is too low, and also the parallel resistor could be higher, e.g. 10K. You've got a very short time constant at the moment.

You could also use a software debounce.

How about adding:

volatile int bCount = 0;

at the top, incrementing it in b_func, and printing it each time you print "b true"? Might give some insight about the interrupts.

Jim

Might be worth to try it with a SR Latch on the input.
This way it would eliminate any input issues

In your setup routine, add the "pinMode(pin_a, INPUT);" statement. You need one for pin_b also. See if that works.