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; }
i
HI
how would you add more states ( lets say 3 states ) in the code
thanks
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.
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?
just saw the above…sorry
What does the button state change code do ?
Hi, that is impossible .
See the latest code block…
stateNum++;
if(stateNum>2) stateNum=0;
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?
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…
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 :)
But did you use a resistor when you connected a button? With pullup you use the internal resistor of the UNO (which is fine).
Well, there is a step I forgot. Would that cause the weird 8 second pattern I got?
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.
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.
Thanks for reply. Will do :)
Test comment.
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 ?
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: [email protected]
if (pushlength 1)
frame = 0;
// rebuild the picture after some delay
delay(100);
}
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;
}
}
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!
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);
}
To add: It won’t compile with multiple statements in one state but it will if I only have one.
Probably it’s another bug, because multiple actions in an if-statement are always possible.
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!!
Great video and explanation! I am newbie and constantly looking for inspirations and examples like that. Thank you so much
hi
Is it possible to use 5 inputs , detect any one their state change and log them in sd card.
thanks
Yes, that’s possible.