Arduino Programming – State change

Arduino Programming - State change Tutorial
Watch this video on YouTube.

I explain you how to program a state change functionality. ‘State change detection’ is a method to see when a button is pressed or released. You can use it to fire a different action each press of a button.

For example the “Play/Pause” button on a cd-player behaves like that. The first press is play, the next press is pause, the next play again etc. Depending the state the action is different ( play > pause, pause > play ).

In this tutorial I explain also the basic code structure ( setup, loop ) of Arduino script.

Level: beginner with Arduino. ( Basic knowledge of programming principles like if/else and variables ).

OnOff.ino:

/*
  LED on when you press a button.
  LED off when you release a button.  
  
  created 01-12-2009 by kasperkamperman.com
*/

const int buttonPin = 2;      // the pin that the pushbutton is attached to
const int ledPin    = 13;     // the pin that the LED is attached to

int buttonState     = 0;      // current state of the button

void setup() {
  pinMode(buttonPin, INPUT);  // initialize the button pin as a input
  pinMode(ledPin, OUTPUT);    // initialize the button pin as a output
}

void loop() {
  // read the pushbutton input pin
  buttonState = digitalRead(buttonPin);

  // turns LED on if the buttonState=HIGH or off if the buttonState=LOW
  digitalWrite(ledPin, buttonState);
}

State_change.ino:

/*
  Set a state of a variable when you press a pushbutton ( the 
  button went from off to on ). 
  
  created 01-12-2009 by kasperkamperman.com
  based on example 'State change detection' by Tom Igoe
*/

const int buttonPin  = 2;     // the pin that the pushbutton is attached to
const int ledPin     = 13;    // the pin that the LED is attached to

int buttonState      = 0;     // current state of the button
int lastButtonState  = 0;     // previous state of the button
int ledState         = 0;     // remember current led state

void setup() {
  pinMode(buttonPin, INPUT);  // initialize the button pin as a input
  pinMode(ledPin, OUTPUT);    // initialize the button pin as a output
}

void loop() {
  // read the pushbutton input pin
  buttonState = digitalRead(buttonPin);

  // check if the button is pressed or released
  // by comparing the buttonState to its previous state 
  if (buttonState != lastButtonState) {
    
    // change the state of the led when someone pressed the button
    if (buttonState == 1) { 
      if(ledState==1) ledState=0;
      else            ledState=1;         
    }
    
    // remember the current state of the button
    lastButtonState = buttonState;
  }
  
  // turns LED on if the ledState=1 or off if the ledState=0
  digitalWrite(ledPin, ledState);
  
  // adding a small delay prevents reading the buttonState to fast
  // ( debouncing )
  delay(20);
}

If you like to work with more than two states, do something like below. And use a switch or if statement later to perform some action on a certain stateNum value.

if (buttonState == 1) { 
      stateNum++; 
      if(stateNum>2) stateNum=0;      
}

25 thoughts on “Arduino Programming – State change”

  1. i
    HI
    how would you add more states ( lets say 3 states ) in the code

    thanks

  2. Em, I explained that: If you like to work with more than two states, do something like below. And use a switch or if statement later to perform some action on a certain stateNum value.

  3. Just what I was looking for! I’m interested in toggling between 2 different LEDs based on the button state. Can you help with example code for that?

  4. If I implement this code on my UNO, there seems to be an 8 second window for interaction.
    If I run the code and do nothing, the LED turns on for 8 seconds, then off for 8 seconds, and so on.
    During the first 8 seconds it doesn’t respond to button pushes, in the second 8 seconds it does respond and I can turn the LED on and off as much as I like, then I get another 8 seconds where I can’t do anything. The next 8 seconds it will respond again.
    Any idea why this is the case and how I can fix that?

  5. No idea. Did you put a delay somewhere? In my example there is a small delay of 20 milliseconds to prevent bouncing. Are you running other code? Try to go back to the barebone example of me to test it. Otherwise it might be a hardware, cabling problem…

  6. That’s the first thing I did, went to a new file and only worked with your code, kept having the weird 8 second increment thing. But I somehow seem to have fixed it.

    I changed “pinMode(buttonPin, INPUT);” to “pinMode(buttonPin, INPUT_PULLUP);”.
    Now it works like a charm. I have no idea what caused the weird 8 second thing, or why this change fixed it, to be honest. But it works!
    Thanks :)

  7. Well, there is a step I forgot. Would that cause the weird 8 second pattern I got?

  8. How would you write a code to execute a function when button is pressed and stop it immediately if button is pressed again? My function is a very basic sequence of 4 leds turning on and off.

    void blinker(){

    digitalWrite(ledA, HIGH);
    delay(delayOn);
    digitalWrite(ledB, HIGH);
    delay(delayOn);
    digitalWrite(ledC, HIGH);
    delay(delayOn);
    digitalWrite(ledD, HIGH);
    delay(delayOn);
    digitalWrite(ledA, LOW);
    delay(delayOff);
    digitalWrite(ledB, LOW);
    delay(delayOff);
    digitalWrite(ledC, LOW);
    delay(delayOff);
    digitalWrite(ledD, LOW);
    delay(delayOff);
    }

    I could get it started with your code – stopping is the problem.

  9. First program the blinking without using the delay function. Search for blink without delay. Then use a variable. Start reading a geting started book of Arduino first, so you get an understanding how things work.

  10. hey if I wanted to change this code so it sent a message over the serial port only when the button was pushed down or released

    how would I go about it ?

  11. Hello
    here I try with a button of an encoder to change several draw which one each info.
    support court secondary screen draw, reappui back main screen.
    I will like second support see third screen draw and reappui back main screen.
    could you help me please.
    attached program on / off screen
    in advance thank you email: hohm.michel@free.fr
    if (pushlength 1)
    frame = 0;
    // rebuild the picture after some delay
    delay(100);
    }

  12. Hello..
    When I press the push button, case1 works according to the time in the interval, which I programmed for 5 minutes
    If I want to move to case2, I can’t have until case1 finishes five minutes into it.
    Any help please.

    Here is the code…

    void loop() {

    currentMillis = millis();

    buttonPoll = digitalRead(button);

    if (buttonPoll == LOW){

    buttonState++; //increase state by 1

    if (buttonState>2) buttonState=0;

    }

    switch (buttonState) {

    case 1:

    if(currentMillis – previousMillis >= interval){
    Serial.println(“case 1”);

    option1();
    previousMillis=currentMillis;

    }

    break;

    //————————————

    case 2:

    if(currentMillis – previousMillis >= interval){
    Serial.println(“case 2”);

    option2();
    previousMillis=currentMillis;

    }

    break;

    //————————————–
    default:
    //
    break;

    }
    }

  13. Hi Kasper Kasperman!
    I’ve been trying to use your code to program something like the ignition sequence for the war rig in the movie Mad Max (Idk if you’ve seen it). It’s basically the same concept with the difference that switches are used. If you turn the switches in the right sequence, you get the green light.
    My problem is, that I want the program to read in the “code” only if the switches change states, so if they’re flipped:

    if (BtnState1 != LastBtnState1){ //if switch1 is flipped
    checkEntered1(1); //call checkEntered and pass it a 1

    LastBtnState1 = BtnState1;
    delay(250);
    }

    So the only change I made is for the if statement to look for a change in the state of the switch, and then after following the checkEntered protocol, to change the last state of the switch into the current state.
    For some reason I don’t know, because I’m fairly new to Arduino and programming, it doesn’t work. What am I doing wrong?
    Thank you in advance mate!

  14. Hi and thank you for the tutorial.
    I have a question:
    If I wanted two states could I also have multiple actions within each state?
    example:

    Each state is reading pin D2 from the Nano via an Hall effect sensor.

    I’m not even sure sure this is doable but i’ve been trying hours.
    Any advice will help.
    Many thanks

    if (state == 1){
    digitalWrite(MagnetPin1, HIGH);
    digitalWrite(DialPin3 HIGH);
    digitalWrite(DialPin4 HIGH);
    }
    if (state == 2){

    digitalWrite(MagnetPin1, HIGH);
    digitalWrite(DialPin3 LOW);
    digitalWrite(DialPin4 HIGH);
    }

  15. To add: It won’t compile with multiple statements in one state but it will if I only have one.

  16. Hello, I am trying to make a 2 position 2 pin toggle on/off switch Behave like an ignition switch in a car. So when It is in the on position State it reports HIGH for a 50 mil and back to LOW. Then when it is in the off position it reports HIGH for 50 mil and back to LOW. How would I do this? I am trying to emulate a ignition switch in a race simulator. Any Help would be appreciated!!

  17. Great video and explanation! I am newbie and constantly looking for inspirations and examples like that. Thank you so much

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.