6191

Build an Arduino-based ventilation controller that monitors room temperature and humidity and automatically switches a fan when preset limits are exceeded.

A simple Arduino controller can automate room ventilation by monitoring temperature and humidity and switching a fan when conditions exceed preset limits. 

This project uses an Arduino Uno, DHT11 sensor, and relay module. The system was built and tested in a real room, with the switching thresholds and sampling interval adjusted during testing to provide stable operation. 

Project Design 

The goal was to solve four basic problems: 

  •  Measure room temperature and humidity. 
  •  Decide when additional ventilation is needed. 
  •  Switch a ventilation fan safely. 
  •  Avoid unnecessary relay switching. 
A simple rule-based controller was used rather than a more complicated control algorithm.
 
The final system consists of an Arduino Uno as the controller, a DHT11 for temperature and humidity measurement, a 5 V single-channel relay module, and a ventilation fan.
 
Keeping sensing, control, and load switching separate also makes the prototype easier to troubleshoot.

Components

The project requires:
 
  •  Arduino Uno 
  •  DHT11 temperature and humidity sensor module 
  •  5 V single-channel relay module 
  •  Ventilation fan 
  •  Breadboard 
  •  Jumper wires 
  •  External power supply where required by the fan 
  •  USB cable for programming the Arduino 
The original prototype used an AC fan switched through the relay. If you reproduce the project with an AC load, remember that mains voltage requires appropriate insulation, enclosure, wiring, and electrical safety precautions. For initial breadboard testing, using a low-voltage fan is the safer option.

Connecting the DHT11

The DHT11 module requires only three connections:
 
  • VCC → Arduino 5 V
  • GND → Arduino GND
  • DATA → Arduino digital pin 2
The sensor module used in this project already contained the required pull-up resistor, so no additional resistor was necessary.
 
If you are using a bare DHT11 sensor instead of a breakout module, check its datasheet and wiring requirements before connecting it.

Connecting the Relay

Connect the low-voltage control side of the relay module as follows:
 
  • VCC → Arduino 5 V
  • GND → Arduino GND
  • IN → Arduino digital pin 8
The relay used in the prototype was active-low. This means pulling the input LOW energizes the relay, while HIGH keeps it off.

The fan was connected through the relay's Normally Open (NO) contact so that it remains off when the relay is not energized.
 
Before connecting a fan, it is worth testing the relay separately. Different relay modules do not always use the same input logic.

How the Control Logic Works

The Arduino repeatedly performs a simple sequence:
 
  1.  Read temperature and humidity from the DHT11. 
  2.  Compare both readings with preset limits. 
  3.  Turn the fan on if either limit is exceeded. 
  4.  Turn the fan off when the readings are below the limits. 
  5.  Wait before taking the next measurement. 
For this prototype, the final thresholds were set to:
 
  • Temperature: 30 °C
  • Humidity: 70% RH
The fan therefore starts when:
 

Temperature > 30 °C OR Humidity > 70%

Otherwise, it remains off.
 
A three-second delay is used between measurements.
 
This is intentionally simple. The project was intended as practical room automation rather than precision environmental control.

Arduino Code

The following is the code used in the project:
 

#include <DHT.h>

#define DHTPIN 2 #define DHTTYPE DHT11 #define RELAY_PIN 8

float tempThreshold = 30.0; float humidityThreshold = 70.0;

DHT dht(DHTPIN, DHTTYPE);

void setup() { Serial.begin(9600);

pinMode(RELAY_PIN, OUTPUT); digitalWrite(RELAY_PIN, HIGH); // Relay OFF (active-LOW)

dht.begin();

Serial.println("Automatic Ventilation System Started"); }

void loop() { float humidity = dht.readHumidity(); float temperature = dht.readTemperature();

if (isnan(humidity) || isnan(temperature)) { Serial.println("Sensor reading failed"); delay(2000); return; }

Serial.print("Temperature: "); Serial.print(temperature); Serial.print(" °C | Humidity: "); Serial.print(humidity); Serial.println(" %");

if (temperature > tempThreshold || humidity > humidityThreshold) { digitalWrite(RELAY_PIN, LOW); // Fan ON Serial.println("Fan: ON"); } else { digitalWrite(RELAY_PIN, HIGH); // Fan OFF Serial.println("Fan: OFF"); }

Serial.println("----------------------"); delay(3000); }

The program also checks whether the DHT11 returns a valid reading. If either measurement is invalid, that cycle is ignored rather than allowing bad sensor data to control the relay.

Testing the System

After uploading the sketch, open the Arduino IDE Serial Monitor and set it to 9600 baud.
 
You should see temperature and humidity readings followed by the current fan state.
 
For example:
 

Temperature: 27.00 °C | Humidity: 55.00 % Fan: OFF ----------------------

Temperature: 31.00 °C | Humidity: 58.00 % Fan: ON ----------------------

During initial testing, it can be useful to temporarily reduce the temperature threshold so you do not have to wait for the room to reach 30 °C.
 
For example:
 

float tempThreshold = 25.0;

Once you have confirmed that the relay reacts correctly, restore the intended threshold.
 
The same test can be performed for humidity by temporarily changing humidityThreshold.

What Changed During Real-World Testing

The first version worked, but testing revealed several practical details that were not obvious from the circuit alone.
 
  • The DHT11 Responds Slowly
The DHT11 is suitable for basic environmental monitoring, but it is not a fast sensor.
 
Taking readings too frequently simply produced repeated values rather than useful new information. Increasing the interval between readings made the output easier to work with and was more than adequate for room ventilation, where environmental conditions normally change slowly.
 
The final program therefore waits three seconds between normal readings.
 
  • The Threshold Needed Adjustment
The original temperature trigger was lower.
 
During testing, this caused the fan to switch more frequently than necessary. The value was eventually adjusted to 30 °C, which provided more stable behavior for the room where the prototype was tested.
 
Thresholds are therefore not universal values.
 
A bedroom, workshop, laboratory, bathroom, or equipment room may need different limits.
 
  • Short Humidity Changes Can Trigger the Fan
Temporary humidity changes were another issue during testing. Nearby cooking, an opened door, or other short environmental changes could affect the sensor.
 
Using a longer sampling interval and a sensible threshold reduced unnecessary reactions.
 
For a more advanced version, averaging several readings or requiring the threshold to remain exceeded for a certain period would make the controller less sensitive to short spikes.
 
  • Relay Logic Can Be Confusing
Many inexpensive relay boards are active-low.
 
In this project:
 

digitalWrite(RELAY_PIN, LOW);

turns the fan ON, while:
 

digitalWrite(RELAY_PIN, HIGH);

turns it OFF.
 
Verifying this behavior before connecting the load prevents a surprising situation where the fan starts when you expected it to remain off.
 
  • Frequent Switching Should Be Avoided
Mechanical relays have a finite operating life, and repeated switching also produces noticeable clicking.
 
During the prototype tests, reducing unnecessary switching made the system quieter and reduced relay activity.
 
This is another reason not to sample an environmental sensor as if it were a high-speed control input.

What Could Be Improved?

The prototype deliberately uses simple hardware and control logic, but it leaves several obvious paths for development.
 
The DHT11 could be replaced with a DHT22 or another more accurate environmental sensor.

An LCD or OLED display could show temperature, humidity, and fan status without requiring a connected computer.

Replacing the Arduino Uno with an ESP32 would make Wi-Fi monitoring and remote control possible.

Another useful software improvement would be hysteresis, using different thresholds for switching the fan on and off. This would reduce switching when readings remain close to the trigger point.
 
The project could also be expanded beyond temperature and humidity by adding sensors for CO₂ or other indoor-air-quality parameters.

Final Thoughts

This project showed that basic automation does not always need complex control logic.
 
The Arduino simply measures two environmental variables and makes a decision based on predefined thresholds. What made the system work reliably was not adding more code, but testing the prototype and adjusting the sampling interval, thresholds, and relay behavior to match the real environment.
 
It also demonstrates an important limitation of prototype sensors such as the DHT11: they are perfectly useful for basic room monitoring, but they should not be treated as precision or high-speed devices.
 
For a beginner, the project provides a complete introduction to sensor input, decision logic, and relay control. It can then be expanded with better sensors, displays, wireless connectivity, or more sophisticated control logic.

Source and Full Project

This article is a condensed and re-edited version of the original project published on PCBCool.
 
The complete article includes additional background, testing observations, FAQs, and discussion of possible project upgrades.
 
Full project: DIY Automatic Room Ventilation System with Arduino