// https://wokwi.com/projects/373311239978862593
// https://forum.arduino.cc/t/using-an-isr-to-start-over-on-a-nano/1158993
// also see post 30, and the thread that this came from
// https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654/30
/* setjmp example */
# include <setjmp.h>
# define numLoops 3
# define myButton 3
# define theLED LED_BUILTIN
static jmp_buf buf;
int whichLoop = 0;
unsigned char once = 0;
volatile unsigned char ignore = 0;
volatile int ignored = 0;
void myISR()
{
if (ignore) {
ignored++;
return;
}
detachInterrupt(digitalPinToInterrupt(myButton));
ignore = 1;
/* and yank the big lever */
longjmp(buf, 1);
}
void setup() {
Serial.begin(115200);
Serial.println("hello setjmp/longjmp world!\n");
pinMode(myButton, INPUT_PULLUP);
pinMode(theLED, OUTPUT);
}
void loop()
{
for (; ; ) {
while (1) {
if (!setjmp(buf)) {
EIFR |= (1 << digitalPinToInterrupt(myButton)); // clear flag on button interrupt
attachInterrupt(digitalPinToInterrupt(myButton), myISR, FALLING);
// delay(20);
ignore = 0;
break; // normal return, just start looping
}
else { // big lever return, do whatever, then start mostly all over
whichLoop++;
if (whichLoop >= numLoops)
whichLoop = 0;
Serial.println("");
if (ignored) { Serial.print(" ignored "); Serial.print(ignored); }
Serial.print("switching to loop "); Serial.print(whichLoop);
Serial.println("");
delay(500); // very poor man's debounce - get off that switch
}
}
for (; ; )
loopDispatch();
}
}
void loopDispatch() {
switch (whichLoop) {
case 0 :
loop0();
break;
case 1 :
loop1();
break;
case 2 :
loop2();
break;
}
}
void loop0()
{
static unsigned char toggle;
digitalWrite(LED_BUILTIN, ++toggle & 0x1);
delay(333);
}
void loop1()
{
int counter = 0;
for (; ; ) {
Serial.print("loop 1 : ");
Serial.println(counter);
counter++;
delay(33);
}
}
void loop2()
{
static int counter = 0;
Serial.print("loop 2 : ");
Serial.println(counter);
counter++;
delay(33);
}