Hi everyone,
I'm working on project which involves pressing a button and a fan turns on for 5 seconds before turning. While I was able to turn the fan on by pressing the button, I was unable to turn it off after 5 seconds.
Any help is appreciated.
Here's the code:
int buttonPin = 2;
int relayPin = 3;
int relayState = HIGH;
int buttonState; //record the current button state
int lastButtonState = LOW; // record the last button state
long lastDebounceTime = 0;
long debounceDelay = 50; // eliminate debounce time
void setup() {
pinMode(buttonPin,INPUT);
pinMode(relayPin, OUTPUT);
digitalWrite(relayPin, relayState); // configure the initial state of relay
}
void loop() {
int reading = digitalRead(buttonPin); //read the value of button
//once detects change of state, record time
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
// wait for 50ms to evaluate if it is the same state as last state
// if different, change the button state
// if the state of button is high(pressed), change the state of relay
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
if (buttonState == HIGH) {
relayState = !relayState;
}
}
}
digitalWrite(relayPin, relayState);
//change the last state of button
lastButtonState = reading;
}
Instead of toggling the relayState when a button is pressed, set it to HIGH (assuming the relay is activated with a HIGH signal) and 'start a timer'.
The below code is based on your code; it gives the fleibility to use active HIGH or active LOW relay.
// defines if relay is active when a the pin is set HIGH; change HIGH to LOW if the relay activates with a LOW signal
#define ACTIVE HIGH
int buttonPin = 2;
int relayPin = 3;
int relayState = HIGH;
int buttonState; //record the current button state
int lastButtonState = LOW; // record the last button state
// changed long to unsigned long; millis() based timings should use unsigned variables
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50; // eliminate debounce time
// duration that relay must be on
const unsigned long duration = 5000;
void setup()
{
pinMode(buttonPin, INPUT);
pinMode(relayPin, OUTPUT);
digitalWrite(relayPin, relayState); // configure the initial state of relay
}
void loop()
{
static unsigned long startTime;
if (relayState != ACTIVE)
{
int reading = digitalRead(buttonPin); //read the value of button
//once detects change of state, record time
if (reading != lastButtonState)
{
lastDebounceTime = millis();
}
// wait for 50ms to evaluate if it is the same state as last state
// if different, change the button state
// if the state of button is high(pressed), change the state of relay
if ((millis() - lastDebounceTime) > debounceDelay)
{
if (reading != buttonState)
{
buttonState = reading;
if (buttonState == HIGH)
{
// 'start' a timer
startTime = millis();
// set the relay state to active
relayState = ACTIVE;
}
}
}
//change the last state of button
lastButtonState = reading;
}
else
{
// check if time is over
if (millis() - startTime > duration)
{
// set the relay state back to inactive
relayState = !ACTIVE;
}
}
digitalWrite(relayPin, relayState);
}
I have also fixed a minor issue in your original code regarding long / unsigned long.
Compiles, not tested.
Note:
relayState is also used as a flag to check if the relay is active; if the relay is active, the button is not checked.
There was a slight problem the code as the fan turning off for 5 seconds before turning on but I was able to fixed it by defining active and relayState as low.