From what I\'ve read, the solution to my problem is to use an interrupt, but if I understand them correctly, I can\'t use a delay in the routine that gets called by the inte
You are correct in most of your assumptions. The proper way to handle this is using an interrupt and it is not a good idea to have delays in your interrupt service routines (ISR). So what you want to do is set a flag in your ISR and check that flag in your main loop.
// Flag needs to be volatile if used in an ISR
volatile int buttonFlag = 0;
void loop()
{
if (buttonFlag == 0)
{
heartbeat(); //make led beat
}
else
{
analogWrite(greenPin, 255); //button stays green once pushed
functionA //has some delays in it
functionB //has some other delays
buttonFlag = 0; //clear flag after executing code
}
}
// Interrupt Service Routine attached to INT0 vector
ISR(EXT_INT0_vect)
{
buttonFlag = digitalRead(buttonPin); //set flag to value of button
}
Since the interrupt will only trigger on a change in the state of the button, you don't need to check for that.
Make sure that your flag variable is global and is declared volatile for use in the ISR. And make sure you are using the correct interrupt vector for use with the pin you are using.
Here is a good tutorial on Arduino interrupts. And here is another good example of what you're trying to do.
You may also want to look into debouncing your switch presses depending on what type of switch you're using. If instead of missing the first press, you're getting too many presses, you will need to implement some type of debouncing.