Why isn't my polling routine working when I poll on interrupt and works when I do on main routine

87 views Asked by At

I have a routine that polls the status of a button connected on the microcontroller ATMega328P (on chip arduino nano but code is written in C++), the routine code is this:

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

bool GPIO::GetPressed()
{
     if (bit_is_clear(*this->GetPortOrPin(), this->wichPin)) 
     {
         this->confidenceReleased = 0;                         
         ++this->confidencePressed;
         if (!this->pressed && confidencePressed > thresholdPressed) 
         {
             this->pressed = true;           
             confidencePressed = 0; 
             return true;
         }
     }
    
     else 
     {
         this->confidencePressed = 0; 
         ++this->confidenceReleased;
        if (this->pressed && confidenceReleased > thresholdReleased)
        {
            this->pressed = false; 
            confidenceReleased = 0; 
        }
    }
    return false;
}

This method returns true if the button is pressed (it's a little bit sophisticated because there is some debouncing stuff going on), and returns false otherwise.

*this->GetPortOrPin() returns the PINX register of interest.

When I use this method inside main it works perfectly.

If I try to poll the button using this same method on an interrupt service routine (triggered by the button itself), this method returns always false.

By interrupt service routine I mean:

ISR (PCINTX_vect) //X can be 1 2 or 3
{
    //i press the button and code makes till this point

    if (somebutton.GetPressed() )
    {
        //never gets inside
    }
}

I tried to disable the interrupts once inside the ISR so maybe if the bouncing effect triggers a lot of interrupts on pin change I get rid of this problem but that didn't work.

1

There are 1 answers

0
Vincenzo Catania On BEST ANSWER

The problem with the code of buttonpressed method is that if you call it in the main recursively the counters will be increased in each call in the polling "fashion": if you call it on a interrupt routine the function will be executed only once and the output will always evaluate to false because the counters cannot reach threshold.