Project showcase
Temperature Controlled Exhaust Fan

Temperature Controlled Exhaust Fan © GPL3+

Control at what temperature a ventilation fan should automatically come on.

  • 21 respects

Components and supplies

About this project

Project Description

This device allows me to configure at what temperature I want to automatically turn on a 230 VAC ventilation fan. It uses a solid state relay so is silent in operation and more durable than using a mechanical relay.

Another notable feature is that, once the temperature is below the threshold at which the fan should turn on, it will wait 60 seconds before turning the fan off. This avoids the fan being turned on and off repeatedly when the temperature fluctuates right at the threshold of when the fan should be turned on.

To illustrate, let's assume we configure the temperature at which the fan should be turned on at 27 degrees Celsius and it is now 26 degrees. When it gets hotter and the temperature turns to 27 degrees, the fan will turn on. As long as the temperature is 27 degrees or higher, the fan will remain on. Once the temperature turns to 26 degrees, the device will start a 60 second countdown timer whilst still keeping the fan on. If during the countdown the temperature fluctuates back to 27 degrees or higher, it will abort the countdown and keep the fan on. On the other hand, if the temperature remains at 26 for the full 60 second countdown, then the fan will be turned off at the end of the countdown.

When the Arduino first starts up it is configured to turn the fan on at 27 degrees Celsius. This can be changed to a higher or lower temperature by pressing Temperature Up/Down push buttons and the change will be reflected in the LCD display.

Note that in place of the 230 VAC ventilation fan another electrical appliance could be controlled, as long as its current consumption is below the maximum that the solid state relay is rated to handle. Note also that the code can easily be changed to control the appliance based on a relative humidity threshold in addition to, or instead of, the temperature.

WARNING: Working with AC power is dangerous so you should know what you are doing. Seek the expert help of a certified electrician if you don't know, or proceed at your own risk!


Some time ago I built a driving simulation capsule/enclosure. It had a 230 VAC ventilation fan in it with a rocker switch in the dashboard to control it. Due to the fact that there was a 230 VAC wire going to the rocker switch on the dashboard alongside USB and video cables, anytime I switched the fan on or off an electrical spike temporarily disconnected the USB devices and also affected the video signal to the screen.

This project solved this issue with the use of a solid state relay which has been placed in the power compartment of the simulator, away from USB and video cables. Now there is no 230 VAC cable going to the dashboard either and instead there is a 12 VDC cable to power the Arduino and a 5 VDC power and trigger line going to the solid state relay, neither of which affect the USB or video signals.

I also thought it would be nice to not have to manually turn the fan on and off while driving, so this and being able to see the temperature and humidity on the LCD display is really nice!

The following video shows how the fan controller has been integrated into the driving simulator and a demo of the features explained above.

Have a great day!


Exhaust Fan ControllerArduino
//  ---------------------------------------------------------------------------------------------------------------------
//  Exhaust Fan Controller
//  Written by Alan De Windt for the Arduino Uno
//  August 2018
//  See the following YouTube video for demonstration:
//  ---------------------------------------------------------------------------------------------------------------------

#include <LiquidCrystal.h>
#include <DHT.h>

#define DHTPIN 4                    // Digital pin for temperature and humidity sensor
#define DHTTYPE DHT22               // Type of sensor - DHT22

DHT dht(DHTPIN, DHTTYPE);           // Initialize temperature and humidity sensor
LiquidCrystal lcd(12, 11, 8, 7, 6, 5);  // Initialize LCD screen

const int tempUpButton = 2;         // Digital pin for temperature up button
boolean lastTempUpButton = LOW;
boolean currentTempUpButton = LOW;

const int tempDownButton = 3;       // Digital pin for temperature down button
boolean lastTempDownButton = LOW;
boolean currentTempDownButton = LOW;

unsigned long currentTime = 0;
unsigned long lastFanCheckTime = 0;

volatile int fanOnTemp = 27;        // Initial temp which fan should turn on
int fanStatus = 0;                  // Initial fan status set to off
int remainingSeconds = 60;          // Count down timer set to 60 seconds
const int fanControl = 9;           // Digital pin for solid state relay for fan

int tempInt = 0;
int humInt = 0;
boolean timeToCheck = HIGH;

// The setup function runs once when you press reset or power the board
void setup() {
  pinMode(fanControl, OUTPUT);      // Set fan control digital pin as an output pin
  pinMode(tempUpButton, INPUT);     // Set temperature up digital pin as an input pin
  pinMode(tempDownButton, INPUT);   // Set temperature down digital pin as an input pin
  // Turn fan off initially (which should be the case already but just to make sure)
  digitalWrite(fanControl, LOW);  

  // Initialize LCD screen
  lcd.begin(20, 4);
  // Position cursor and print labels
  lcd.setCursor(0, 0);
  lcd.print("  Fan: OFF");

  lcd.setCursor(0, 1);
  lcd.print(" Temp: ");
  lcd.print(" c");

  lcd.setCursor(0, 2);
  lcd.print("On at: ");
  lcd.print(" c");
  lcd.setCursor(0, 3);
  lcd.print("Humid: ");
  lcd.print(" %");

// The loop function runs over and over again forever
void loop() {

  // Get current millis
  currentTime = millis();

  // Check status of fan every second 
  if (currentTime >= (lastFanCheckTime + 1000)) {

    // If current temperature is temp at which fan should be turned on or a higher temp...
    if (tempInt >= fanOnTemp) {
      // If fan is currently off then turn it on
      if (fanStatus == 0) {
        fanStatus = 1;
        digitalWrite(fanControl, HIGH);  
      // Reset count down timer to 60 seconds
      remainingSeconds = 60;
      // Update display to indicate that fan is on
      lcd.setCursor(7, 0);
      lcd.print("ON           ");
    // Else current temp is below fan triggering temp...
    else {
      // If fan is currently on...
      if (fanStatus == 1) {
        // If count down timer has not run down to zero...
        if (remainingSeconds > 0) {
          // Show remaining count down seconds in display
          lcd.setCursor(7, 0);
          lcd.print("Off in ");
          lcd.print(" ");
          // Decrement countdown timer by one second
          remainingSeconds = remainingSeconds - 1;
        // Else count down timer has reached zero...
        else {
          // Turn the fan off
          fanStatus = 0;
          digitalWrite(fanControl, LOW);  
          // Update display to show that fan is now off
          lcd.setCursor(7, 0);
          lcd.print("OFF          ");
    lastFanCheckTime = currentTime;
    timeToCheck = HIGH;

  // Read temperature sensor every 250 milliseconds after fan status has been checked
  // This avoids countdown timer not being updated right on the second since reading sensor takes about
  // 250 milliseconds and can therefore delay refresh of remaining seconds on LCD screen
  if ((currentTime >= (lastFanCheckTime + 250)) && timeToCheck == HIGH) {
    // Reading temperature or humidity takes about 250 milliseconds!
    // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
    float h = dht.readHumidity();
    // Read temperature as Celsius (the default)
    float t = dht.readTemperature();
    // Check if any reads failed and proceed only if none failed
    if (!isnan(h) && !isnan(t)) {

      humInt = h;
      tempInt = t;
      // Show current temperature and humidity on LCD screen
      lcd.setCursor(7, 1);
      lcd.print(" c");
      lcd.setCursor(7, 3);
      lcd.print(" %");
    timeToCheck = LOW;    

  // Read button to increase temperature at which fan should turn on
  currentTempUpButton = debounce(lastTempUpButton, tempUpButton);
  if (lastTempUpButton == LOW && currentTempUpButton == HIGH) {

    // If temp to turn on fan is less than 35 degrees...
    if (fanOnTemp < 35) {
      // Increase temp to turn fan on by one degree
      fanOnTemp = fanOnTemp + 1;
      // Update display to show new Fan On temp
      lcd.setCursor(7, 2);
      lcd.print(" c");
  lastTempUpButton = currentTempUpButton;

  // Read button to decrease temperature at which fan should turn on
  currentTempDownButton = debounce(lastTempDownButton, tempDownButton);
  if (lastTempDownButton == LOW && currentTempDownButton == HIGH) {

    // If temp to turn on fan is greater than 25 degrees...
    if (fanOnTemp > 20) {
      // Decrement fan turn on temp by one degree
      fanOnTemp = fanOnTemp - 1;
      // Update display to show new Fan On temp
      lcd.setCursor(7, 2);
      lcd.print(" c");
  lastTempDownButton = currentTempDownButton;

//A debouncing function that can be used for any button
boolean debounce(boolean last, int pin) {
  boolean current = digitalRead(pin);
  if (last != current) {
    current = digitalRead(pin);
  return current;


Exhaust Fan Controller
Capture h94coycmth


Similar projects you might like

TV remote controlled Light and Fan

Project tutorial by Rishabh

  • 62 respects

Automatic Temperature Based Fan Control (for Media Cabinets)

Project tutorial by Vess Bakalov

  • 24 respects

Health Kit: Humidity and Temperature Control

Project tutorial by Diana Khalipina

  • 42 respects

Arduino Temperature Control

Project tutorial by Team pandhoit

  • 28 respects

Remote and Voice Controlled Smart Fan

Project tutorial by Paul Trebilcox-Ruiz

  • 19 respects

Temperature & Humidity Data Logging

Project tutorial by MatrixOrbital

  • 16 respects
Add projectSign up / Login