c++microcontrollerinterruptpollingatmega

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


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.


Solution

  • 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.