There are many ways to handle this issue.
Here's one off the wall. It uses the setjmp/longjmp mechanism to switch by pushbutton on an interrupt, between as many loop() -like functions as you have room for. Try it out, the demo switches between three loop-like functions.
// 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);
}
There is only the need to get off the button in less than 500 milliseconds, otherwise you'll skip ahead in the cycle of loops.
It's a bit delicate, so don't get too creative with the mechanism.
Close readers will wonder about this
void loop()
{
for (; ; ) {
captivated loop with a infinite loop... read here:
a7