ISR Change - how to use

Status
Not open for further replies.

RicVA

New member
I am trying to use interrupts :)
The board is Teensy 3.2, and I have a button connected to pin 0 and GND (normally open).

I am trying to catch only when the button is pressed and then when released.

#include <avr/io.h>
#include <avr/interrupt.h>​

During setup I have the following

pinMode(0, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(0), IServiceChange, CHANGE);

And the routine is:

void IServiceChange()
{
cli();
Serial.println("IServiceChange");

uint8_t r1 = digitalRead(0);
delay(500);
uint8_t r2 = digitalRead(0);
Serial.print("r1 = "); Serial.print(r1);
Serial.print(", r2 = "); Serial.println(r2);

if (r1 == r2)
{
bool b = (r1 == HIGH ? false : true);

if (b)
{
Serial.println("Button Pressed");
}
else
{
Serial.println("Button up");
Serial.println("");
}
sei();
}
}​

When I push (and hold) the button down I want to get one interrupt (and the routine prints "Button Pressed" at the end)
What I actually get is the following repeating itself until I let go of the button:

IServiceChange
r1 = 0, r2 = 0
Button Pressed
IServiceChange
r1 = 1, r2 = 1
Button up

[repeats same message block]


What is the proper way to code this?
Thanks
Ric
 
The button is 'bouncing' as it closes. Contacts in the switch are making and breaking connections a couple time in quick succession.

I did a WEB search and got a link to this post that may be instructive: Teensy-3-1-GPIO-interrupts

Try FALLING?
 
Thanks - I will look at trying some debounce circuitry. Hard for me to know that it is bouncing as I do not have access to test gear. I thought that the interrupts would stop after a bit but it never does. I also thought that reading the pin twice would help for debounce, but I am guessing that the interrupts are stacking up.

I did try FALLING and RISING, with the same results.
 
Code:
void IServiceChange()
{
    cli(); 
    Serial.println("IServiceChange");

    uint8_t r1 = digitalRead(0);
    delay(500);
    uint8_t r2 = digitalRead(0);
    Serial.print("r1 = "); Serial.print(r1);
    Serial.print(", r2 = "); Serial.println(r2);

    if (r1 == r2)
    {
        bool b = (r1 == HIGH ? false : true);
        if (b)
       {
            Serial.println("Button Pressed");
       }
        else
        {
            Serial.println("Button up");
             Serial.println("");
        }
        sei();
    }
}
There are several things I don't like about this handler. Typically you do not want to do anything time consuming within an interrupt handler. and yours first does cli() which on normal Arduinos disables interrupt and the corresponding sei() only happens if r1==r2.

Then you do a half second delay within the handler. Also Serial prints can hang up if the output queue is full and if interrupts are truly disabled, the Serial (USB) code may not be able to do anything...

Again you did not say what your goal for this is, but if it were me, I would probably do something like:
Code:
bool button_was_pressed = false;
uint32_t time_button_was_last_pressed = 0;
#define DEBOUNCE_TIME 15000
...


void IServiceChange()
{
    uint32_t time_button_pressed = micros();
    if ((time_button_presses - time_button_was_last_pressed) > DEBOUNCE_TIME)
    {
        button_was_pressed = true;
        time_button_was_last_pressed = time_button_pressed;
    }
}


... 

void loop() 
{
    if (button_was_pressed)
    {
        Serial.prinln("Button was pressed");
    }
}
I would also setup the interrupt to be either rising or falling, depending on which transition you are interested in. If you are interested in both, you could have the above routine, save to a variable the digitalRead of the button, when you set pressed equal to true and then use it in loop...
 
thanks for the feedback. I missed that my sei was in the totally wrong spot. I am going to add a hardware solution to the front as part of the solution. and then will test again.

The goal is that there are 3 switches which must be handled immediately, and I need to know when the switches are being held down and, for one, how long it is held down for. The same base logic for detecting the state is being used in all 3 switches.

Thanks again for the feedback
 
Status
Not open for further replies.
Back
Top