It is possible. You could use a setjmp()/longjmp() combination, or you could just manipulate the stack in assembly right before returning from the interrupt. This however, makes the program very difficult to reason about, which can easily lead to introducing very hard to find bugs. It is certainly not a good solution for your specific problem.
The straightforward solution to your actual problem is to make your loop non blocking, and this is achieved with the technique explained in the Blink without delay Arduino tutorial. Your case is a little bit more complex, as your LED can be in three modes. I suggest you consider instead that it can actually be in four modes by saying that, while it's blinking, the ON and OFF states are different modes:
static enum { OFF, BLINK_OFF, BLINK_ON, ON } mode;
I would let the interrupt handler take care of the button-controlled mode switching:
void switchMode()
{
// Debounce.
static uint32_t last_interrupt_time;
uint32_t interrupt_time = millis();
if (interrupt_time - last_interrupt_time < DEBOUNCE_TIME)
return;
last_interrupt_time = interrupt_time;
// Switch modes.
switch (mode) {
case OFF: // OFF -> blink
digitalWrite(LED_PIN, HIGH);
mode = BLINK_ON;
break;
case BLINK_OFF: // blink -> ON
case BLINK_ON: // ditto
digitalWrite(LED_PIN, HIGH);
mode = ON;
break;
case ON: // ON -> OFF
mode = OFF;
break;
}
}
And the loop()
only has to deal with the blinking:
void loop()
{
// This only has to handle the timing of the blinking.
uint32_t now = millis();
static uint32_t last_toggle_time;
switch (mode) {
case BLINK_OFF:
if (now - last_toggle_time > TIME_OFF) {
digitalWrite(LED_PIN, HIGH);
mode = BLINK_ON;
last_toggle_time = now;
}
break;
case BLINK_ON:
if (now - last_toggle_time > TIME_ON) {
digitalWrite(LED_PIN, LOW);
mode = BLINK_OFF;
last_toggle_time = now;
}
break;
default:
// Nothing to do in the other modes.
break;
}
}
Another option is to have the interrupt handler only set a flag to
signal the button press. Then loop()
would take care off all mode
changes. This can be a good option if you want the "state machine" (the
control of the mode
) contained in a single function.