I'm writing a simple program that senses a push button and initiates a countdown sequence and pulses a flash relay. The event sequence looks like this:
Green "Ready" LED is on
Push button is activated, Green LED turns off
Red LED on for 1 sec
Red LED off, Orange LED on for 1 sec
Orange LED off, Yellow LED on for 1 sec
Yellow LED off, Green LED on, pulse Flash relay
Wait for push button to be activated again
My problem is that the sequence will loop itself 2 or more times every push of the button. I'm using a common debounce code I've used in the past with no problems. NOTE my push button has +5 on the NO contact, GND on the NC contact, and the COM contact connected to my BUTTON pin.
int BUTTON = 18; // Pin connected to push button.
int FLASH = 19; // Pin connected to flash relay
int RED = 14; // Countdown LED
int ORANGE = 15; // Countdown LED
int YELLOW = 16; // Countdown LED
int GREEN = 17; // Ready LED
int BUTstate; // Current reading from BUTTON pin
int lastBUTstate = LOW; // Previous reading from BUTTON pin
long lastDebounce = 0; // Last time output was changed
long Delay = 25; // Debounce Time
void setup()
{
pinMode (BUTTON, INPUT);
pinMode (FLASH, OUTPUT);
pinMode (RED, OUTPUT);
pinMode (ORANGE, OUTPUT);
pinMode (YELLOW, OUTPUT);
pinMode (GREEN, OUTPUT);
digitalWrite(GREEN, HIGH);
}
void loop()
{
int reading = digitalRead(BUTTON);
if (reading != lastBUTstate)
{
lastDebounce = millis();
}
if ((millis() - lastDebounce) > Delay)
{
BUTstate = reading;
}
if (BUTstate == HIGH)
{
digitalWrite(GREEN, LOW);
digitalWrite(RED, HIGH);
delay(1000);
digitalWrite(RED, LOW);
digitalWrite(ORANGE, HIGH);
delay(1000);
digitalWrite(ORANGE, LOW);
digitalWrite(YELLOW, HIGH);
delay(1000);
digitalWrite(YELLOW, LOW);
digitalWrite(GREEN, HIGH);
digitalWrite(FLASH, HIGH);
delay(100);
digitalWrite(FLASH,LOW);
}
lastBUTstate = reading;
}
I just can't seem to figure out why it's looping itself. Once the button is released its grounded on and LOW, so why is the loop repeating?
You never reset BUTstate back to LOW once the loop runs. Just addin,
(Just a snippet from your code.)
if (BUTstate == HIGH)
{ BUTstate = LOW; // resets it back to LOW
digitalWrite(GREEN, LOW);
digitalWrite(RED, HIGH);
delay(1000);
digitalWrite(RED, LOW);
digitalWrite(ORANGE, HIGH);
delay(1000);
digitalWrite(ORANGE, LOW);
HazardsMind:
You never reset BUTstate back to LOW once the loop runs. Just addin,
(Just a snippet from your code.)
if (BUTstate == HIGH)
{ BUTstate = LOW; // resets it back to LOW
digitalWrite(GREEN, LOW);
digitalWrite(RED, HIGH);
delay(1000);
digitalWrite(RED, LOW);
digitalWrite(ORANGE, HIGH);
delay(1000);
digitalWrite(ORANGE, LOW);
That's what the lastBUTstate = reading at the end of the code is for. It compares the current state to the last state and if they are different it then compares the time to the delay, and if it's greater it takes it as a reading and not "noise".
Arrch:
You already have delays in the sequence, why complicate it with debounce?
What's wrong with just the if statement for the sequence?
Good point. I guess I am just in the habit of debouncing after the past few programs i've written.
Removed the debounce sequence, works perfectly now.
I guess it's the simple solutions that are so easily overlooked....
aalexa5588:
Good point. I guess I am just in the habit of debouncing after the past few programs i've written.
Removed the debounce sequence, works perfectly now.
I guess it's the simple solutions that are so easily overlooked....
Thanks Arrch
It's good practice, but if was certainly the cause of your trouble in this case because the debounce code is intended to run often. What was happening was that after the display sequence, loop() was called again, It wasn't prepared to say it was LOW quite yet because as far as it was concerned, it just switched to ground.
Arrch:
It's good practice, but if was certainly the cause of your trouble in this case because the debounce code is intended to run often. What was happening was that after the display sequence, loop() was called again, It wasn't prepared to say it was LOW quite yet because as far as it was concerned, it just switched to ground.
Well shucks, that makes a whole lotta sense. Now that i think of it you're right about the debounce intended to be ran often, most of my other programs are always looking and receiving key presses, where as this one is idle for much longer in between key presses.