First, I am a beginner at this, and just starting to learn this in a college course. I am using an UNO, a breadboard and some resistors and a pushbutton and an Red, Yellow, and Green LED.
I've created a sketch (which I will paste the code here later this evening) that turns on and off a red, yellow, and green LED sequentially, with a 1 second delay between each LED lighting up. This does this when the button is not pushed (OFF)
I am trying to add the behavior that when the button is pressed (ON), it skips the LED portion and goes to the end of the loop, and starts over. I also want to add when I hold the button down it will remain at the end of the sequence until I let go of the button.
When I press and hold the button currently, it just interrupts the loop leaving whatever LED (R, Y, G) is lit on. When I let it go, it just continues its pattern.
I do not see a difference between
1)
I am trying to add the behavior that when the button is pressed (ON), it skips the LED portion and goes to the end of the loop, and starts over.
2)
I also want to add when I hold the button down it will remain at the end of the sequence until I let go of the button.
So maybe you can word those conditions a little different.
To solve your current problem where a led stays on, how about adding an else and switching all leds off?
if (buttonState == LOW)
{
...
...
}
else
{
// switch all leds off
...
...
}
If you want immediate reaction on the button press, you will need to get rid of delay and use a millis() based timing.
Just on a side note:
Are you using a pull-down resistor to prevent floating inputs?
What I want to happen is when I just push the button or hold it down and let go, it will skip to the end of the loop, in this case to the green light, and then start the sequence over.
You are currently caring about whether the switch IS pressed. What you need to care about is whether or not the switch HAS BECOME pressed. See the state change detection example.
/*
Sequential Red, Yellow, Green, with Push Button interrupt to start loop over controlled LED
*/
const int RLED = 9;
const int YLED = 10;
const int GLED = 11;
const int BUTTON = 2;
int buttonState = 0;
int lastButtonState = 0;
int buttonPressCount = 0;
int numberOfLED = 3;
void setup()
{
pinMode (RLED, OUTPUT); //Set the RLED pin as an output
pinMode (YLED, OUTPUT); //Set the YLED pin as an output
pinMode (GLED, OUTPUT); //Set the GLED pin as an output
pinMode (BUTTON, INPUT); //Set button as input (not required)
}
void loop()
{
buttonState = digitalRead(BUTTON);
if (buttonState != lastButtonState) {
if (buttonState == HIGH) {
buttonPressCount++;
}
// Delay a little bit to avoid bouncing
delay(50);
}
lastButtonState = buttonState;
if (buttonState == LOW) {
if (buttonPressCount % numberOfLED == 0) {
//turn RLED on:
digitalWrite(RLED, HIGH);
}
else
{
digitalWrite(RLED, LOW);
}
if (buttonPressCount % numberOfLED == 1) {
//turn YLED on:
digitalWrite(YLED, HIGH);
}
else
{
digitalWrite(YLED, LOW);
}
if (buttonPressCount % numberOfLED == 2) {
//turn GLED on:
digitalWrite(GLED, HIGH);
}
else
{
digitalWrite(GLED, LOW);
}
buttonPressCount++;
delay(1000);
}
}
PaulS:
You are currently caring about whether the switch IS pressed. What you need to care about is whether or not the switch HAS BECOME pressed. See the state change detection example.
Paul,
I've taken a look at the state change example. I tried to implement a state that will check when the button is pressed. Whatever I am doing doesn't work.
Here's what I am trying to accomplish
"If it is ON (pushed), then skip the LED part and go to the end of loop at a time for one second. The LED display should come on as before. When you keep the button pressed, the display would stop at the end of sequence and will remain so as long as the button is pressed. It would start again when you let go."
Right now, it goes through my loop, and if I press the button it does nothing. If I hold the button it stays on whichever LED is lit, and when I let go of the button it turns off the currently lit LED and turns on the previous one. (like its stepping backward in the loop)
It does not do nothing It increments the counter once; no idea why you do that (you also increment the counter at the end of the loop). But it indeed does not do the led sequence.
It's still not quite clear to me (not your fault probably) what you want to happen.
Button not pressed:
sequence red, yellow, green
1 second delay
Button pressed short:
skip sequence, current led stays on (or not)
delay 1 second
continue sequence (so if red was on, now yellow will go on)
Button pressed long:
skip sequence, what needs to happen with current led?
wait for button to be released
start sequence from red or start sequence from where it was?
You probably need to get rid of delay if you don't want to wait two seconds to detect the long press.
dalaraen:
I want when the button is pushed it goes immediately to the end of the loop.
I want when I hold it to start the loop over
Isn't going to the end of loop() essentially the same as starting loop() again, since the next thing that happens at the end, is to go back to the top?
edit: oh wait, I think it means to just before the last step of the loop, not the end, which would be after the last step and effectively the beginning. Sorry.
dalaraen:
I don't want any LED's to stay on when I push the button at all, and I don't want to explicitly tell the LED's to turn off when I push the button.
Thinking about it, maybe you can consider the use of a number of logic (e.g. NAND) gates; in that case you don't need to switch the leds off, the button can do that via the logic gates.
I've created a sketch (which I will paste the code here later this evening) that turns on and off a red, yellow, and green LED sequentially, with a 1 second delay between each LED lighting up. This does this when the button is not pushed (OFF)
I am trying to add the behavior that when the button is pressed (ON), it skips the LED portion and goes to the end of the loop, and starts over. I also want to add when I hold the button down it will remain at the end of the sequence until I let go of the button
You have a sketch that when powered up, sequentially turns ON and OFF a RED, YELLOW and GREEN LED.
You have a BUTTON, that is normally OFF.
You want the BUTTON, when pushed and held ON, to stop and turn OFF the LEDs.
You want when the button is released the sequence of LEDs to return.
You want it so anytime through the sequence the button activation will work.
Is this all you want to do?
Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
NOT a Fritzy picture.
Hi,
This code should get your LEDs to turn OFF when you press and hold the button ON.
However it does it when a sequential scan ends, not if you push the button someway though the sequence.
/*
Sequential Red, Yellow, Green, LED with Push Button
*/
const int RLED = 9;
const int YLED = 10;
const int GLED = 11;
const int BUTTON = 2;
int buttonState = 0;
void setup()
{
pinMode (RLED, OUTPUT); //Set the RLED pin as an output
pinMode (YLED, OUTPUT); //Set the YLED pin as an output
pinMode (GLED, OUTPUT); //Set the GLED pin as an output
pinMode (BUTTON, INPUT); //Set button as input (not required)
}
void loop()
{
buttonState = digitalRead(BUTTON);
if (buttonState == HIGH)
{
digitalWrite(RLED, LOW);
digitalWrite(YLED, LOW);
digitalWrite(GLED, LOW);
}
else
{
//turn RLED on:
digitalWrite(RLED, HIGH);
delay(1000);
digitalWrite(RLED, LOW);
// turn YLED on:
digitalWrite(YLED, HIGH);
delay(1000);
digitalWrite(YLED, LOW);
//turn GLED on:
digitalWrite(GLED, HIGH);
delay(1000);
digitalWrite(GLED, LOW);
}
}
It compiles but I haven't run it.
You will have to use millis instead of delay to time your intervals to get the button press to respond during a sequence.
Look in the IDE Examples for "Blink without delay"
Tom...