Super Beginner - Controlling Sets of code with one Button [Solved]

int switchState = 0; 


void setup()
{
pinMode(2,INPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);


}

void loop()
{
switchState = digitalRead (2);

if(switchState == LOW)
{
  digitalWrite (3,HIGH);
  digitalWrite (4,LOW);
  digitalWrite (5,LOW);
 
}

else
{
  digitalWrite (3,LOW);
  digitalWrite (4,HIGH);
  digitalWrite (5,LOW);
  delay(250);
  digitalWrite(4,LOW);
  digitalWrite (5,HIGH);
  delay(250);
}
}

This is the "Spacecraft Control Panel" from the starter box. I figured out how to push a button and keep the LED on, and then push it again and keeping the LED off. What I am trying to do is put this code into 2 forms, when you push the button the 2 LED will start blinking and then one will turn off. Then if you push the button once more, the 2 LED will stop blinking and then the other one will turn on again. I was thinking maybe a while() loop and then break it, but I am not 100% sure and keep trying different ways. I hope this makes sense, and thanks in advance.

You need to start with the BlinkWithoutDelay example. That way you can loose the delay() calls and the button will react immediately.

Second you should implement a basic finite state machine, where the button switches states.

In case "basic finite state machine" sounds complicated, it's not. It just means that each press of a button causes the value of some variable to change - perhaps from A to B to C to D to A etc. Then a separate part of your code gets the leds to light or blink or whatever depending on the current value of that variable.

...R

majenko:
You need to start with the BlinkWithoutDelay example. That way you can loose the delay() calls and the button will react immediately.

Second you should implement a basic finite state machine, where the button switches states.

i'm trying to figure out the same thing where delay() needs to be replaced with millis() and i realise finite state machines (FSM) are essential to a programmer's basic skills.
i learned some BASIC programming long ago (80s!) so am familiar with IF...THEN & FOR...NEXT structures but am struggling to switch to the abstract paradigm where FSMs come in.
i've tried to watch several YouTube videos on FSMs and i think i understand the gist of it, but haven't seen any simple examples to show how easy sketches could be shown in such FSM diagrams.

here's my attempt at the above situation;

what mistakes am i making and do you have any tips on how i should expand on it; obviously the second circle is going to have further subsets within where millis() becomes the 'changing condition' - sorry about the misused terminology !

Take a look at this recent thread: State Machine - recomendattions / opinions ? - Project Guidance - Arduino Forum

You need to separate the concept of pressing the button from flashing the LED.

The finite state machine controls the flashing of the LED, and the button controls the state of the state machine.

So you have the following:

  1. State machine starts in state 0
  2. Press the button (button CHANGES from LOW to HIGH for example)
    2a. State machine changes to state 1.
  3. Press the button (button CHANGES from LOW to HIGH for example)
    3a. State machine changes to state 0.

Then the state machine says:

  1. If state 0, turn on 3 and off 4&5.
  2. If state 1 and 250ms has elapsed, then toggle the LEDs for this state.

State 1 can be further broken down:

  1. If 250ms has elapsed:
  2. Record the current time to measure the next 250ms
  3. If the LED state is 0 then turn on 4 and off 3&5, set the LED state to 1.
  4. ELSE, turn on 5 and off 3&4, set the LED state to 0.

So you can see you effectively have two small FSMs there - one to control what the LEDs do at a high level, controlled by the button, and another one specific to state 1 which is controlled by millis() to flash the LEDs.

Another way to think of it is with code that follows this pattern

char bState = 'A';

void setup() {
  // whatever needs to go here

}

void loop () {
  checkButton();

  dealWithState();

}

void checkButton() {
  // code to see if the button is pressed and if it is to change bState to its next value
}

void dealWithState() {
  // code to check what is the current value of bState and act accordingly
}

...R

wow, thanks for all the replies, guys - VERY HELPFUL !! :smiley:

wildbill:
Take a look at this recent thread: State Machine - recomendattions / opinions ? - Project Guidance - Arduino Forum

thanks, wildbill - lots of homework for me to do there !!

majenko:
You need to separate the concept of pressing the button from flashing the LED.
...
...

that's a very crucial guiding light - thank you majenko !

Robin2:
Another way to think of it is with code that follows this pattern

char [b]bState [/b]= 'A';

void setup() {
  // whatever needs to go here

}

void loop () {
  checkButton();

dealWithState();

}

void checkButton() {
  // code to see if the button is pressed and if it is to change bState to its next value
}

void dealWithState() {
  // code to check what is the current value of bState and act accordingly
}




...R

thanks, Robin2 - that's closer to my "language" - and 'bState' in this case is what's called a flag, right ?
and your 'pattern' is "polling the flag" ?

will have to step back and properly grasp the FSM though - thanks again all !

Cheers!

My code may be more transparent (that's my intention and my preference) but it is intended to be a proper State Machine. I've just left off the christmas-tree decorations.

...R

Thank you guys very much! After googling and reading your comment, I think this is a state machine? I used Edge Detection. I am a novice C++ programmer, so I understand all of the syntaxes and what not, just getting use to the different functions for Arduino.

So I used Edge Detection, got rid of the Delay and used Milli for LED blink and got my program working pretty well =D.

One thing I know that is bad programming is global variables, but it seems like a lot of things use this for Arduino? Is it because this is just beginner so Globals are not going to be a big issue, or is this actually normal?

const int  buttonPin = 2;    
const int led9 = 9;
const int led12 = 12;
const int led13 = 13;
int ledState = LOW;
int ledState2 = LOW;

void hyperDrive();
int buttonPushCounter = 1;   
int buttonState = 0;         
int lastButtonState = 0;     

long interval = 500;
long prevMillis = 0;
void setup() {

  pinMode(buttonPin, INPUT);

  pinMode(led9, OUTPUT);
  pinMode(led12, OUTPUT);
  pinMode(led13, OUTPUT);
 
}

void loop() {
  
  buttonState = digitalRead(buttonPin);
  

  if (buttonState != lastButtonState)
  {
  if (buttonState == HIGH) 
  {
    buttonPushCounter++;
  } 
  }
  
  lastButtonState = buttonState;
  
  if (buttonPushCounter % 2 == 0)
  
  {
 hyperDrive();
  }
  
  else 
  {
    digitalWrite(led9, HIGH);
    digitalWrite(led12, LOW);
    digitalWrite(led13, LOW);
  }
  
}

void hyperDrive()

{
  digitalWrite(led9, LOW);
 unsigned long currentMillis = millis(); 
  
  
 if(currentMillis - prevMillis > interval) 
 {
    
    prevMillis = currentMillis;   

   
    if (ledState == LOW)
    {
      ledState = HIGH;
      ledState2 = LOW;
    }
    else
    {
      ledState = LOW;
      ledState2 = HIGH;
    }
    
    digitalWrite(led12, ledState);
    digitalWrite(led13, ledState2);
  }
}

In my opinion because the size and nature of Arduino code is very limited compared with a PC it seems perfectly sensible to use global variables if they make the code easier to construct.

The only strong reason I can see for local variables is that because they are temporary the compiler frequently creates them within the CPU registers so they don't take up RAM.

If you are contemplating re-using a piece of code at a later date it may be useful to use a variable naming convention that minimizes the risk of global variable names conflicting with those in your future code.

...R