Close
0%
0%

Window Fan Controller

This project was created so I do not have to turn my window box fan off at night when it gets too cold.

Similar projects worth following
Use this program to control a widow fan so that it will turn off at a set temperature.

This program is used to control a window fan.  Use the controls to set a temperature that the fan will turn off.  No more freezing at night!

UP and DOWN controls the temperature set point.  SELECT will toggle the fan on and off.

Display shows:

Temperature set point,  Current temperature

On/Off status, Humidity, Feels Like temperature

  • 1 × Arduino UNO
  • 1 × LCD shield
  • 1 × External solid state relay
  • 1 × DHT22 temperature/humidity sensor

  • 1
    Step 1


    // Temperature Controler for window fan
    // Written by mike, public domain

    /*--------------------------------------------------------------------------------------
    Includes
    --------------------------------------------------------------------------------------*/
    #include "DHT.h"
    #include <LiquidCrystal.h> // include LCD library

    /*--------------------------------------------------------------------------------------
    Defines
    --------------------------------------------------------------------------------------*/
    // Pins in use
    #define DHTPIN 2 // D2 is for DHT22
    #define OUTPUTPIN 3 // Relay pin
    #define BUTTON_ADC_PIN A0 // A0 is the button ADC input
    // ADC readings expected for the 5 buttons on the ADC input
    #define RIGHT_10BIT_ADC 0 // right
    #define UP_10BIT_ADC 131 // up
    #define DOWN_10BIT_ADC 305 // down
    #define LEFT_10BIT_ADC 476 // left
    #define SELECT_10BIT_ADC 718 // select
    #define BUTTONHYSTERESIS 20 // hysteresis for valid button sensing window

    //return values for ReadButtons()
    #define BUTTON_NONE 0 //
    #define BUTTON_RIGHT 1 //
    #define BUTTON_UP 2 //
    #define BUTTON_DOWN 3 //
    #define BUTTON_LEFT 4 //
    #define BUTTON_SELECT 5 //
    #define DHTTYPE DHT22 // DHT 22 (AM2302)
    // Define our states
    #define STATE_TITLE 00 // A title screen
    #define STATE_MODE 05 // Waiting for mode selection
    #define STATE_HEATING 10 // Heating Mode
    #define STATE_COOLING 20 // Cooling Mode

    DHT dht(DHTPIN, DHTTYPE);
    LiquidCrystal lcd( 8, 9, 4, 5, 6, 7 ); //Pins for the freetronics 16x2 LCD shield. LCD: ( RS, E, LCD-D4, LCD-D5, LCD-D6, LCD-D7 )


    /*--------------------------------------------------------------------------------------
    Variables
    --------------------------------------------------------------------------------------*/
    float hi = 0;
    float h = 0;
    float t = 0;
    float f = 0;
    byte buttonJustPressed = false; //this will be true after a ReadButtons() call if triggered
    byte buttonJustReleased = false; //this will be true after a ReadButtons() call if triggered
    byte buttonWas = BUTTON_NONE; //used by ReadButtons() for detection of button events
    byte button = BUTTON_NONE; // return no button pressed if the below checks don't write to btn
    byte state, nextstate;
    int Temperature_Set_Point = 71;
    unsigned int buttonVoltage;
    int relayState = LOW;
    int fanState = HIGH;

    void setup() {
    Serial.begin(9600);
    Serial.println("DHTxx test!");
    pinMode(BUTTON_ADC_PIN, INPUT ); // Analogue input for the LCD's buttons
    pinMode(OUTPUTPIN, OUTPUT );
    digitalWrite(OUTPUTPIN, relayState );
    dht.begin();
    lcd.begin( 16, 2 ); // Tell LCD library this is 16x2 display

    // TITLE

    lcd.clear();
    // 1234567890123456
    lcd.print( "THERMOSTAT" );
    lcd.setCursor( 0, 1 );
    // 1234567890123456
    lcd.print( "Version .3" );
    delay (2000);

    lcd.clear();
    }

    void loop() {
    h = dht.readHumidity();
    f = dht.readTemperature(true);
    hi = dht.computeHeatIndex(f, h);

    if (fanState && !relayState && Temperature_Set_Point < f - 1) {
    relayState = HIGH;
    digitalWrite(OUTPUTPIN, relayState);
    }
    if ((!fanState) || (relayState && Temperature_Set_Point >= f)) {
    relayState = LOW;
    digitalWrite(OUTPUTPIN, relayState);
    }

    lcd.setCursor( 0, 0 );
    lcd.print(Temperature_Set_Point);
    lcd.print("F");lcd.setCursor( 10, 0 );
    lcd.print(f);
    lcd.print("F");
    lcd.setCursor( 0, 1 );
    lcd.print(relayState);
    lcd.setCursor( 3, 1 );
    lcd.print(h);
    lcd.setCursor( 10, 1 );
    lcd.print(hi);
    lcd.print("F");

    delay(500); // Delay to stop buttons "jittering" false presses

    button = ReadButtons();

    while (button == BUTTON_UP) {
    Temperature_Set_Point = Temperature_Set_Point + 1;
    lcd.setCursor( 0, 0 );
    lcd.print(Temperature_Set_Point);
    lcd.print("F");
    delay(500); // Delay to stop buttons "jittering" false presses
    button = ReadButtons();
    }
    while (button == BUTTON_DOWN) {
    Temperature_Set_Point = Temperature_Set_Point - 1;
    lcd.setCursor( 0, 0 );
    lcd.print(Temperature_Set_Point);
    lcd.print("F");
    delay(500); // Delay to stop buttons "jittering" false presses
    button = ReadButtons();
    }
    while (fanState && button == BUTTON_SELECT) {
    fanState = LOW;
    delay(500); // Delay to stop buttons "jittering" false presses
    button = ReadButtons();
    }
    while (!fanState && button == BUTTON_SELECT) {
    fanState = HIGH;
    delay(500); // Delay to stop buttons "jittering" false presses
    button = ReadButtons();
    }

    //clear the buttonJustPressed & buttonJustReleased flags; they've already done their job
    if(buttonJustPressed) buttonJustPressed = false;
    if(buttonJustReleased) buttonJustReleased = false;

    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperature: ");
    Serial.print(f);
    Serial.print(" *F\t");
    Serial.print("Heat index: ");
    Serial.print(hi);
    Serial.println(" *F");
    }

    /*--------------------------------------------------------------------------------------
    ReadButtons()
    Detect the button pressed and return the value
    Uses global values buttonWas, buttonJustPressed, buttonJustReleased.
    --------------------------------------------------------------------------------------*/
    byte ReadButtons() {
    unsigned int buttonVoltage;
    byte button = BUTTON_NONE; // return no button pressed if the below checks don't write to btn

    //read the button ADC pin voltage
    buttonVoltage = analogRead( BUTTON_ADC_PIN );
    //sense if the voltage falls within valid voltage windows
    if( buttonVoltage < ( RIGHT_10BIT_ADC + BUTTONHYSTERESIS ) )
    {
    button = BUTTON_RIGHT;
    }
    else if( buttonVoltage >= ( UP_10BIT_ADC - BUTTONHYSTERESIS )
    && buttonVoltage <= ( UP_10BIT_ADC + BUTTONHYSTERESIS ) )
    {
    button = BUTTON_UP;
    }
    else if( buttonVoltage >= ( DOWN_10BIT_ADC - BUTTONHYSTERESIS )
    && buttonVoltage <= ( DOWN_10BIT_ADC + BUTTONHYSTERESIS ) )
    {
    button = BUTTON_DOWN;
    }
    else if( buttonVoltage >= ( LEFT_10BIT_ADC - BUTTONHYSTERESIS )
    && buttonVoltage <= ( LEFT_10BIT_ADC + BUTTONHYSTERESIS ) )
    {
    button = BUTTON_LEFT;
    }
    else if( buttonVoltage >= ( SELECT_10BIT_ADC - BUTTONHYSTERESIS )
    && buttonVoltage <= ( SELECT_10BIT_ADC + BUTTONHYSTERESIS ) )
    {
    button = BUTTON_SELECT;
    }
    //handle button flags for just pressed and just released events
    if( ( buttonWas == BUTTON_NONE ) && ( button != BUTTON_NONE ) )
    {
    //the button was just pressed, set buttonJustPressed, this can optionally be used to trigger a once-off action for a button press event
    //it's the duty of the receiver to clear these flags if it wants to detect a new button change event
    buttonJustPressed = true;
    buttonJustReleased = false;
    }
    if( ( buttonWas != BUTTON_NONE ) && ( button == BUTTON_NONE ) )
    {
    buttonJustPressed = false;
    buttonJustReleased = true;
    }

    //save the latest button value, for change event detection next time round
    buttonWas = button;

    return( button );
    }

View all instructions

Enjoy this project?

Share

Discussions

Does this project spark your interest?

Become a member to follow this project and never miss any updates