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).
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
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.
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).
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?
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;
}