uint8_t buttonsPressed; // Updated by the ISRs to indicate which buttons are pressed. (Not debounced.)
uint64_t pTime;
// Set the pin that rose.
void ProcessPinRise(uint8_t pin)
{
buttonsPressed |= 1 << pin;
}
void IRAM_ATTR IsrPin2Rise()
{
ProcessPinRise(2);
}
void IRAM_ATTR IsrPin4Rise()
{
ProcessPinRise(4);
}
void IRAM_ATTR IsrPin5Rise()
{
ProcessPinRise(5);
}
struct Button
{
int pin;
void (*isr)(void);
};
const Button Buttons[] =
{
{ 2, IsrPin2Rise },
{ 4, IsrPin4Rise },
{ 5, IsrPin5Rise }
};
void setup()
{
Serial.begin(115200);
for (const auto& Button : Buttons)
{
pinMode(Button.pin, INPUT);
attachInterrupt(digitalPinToInterrupt(Button.pin), Button.isr, RISING);
}
}
void loop()
{
uint64_t tick = millis();
// Make a local copy because the ISRs will update the global variable asynchronously on each press or bounce.
uint8_t localButtonsPressed = buttonsPressed;
if (localButtonsPressed)
{
DiscernButtons(localButtonsPressed);
buttonsPressed &= ~localButtonsPressed;
}
if (tick - pTime >= 1000)
{
pTime = millis();
Serial.println("Tick.");
}
}
void DiscernButtons(uint8_t localButtonsPressed)
{
Serial.print("Pressed: ");
uint8_t button = 0;
while (localButtonsPressed)
{
int pressed = localButtonsPressed & 1;
if (pressed)
{
Serial.print(button);
Serial.print(" ");
}
localButtonsPressed >>= 1;
button++;
}
Serial.println();
}