'Trying to understand why this switch case example works on arduino
Im new to C++, only having done some bash scripting for a few years a while back, and my only other experience was with BASIC some 30 years ago. I started with a (what i thought would be) a simple arduino programme (a user "programmable" LED controller for a PC, triggered by the MB HDD LED, the user can change the animations/colours etc.).
Im not yet at a testing stage, and I'm learning on the fly, trying to understand each thing as I do it, rather than just C+P everything and sticky plaster over the gaps. Im looking into existing libraries, trying to understand how they work, then either using those as a basis for my own code, or using them directly.
So far, I'm good with LED animation control, reading from and using, for input selection, simple button presses, a rotary encoder and a potentiometer, and im nearly there with understanding how to code it all so it appears multitasking (rather than it waiting for long periods to complete code segments before accepting input, or using interrupts). Theres two contact switch buttons id like to use. Ive understood mostly how to watch for button presses and take action, and only act on release, for both short presses and long presses.
Im trying to understand just how this switch case works in the JC_button library example below, as in, how is the state machine's state not destroyed every loop?
https://github.com/JChristensen/JC_Button/blob/master/examples/LongPress/LongPress.ino
void loop()
{
static states_t STATE; // current state machine state
ms = millis(); // record the current time
myBtn.read(); // read the button
switch (STATE)
{
// this state watches for short and long presses, switches the LED for
// short presses, and moves to the TO_BLINK state for long presses.
case ONOFF:
if (myBtn.wasReleased())
switchLED();
else if (myBtn.pressedFor(LONG_PRESS))
STATE = TO_BLINK;
break;
// this is a transition state where we start the fast blink as feedback to the user,
// but we also need to wait for the user to release the button, i.e. end the
// long press, before moving to the BLINK state.
case TO_BLINK:
if (myBtn.wasReleased())
STATE = BLINK;
else
fastBlink();
break;
// the fast-blink state. Watch for another long press which will cause us to
// turn the LED off (as feedback to the user) and move to the TO_ONOFF state.
case BLINK:
if (myBtn.pressedFor(LONG_PRESS))
{
STATE = TO_ONOFF;
digitalWrite(LED_PIN, LOW);
ledState = false;
}
else
fastBlink();
break;
// this is a transition state where we just wait for the user to release the button
// before moving back to the ONOFF state.
case TO_ONOFF:
if (myBtn.wasReleased())
STATE = ONOFF;
break;
}
}
Im trying to understand it so i can try and utilise this for both buttons, without having to duplicate code, however, my understanding is that any variables stored with the main loop will be destroyed when it repeats. So to my mind, once the first case in the switch statement is evalutated true, and acted on, it breaks out of that switch test, and carries on along the main code at the point in entered. Once at the end of the mainloop, it starts again, destroying any set variables within.
So if thats the case, how can the switch test iterate through the enum states {x,z,y}? As the current machine state is stored within the main loop and not globally.
Ive spent a good few hours trying to understand this, but ive not come across many examples of switch being used like this that explains it to me in a way i understand.
Thank you Igor. I had read that, but for somereason the penny only just dropped. I think I was entering a kind of comprehension shutdown when trying to research this before.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
