It is a good way to "jump" betwen different modes?

I want to connect my RGB strip to the arduino and I want it to light in different modes (flashing, rainbow etc).

To do so I'll have a button to change these modes. The question is: it is a good way to do so? I've seen complex programs that used different voids than setup() and loop(), should I use this method too? I'm about to make quite complex program too (changing intensity, rainbow stuff, RGB VU meter reacting to music).

I typed this short program to check if it is the good solution.

const int modeButtonPin = 2;
int mode = 0; 
  
void setup() {
  const int modeButtonPin = 2;
  pinMode(modeButtonPin, INPUT);
  
}

void loop() {

  int buttonState = 0;
  buttonState = digitalRead(modeButtonPin);
  if (buttonState == HIGH)
  {
    mode = mode + 1;
    delay(50);
    }
    else if (mode == 1)
    {
      goto mode_1;
    }

     else if (mode == 2)
    {
      goto mode_2;
    }

     else if (mode == 3)
    {
      goto mode_3;
    }
        else if (mode == 4)
    {
      mode = 1;
    }
  


mode_1:
  //Changing state color dynamically
  if (buttonState == HIGH){
    return;
    }
  
  

mode_2:
  //React to music
  if (buttonState == HIGH){
    return;
    }
  
  

mode_3:
  //RGB rainbow with dynamic changing speed
  if (buttonState == HIGH){
    return;
    }
  
}
  //etc

Each mode contains a lot of code in it (if it changes anything).

No that's terrible.

goto is a ghost from the past, don't use it. It's 2019, we have functions :slight_smile:

Use state change detection to detect when a button becomes pressed.

And the most import thing if you want a responsive button, don't use delay() anywhere!

So instead of goto, which function should I use and how?
Also how to use the state change detection?
I put the delay to not add mode = mode + 1 turn so fast

Your own function :slight_smile: A function is what you called "void" :wink: But void simply means that function doesn't return anything.

For the state change, open the "State change"-example :wink:

If you us state change, you don't need delay() for it to not be fast. Also don't use delay() in your led modes as well.

So instead of goto, which function should I use and how?

if (mode == 2)
  {
    aFunctionOfYourChoice();
  }

As a matter of interest, where did you get the idea of using goto ?

These days you'd normally use switch/case for dispatch:

  switch (mode)
  {
  case 0: mode_0() ; break ;
  case 1: mode_1() ; break ;
  case 2: mode_2() ; break ;
  case 3: mode_3() ; break ;
  ....
  }

Very few pieces of advice should be considered absolute, and there can sometimes be a reason to deviate from what would otherwise be a best practice.

However, I can say this with absolute certainty: NEVER ever ever ever ever use
** **goto** **
. Ever.

The way you are using it here is not likely to cause problems, but that's because you are using it in a very trivial way and is pretty much identical to the switch() statement MarkT posted. However, this code is a disaster waiting to happen and a few edits could easy mix things up so badly that it can be hard to tell which gotos are going where.

So, I have just to make some of new void functions and them call them? For example:

UKHeliBob:

if (mode == 2)

{
    aFunctionOfYourChoice();
  }

and after the void loop add another, like void RGBrainbow() { ... } and it will work.

Yep!

Jiggy-Ninja:
However, I can say this with absolute certainty: NEVER ever ever ever ever use
** **goto** **
. Ever.

Except those who find it useful.

GolamMostafa:
Except those who find it useful are evil.

Fixed it!

Okey thanks guys :smiley: One more thing, why shouldn't I use the goto? It makes a big mess in my program?

It will result in so-called spaghetti code that will eventually be impossible to follow

goto is like burning your bridges. It leaves no trail home.

-jim lee

Meh, goto is very useful in some cases. Linux uses it a lot to clean up resources with error handling. Think of "goto" as a poor-man's exception mechanism.

Example code:

int foo(void)
{
    bool ret = false;

    int a = get_a();
    if (!a) goto out;
    int b = get_b();
    if (!b) goto cleanup_a;
    int c = get_c();
    if (!c) goto cleanup_b;

    // do something with a, b, c
    ret = true;

    cleanup_c(c);
cleanup_b:
    cleanup_b(b);
cleanup_a:
    cleanup_a(a);
out:

    return ret;
}

I challenge anyone to write error-handling code that's simpler and more elegant without using goto (where exceptions are not available).

That’s almost the perfect example of where a switch() case - with fall through- structure would apply !

This is a Flow Chart created in 2006 for coding purpose of an Intel-hex formatted file transfer application between PC and 80x86 Trainer. Here, the programmer had to use a lot of goto statements to arrive at different labels. Did he (the programmer) do evil job? Was it not a challenging job for him to employ while-do structure considering the time constraint of the project?

the programmer had to use a lot of goto statements to arrive at different labels.

I am sure that he/she did not have to do any such thing

christop:
I challenge anyone to write error-handling code that's simpler and more elegant without using goto (where exceptions are not available).

bool foo(void){
  bool ret = false;
  byte errorCode = 0;
  
  do{
    int a = get_a();
    if (!a){
      errorCode = 1;
      break;
    }
    int b = get_b();
    if (!b){
      errorCode = 2
      break;
    }
    int c = get_c();
    if (!c){
      errorCode = 3;
      break;
    }
  }
  while(false);

  switch(errorCode){
    case 0:
      // do something with a, b, c
      ret = true;
      cleanup_c();
    case 2:
      cleanup_a();
    case 3:
      cleanup_b();
  }
  
  return ret;
}

Thanks @septillion...
I didn’t have the patience to fight @GM tonight!