Momentary switch to control a relay for 5 sec.

I am trying to finish a sculpture in which i have a momentary button and i have a relay which runs a large fan. I am trying to make it so when someone pushes the button the fan turns on and stays on for 5 or so seconds. Here is the code i tried and it didn't work at all and i have no idea why.

const int buttonPin = 11; // the number of the pushbutton pin
const int fanRelay = 2;

// variables will change:
int buttonState = 0; // variable for reading the pushbutton status // current state of the switch
int PreviousbuttonState = 0; // previous state of the switch
int fanRelayState = 0;

void setup() {
Serial.begin(9600);
pinMode(fanRelay, OUTPUT);

pinMode(buttonPin, INPUT);
}

void loop(){
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);

fanRelayState = digitalRead(fanRelay);

if (buttonState != PreviousbuttonState) {

// if the state has changed, check change direction
if (buttonState == HIGH){

// if the current state is HIGH then the switch went from off to on
// instigate a relay state change:

if (fanRelayState == LOW)
digitalWrite(fanRelay, HIGH);
else
digitalWrite(fanRelay, LOW);}
Serial.print(buttonState); // print out the value you read:
Serial.print(" ");
Serial.println(fanRelay); //print out of the tone output
}
}

ccc9090:
I am trying to make it so when someone pushes the button the fan turns on and stays on for 5 or so seconds.

The code below should perform the action described by the above quote.

const int buttonPin = 11;     // the number of the pushbutton pin
const int fanRelay =  2;
const boolean ACTIVE_STATE = LOW;

// variables will change:
boolean buttonState;         // variable for reading the pushbutton status

void setup() 
{
  Serial.begin(9600);
  pinMode(fanRelay, OUTPUT);
  pinMode(buttonPin, INPUT);
}

void loop()
{
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  if (buttonState == ACTIVE_STATE)
  {
    digitalWrite(fanRelay, HIGH);
    Serial.println("Fan On");
    delay(5000);
    digitalWrite(fanRelay, LOW);
    Serial.println("Fan Off");
  }
}

The above code assumes the button is active low. If the button is active high change:

const boolean ACTIVE_STATE = LOW;

to

const boolean ACTIVE_STATE = HIGH;

How is the button wired? Do you want to use the internal pull-up resistor? If so you need to set it with "INPUT_PULLUP".

I usually avoid using "delay" but based on your description, I don't see anything wrong with using it in this application.

BTW, See item #7 in the "How to use this forum" post to learn about using code tags.

I think that you have forgotten:
To set PreviousbuttonState after the button has been pressed
To include a 5s delay after the fan has been turned on

You just need to think the cycle of the program through logically;

  • the person presses the button
  • buttonState = 0 and will be set to 1
  • fanRelayState = 0 and will be set to 1
  • ----------------------- the loop begins again without a 5s delay -----------------------------
  • the loop has started again almost instantaneously and the person has not taken their finger off the button
  • buttonState = 1 and is again set to 1
  • buttonState = HIGH
  • relay is on; fanRelayState = 1 still and is toggled to 0
  • ---------------------- the loop begins again ------------------------------------------------

This happens a couple of hundred times until the person takes their finger off, the relay has been toggled on/off a lot.

  • buttonState now = 0
  • PreviousbuttonState also = 0
  • buttonState = PreviousbuttonState and therefore
    [if (buttonState != PreviousbuttonState)] is untrue.
    The program won't enter the if statement and will loop continually through
    [buttonState = digitalRead(buttonPin);
    fanRelayState = digitalRead(fanRelay);] without changing fanRelayState.

@DuaneDegn's code is a more simplistic way of doing it and I think it should work. More simple = less bugs.
Hope this helps...

Thank you so much, that explanation helped a lot and it works perfectly now! Great post!