# Question that probably has a really obvious answer but I'm just too dumb to find it

**URL:** <https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654>\
**Category:** Programming\
**Created:** [July 21, 2021, 9:16pm UTC](https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654 "2021-07-21T21:16:24Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![doodletvm](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/doodletvm/32/653195_2.png) [@doodletvm](https://forum.arduino.cc/u/doodletvm)\
**Post date:** [July 21, 2021, 9:16pm UTC](https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654/1 "2021-07-21T21:16:24Z")

</div>

Hi! So I am a total noob and am just starting out with Arduino and coding in general. I've recently bought a Neopixel LED strip and came to the conclusion that I want to build something with it. I'm thinking a control panel with buttons on it, with each button controlling a different routine that the strip loops through. If I press the first button the LED-s loop through routine nr.1, but as soon as I press another button, the strip should change to the respective routine. I'm thinking to use interrupts in my code but I can't figure out a way to make it so that after the code is done with the interrupt it goes straight to the start of the main loop. Is that even possible? I've watched countless YT videos on the topic, but still no answer.

---

<div class="post-metadata">

**Author:** ![anon94801460](https://avatars.discourse-cdn.com/v4/letter/a/278dde/32.png) [@anon94801460](https://forum.arduino.cc/u/anon94801460)\
**Post date:** [July 21, 2021, 9:19pm UTC](https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654/2 "2021-07-21T21:19:42Z")

</div>

Just about anything is possible.

Start small and go one step at a time. Learn to read buttons, program timed actions without using delay(), etc. Interrupts are for experts, so avoid those until you have all of the other things down cold. Plenty of tutorials on line, and in the Arduino IDE.

---

<div class="post-metadata">

**Author:** ![doodletvm](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/doodletvm/32/653195_2.png) [@doodletvm](https://forum.arduino.cc/u/doodletvm)\
**Post date:** [July 21, 2021, 9:28pm UTC](https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654/3 "2021-07-21T21:28:35Z")

</div>

So, you are saying that I can make my project work without interrupts?

---

<div class="post-metadata">

**Author:** ![LarryD](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/larryd/32/215550_2.png) [@LarryD](https://forum.arduino.cc/u/LarryD)\
**Post date:** [July 21, 2021, 9:30pm UTC](https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654/4 "2021-07-21T21:30:36Z")

</div>

Yes

---

<div class="post-metadata">

**Author:** ![doodletvm](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/doodletvm/32/653195_2.png) [@doodletvm](https://forum.arduino.cc/u/doodletvm)\
**Post date:** [July 21, 2021, 9:31pm UTC](https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654/5 "2021-07-21T21:31:56Z")

</div>

And, could you maybe explain to me how that would work?

---

<div class="post-metadata">

**Author:** ![anon94801460](https://avatars.discourse-cdn.com/v4/letter/a/278dde/32.png) [@anon94801460](https://forum.arduino.cc/u/anon94801460)\
**Post date:** [July 21, 2021, 9:32pm UTC](https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654/6 "2021-07-21T21:32:36Z")

</div>

Get some basics working and well understood, before worrying about such off the wall questions. Don't forget to use code tags when posting and asking about code.

---

<div class="post-metadata">

**Author:** ![LarryD](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/larryd/32/215550_2.png) [@LarryD](https://forum.arduino.cc/u/LarryD)\
**Post date:** [July 21, 2021, 9:34pm UTC](https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654/7 "2021-07-21T21:34:38Z")

</div>

Scan your switches every ≈ 20ms.

When you detect a change in switch state, act on that new switch state.

Example:

```cpp
//TIMER examples

#include <Servo.h>
Servo myservo;

#define enabled true
#define disabled false

#define PUSHED LOW
#define notPUSHED HIGH

const byte heartbeatLED = 13;
const byte startSwitch = 2; //+5V---[50k INPUT_PULLUP]---[switch]---GND
const byte servoPin = 3;

bool servoFlag = disabled;

byte lastStartSwitchStatus;

// **********************************
//timing stuff
unsigned long servoMillis;
unsigned long heartbeatMillis;
unsigned long switchMillis;

// ***************************************************************************
void setup()
{
  pinMode(startSwitch, INPUT_PULLUP);

  pinMode(heartbeatLED, OUTPUT);

  myservo.attach(servoPin);
  myservo.write(0);

} //END of setup()

// ***************************************************************************
void loop()
{
  // *********************** 1/2 second TIMER
  //time to toggle the heartbeatLED ?
  if (millis() - heartbeatMillis >= 500)
  {
    //restart the TIMER
    heartbeatMillis = millis();

    //toggle the LED
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
  }

  // *********************** 20ms TIMER
  //time to check the switches and sensors ?
  if (millis() - switchMillis >= 20)
  {
    //restart the TIMER
    switchMillis = millis();

    checkSwitches();
  }

  // *********************** 2 second TIMER
  //if we are timing, has the 2 seconds servo TIMER expired ?
  if (servoFlag == enabled && millis() - servoMillis >= 2000)
  {
    servoFlag = disabled;

    //move the servo to 0'
    myservo.write(0);

  }

  // *********************************
  //Other non blocking code goes here
  // *********************************

} //END of loop()

// ***************************************************************************
//the following switches and sensors will be tested every 20ms
void checkSwitches()
{
  byte switchStatus;

  // ****************************************
  //start switch
  switchStatus = digitalRead(startSwitch);

  // **********************
  //was there a change in switch state ?
  if (lastStartSwitchStatus != switchStatus)
  {
    //update to the new state
    lastStartSwitchStatus = switchStatus;

    // *************
    if (switchStatus == PUSHED)
    {
      //move the servo to 180'
      myservo.write(180);

      //restart the servo TIMER
      servoMillis = millis();

      //enable the servo TIMER
      servoFlag = enabled;

    }

  } //END of if (lastStartSwitchStatus != switchStatus)

  // ****************************************
  //other switch and sensor code
  // ****************************************

} //END of checkSwitches()

// ***************************************************************************

```

---

<div class="post-metadata">

**Author:** ![drmpf](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/drmpf/32/1126438_2.png) [@drmpf](https://forum.arduino.cc/u/drmpf)\
**Post date:** [July 21, 2021, 11:42pm UTC](https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654/8 "2021-07-21T23:42:59Z")

</div>

[How to write Timers and Delays in Arduino](https://www.forward.com.au/pfod/ArduinoProgramming/TimingDelaysInArduino.html) has a millisDelay class that keeps track of if the timer is running or stopped. That would remove some of the flags and simplify the if statements.  
[Multi-tasking in Arduino](https://www.forward.com.au/pfod/ArduinoProgramming/RealTimeArduino/index.html) covers structuring your code at tasks to use millis timers  
 ![multitaskingDiagramSmall](https://europe1.discourse-cdn.com/arduino/original/4X/0/a/a/0aad99dc4fc6d64301e63252d084a5e3abecca12.jpeg)

---

<div class="post-metadata">

**Author:** ![gfvalvo](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/gfvalvo/32/1013044_2.png) [@gfvalvo](https://forum.arduino.cc/u/gfvalvo)\
**Post date:** [July 22, 2021, 12:21am UTC](https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654/9 "2021-07-22T00:21:57Z")

</div>

> [@anon94801460](#):
>
> Interrupts are for experts

It's really a Catch-22. It takes experience to use interrupts correctly and reliably. But, you don't get to be experienced until you try it, bugger it up, and get burnt a few times.

---

<div class="post-metadata">

**Author:** ![johnwasser](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/johnwasser/32/214270_2.png) [@johnwasser](https://forum.arduino.cc/u/johnwasser)\
**Post date:** [July 22, 2021, 5:55pm UTC](https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654/10 "2021-07-22T17:55:00Z")

</div>

> [@doodletvm](#):
>
> I'm thinking to use interrupts in my code but I can't figure out a way to make it so that after the code is done with the interrupt it goes straight to the start of the main loop. Is that even possible?

I think it is possible (not to say advisable) with 'setjmp/longjmp'. Those functions are supposed to allow you to jump back to a point earlier in the execution of the sketch, such as to the end of `setup()`. However, it doesn't seem to work properly with the Arduino.

I get all sorts of problems jumping back to the end of setup(). Even a short switch closure is causing MANY interrupts and, for some reason, the loop() function is producing bizarre output. maybe someone else can figure out why it isn't working.

```arduino
#include <setjmp.h>

jmp_buf BackToTheBeginning;

const byte InterruptPin = 2;
volatile byte InterruptCount = 0;

void setup()
{
  Serial.begin(115200);
  delay(200);
  Serial.println("Start of setup().");

  pinMode(InterruptPin, INPUT_PULLUP);

  // Return to here after an interrupt
  setjmp(BackToTheBeginning);

  attachInterrupt(digitalPinToInterrupt(InterruptPin), myISR, FALLING);
  Serial.println("End of setup().");
}

void loop()
{
  Serial.println("Start of loop().");

  // Send a number every half a second
  for (int i = 0; i < 10; i++)
  {
    Serial.print(InterruptCount);
    Serial.print(' ');
    Serial.println(i);
    delay(500);
  }

  Serial.println("End of loop().");
}

void myISR()
{
  detachInterrupt(digitalPinToInterrupt(InterruptPin));

  InterruptCount++;

  longjmp(BackToTheBeginning, 1);
}
```

---

<div class="post-metadata">

**Author:** ![doodletvm](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/doodletvm/32/653195_2.png) [@doodletvm](https://forum.arduino.cc/u/doodletvm)\
**Post date:** [July 22, 2021, 9:13pm UTC](https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654/11 "2021-07-22T21:13:38Z")

</div>

This looks very promising, I will look into it. Another thing that came to my mind was to use the goto function, but apparently it doesn't work between different functions. (example below)

```cpp
void loop()
    {
      ....
      REACH:
      ......
    }

    void function()
    {
    goto REACH ;
    }

```

Any idea why that is?

---

<div class="post-metadata">

**Author:** ![doodletvm](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/doodletvm/32/653195_2.png) [@doodletvm](https://forum.arduino.cc/u/doodletvm)\
**Post date:** [July 22, 2021, 10:27pm UTC](https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654/12 "2021-07-22T22:27:53Z")

</div>

This is the code that I have at the moment. It's just to test if my idea works, so it's not the final product.

```cpp
#include <FastLED.h>

#define NUM_LEDS 48
#define DATA_PIN 4
CRGB leds[NUM_LEDS];

volatile int button = 1;

void setup() {
  FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);
  Serial.begin(9600);
  pinMode(2,INPUT);
  pinMode(3,INPUT);
  
  attachInterrupt(0,change1,RISING);
  attachInterrupt(1,change2,RISING);

  
  Serial.println("end setup");
}

void loop() {
  switch(button){
    case 1:
      acc1();
      break;

    case 2:
      acc2();
      break;
  }

}

void change1(){
  button = 1;
  Serial.println("BUTT1");
}

void change2(){
  button = 2;
  Serial.println("BUTT2");
}

void acc1(){
  Serial.println("acc1");
  // Turn the LED on, then pause
  leds[0] = CRGB::Red;
  FastLED.show();
  delay(500);
  // Now turn the LED off, then pause
  leds[0] = CRGB::Black;
  FastLED.show();
  delay(500);
  
}

void acc2(){
  Serial.println("acc2");
  // Move a single white led 
   for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed = whiteLed + 1) {
      // Turn our current led on to white, then show the leds
      leds[whiteLed] = CRGB::White;

      // Show the leds (only one of which is set to white, from above)
      FastLED.show();

      // Wait a little bit
      delay(100);

      // Turn our current led back to black for the next loop around
      leds[whiteLed] = CRGB::Black;
  }
}
```

I am happy to announce that it's working as I want it to, except for one part. When I press another button to change the routine the leds go through, the code waits for the current routine to end and only after that it changes to the next one. I don't know if I explained my problem properly so if you guys have any questions you are more than welcome to ask :)).

---

<div class="post-metadata">

**Author:** ![alto777](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/alto777/32/317385_2.png) [@alto777](https://forum.arduino.cc/u/alto777)\
**Post date:** [July 22, 2021, 10:34pm UTC](https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654/13 "2021-07-22T22:34:57Z")

</div>

@johnwasser leaving the propriety and other arguments about using setjmp/longjmp aside, it is unfair to criticize it until you have employed it correctly.

google or consult your favorite reference, there’s a bit more to it than you’ve coded.

I have tried it on the the Arduino, just because I was surprised to find it available, and had used it elsewhere. It is a mechanism that def has its place.

a7

---

<div class="post-metadata">

**Author:** ![doodletvm](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/doodletvm/32/653195_2.png) [@doodletvm](https://forum.arduino.cc/u/doodletvm)\
**Post date:** [July 22, 2021, 10:45pm UTC](https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654/14 "2021-07-22T22:45:08Z")

</div>

I've also tried to implement it in my code but it kept doing weird stuff.

---

<div class="post-metadata">

**Author:** ![alto777](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/alto777/32/317385_2.png) [@alto777](https://forum.arduino.cc/u/alto777)\
**Post date:** [July 23, 2021, 3:56am UTC](https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654/15 "2021-07-23T03:56:59Z")

</div>

I can make a simple setjmp/longjmp example work fine here.

Arduino UNO and Nano, Mac OSX, IDE 1.8.7 which may make no difference.

I cannot get a more ambitious and complete example, which I hoped to provide as a ~~dis~~ service to y'all to function on either board.

Same behaviour on both: starts off fine, then goes ~~a bit~~ cray-cray. Imma find out if anyone has done anything real with setjmp/longjmp; I allow for the possibility that I have an unrelated error in my code.

I haven't decided it is worth using more sleep over… for now, not in my bag o' Arduino tricks.

a7

---

<div class="post-metadata">

**Author:** ![johnwasser](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/johnwasser/32/214270_2.png) [@johnwasser](https://forum.arduino.cc/u/johnwasser)\
**Post date:** [July 23, 2021, 2:18pm UTC](https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654/16 "2021-07-23T14:18:16Z")

</div>

> [@doodletvm](#):
>
> it doesn't work between different functions.
> 
> Any idea why that is?

Labels are local to the function. You can't reference a label in another function just like you can't reference a local variable in another function.

---

<div class="post-metadata">

**Author:** ![johnwasser](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/johnwasser/32/214270_2.png) [@johnwasser](https://forum.arduino.cc/u/johnwasser)\
**Post date:** [July 23, 2021, 2:34pm UTC](https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654/17 "2021-07-23T14:34:13Z")

</div>

> [@alto777](#):
>
> ... unfair to criticize it until you have employed it correctly.  
> google or consult your favorite reference,

If I have employed it incorrectly, please let me know how to correct my mistake.

[http://www.cplusplus.com/reference/csetjmp/setjmp/](http://www.cplusplus.com/reference/csetjmp/setjmp/)  
[http://www.cplusplus.com/reference/csetjmp/longjmp/](http://www.cplusplus.com/reference/csetjmp/longjmp/)  
I don't see anything in this documentation that indicates that I have not "employed it correctly". I don't need to know if the setjmp() is returning the first time (returns 0) or because of longjmp() (returns non-zero) so I don't check the return value.

---

<div class="post-metadata">

**Author:** ![alto777](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/alto777/32/317385_2.png) [@alto777](https://forum.arduino.cc/u/alto777)\
**Post date:** [July 23, 2021, 3:22pm UTC](https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654/18 "2021-07-23T15:22:17Z")

</div>

@johnwasser well I never argue with success. Since it works for you, I’ll leave it at that.

_Oh, wait, it doesn’t work for you_… 😉

But your unusual, like I never seen it done, use of the mechanism may be part of the trouble. The question is can a single setjmp created object be longjmp’d at multiple times.

As much googling as I am going to do on your account suggests that it is probably OK. But it is trivial to re-execute the setjmp for each single longjmp it is expected to accommodate. Why not cut out even the tiniest probability that you inadvertently raise up the circumstances in which a second (or Nth) longjmp goes bad?

I find more ink on how to _not_ use setjmp/longjmp than on whether it works on the UNO or any of the small Arduino boards. And plenty of admonishments to just not do.

I have used it in on processors from the smallest to the largest, not many times, but it does have a place. It vexes me that I cannot roll up a simple example that works. When

```
  Serial.print(count);

```

where count is a sixteen bit integer prints 7 digit numbers, you know something has gone terribly wrong.

As I said before, if I can make a little more progress I may bother the heavies with the matter. My Arduino logic looks fine, and runs well as a standalone C program, the big difference and I suspect deal breaker is in the interrupt mechanism, which I had to simulate on the desktop version.

Sadly, my idea of fun. 😑

a7

---

<div class="post-metadata">

**Author:** ![johnwasser](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/johnwasser/32/214270_2.png) [@johnwasser](https://forum.arduino.cc/u/johnwasser)\
**Post date:** [July 23, 2021, 3:56pm UTC](https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654/19 "2021-07-23T15:56:20Z")

</div>

> [@alto777](#):
>
> it is trivial to re-execute the setjmp for each single longjmp

Done. I also added more output and more delays but I still get bizarre output from the 'for' loop. It is still printing values above 65535 for a SIGNED int. My guess is that setjmp is not saving enough registers.

```arduino
Start of setup().
Attaching interrupt
setjmp returned 10
Attaching interrupt
Interrupt attached
End of setup().
Start of loop().
1 0
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
End of loop().
Start of loop().
1 0
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
setjmp returned 10
Attaching interrupt
setjmp returned 10
Attaching interrupt
Interrupt attached
End of setup().
3 65537
3 65538
3 65539
3 65540

```

The current sketch:

```arduino
#include <setjmp.h>

jmp_buf BackToTheBeginning;

const byte InterruptPin = 2;
volatile byte InterruptCount = 0;

void setup()
{
  Serial.begin(115200);
  delay(200);
  Serial.println("Start of setup().");

  pinMode(InterruptPin, INPUT_PULLUP);

  // Return to here after an interrupt
  int r;
  while ((r = setjmp(BackToTheBeginning)) != 0)
  {
    Serial.print("setjmp returned ");
    Serial.println(r);
    delay(1000);
  }

  Serial.println("Attaching interrupt");
  delay(1000);
  attachInterrupt(digitalPinToInterrupt(InterruptPin), myISR, FALLING);
  Serial.println("Interrupt attached");
  delay(1000);

  Serial.println("End of setup().");
  delay(1000);
}

void loop()
{
  Serial.println("Start of loop().");
  delay(1000);

  // Send a number every half a second
  for (int i = 0; i < 10; i++)
  {
    Serial.print(InterruptCount);
    Serial.print(' ');
    Serial.println(i);
    delay(500);
  }

  Serial.println("End of loop().");
  delay(1000);
}

void myISR()
{
  detachInterrupt(digitalPinToInterrupt(InterruptPin));

  InterruptCount++;

  longjmp(BackToTheBeginning, 10);
}
```

---

<div class="post-metadata">

**Author:** ![alto777](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/alto777/32/317385_2.png) [@alto777](https://forum.arduino.cc/u/alto777)\
**Post date:** [July 23, 2021, 7:27pm UTC](https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654/20 "2021-07-23T19:27:52Z")

</div>

@johnwasser Nice work. That's an MRE for the big boys.

But setjmp/longjmp work perfectly; the finger is now firmly pointed at the interrupt mechanism messing it up.

_Oops!_ **Spoke too soon.** I do get better, nearly what I expected behaviour when I don't use interrupts, but now have some truly bizarre output, not seen in the "desktop" version, that is inexpressibly beyond inexplicable.

So sry, I was really hoping that investigation of faking the interrupt would demonstrate that your original use of setjmp/longjmp would otherwise be OK.

The interrupt thing points up a problem with the implementation of setjmp/longjmp, which may or may not be quite all that is wrong with it.

Given the general and understandable distaste for use of the "non-local goto", I dunno if it is worth more of anyone's time; I will probably still look for anyone who has successfully done something with it on these little machines…

And figure out why things can get printed out of order, yikes.

a7

[Next page](https://forum.arduino.cc/t/question-that-probably-has-a-really-obvious-answer-but-im-just-too-dumb-to-find-it/887654.md?page=2)
