Introduction: Home Ventilation Fan Controller Using an Arduino UNO, and Bi-Stable Relay

In a house where there is forced ventilation (by electric fan) from areas like bathrooms and kitchens, there is always a compromise to be made regarding ventilation rate Vs thermal impact.

I discovered this issue when I installed a ventilation fan to ventilate ; kitchen, bathroom, and a room susceptible to damp, in my house. I installed the fan and ducting, switched it on, and awoke the next morning to a well ventilated, but noticeably colder house (it was winter !!). I must make it clear that this fan is simply extracting air from the house (and dumping it outside), which in effect is sucking in replacement air from outside, into the house. It is possible to buy ventilation fan systems that use a heat exchanger to recover heat from air being sucked out from the house. That is probably the most efficient solution. However, such fan systems are expensive and more complicated to install. Simple extraction fans are cheap and relatively easy to install. I installed a cheap fan. I like cheap and simple !

Some simple fan systems use a humidity sensing device to reduce airflow rate when humidity inside the house is low. This could be a partial answer to my problem. However, since I was so desperate to find a use for an Arduino UNO board I had, I decided to develop my own solution.

Simply put, I wanted a control system to maximise ventilation, but not so much as to excessively cool the house in winter (by drawing in too much cold air), or heat the house in summer (by drawing in too much hot air). Fan control will be done by switching the fan ON and OFF using a relay.

This is also a great opportunity to use a bi-stable relay. didn't you always want to play with one of those ?

Step 1: Hardware and Electrical Circuit

The control is done by a loop running on an Arduino UNO clone board. The board has 2 temperature sensors inputting realtime temperature information into the control logic. 1 temp sensor is placed in one of the fan extraction ducts, and is therefore reading "house temperature" (HT). The other sensor is outside the house, and reads "outside temperature" (OT).

The arduino drives a relay to control the fan. Since the relay may be in either state for long periods (days or weeks at a time) I decided to use a bi-stable relay. This gives the advantage that the relay does not have to be continuously energised to maintain either position. I figured that this will mean the relay will have a longer working life than if a "normal" relay was used.

It was not easy to check that the logic being used was actually doing what I wanted, so I added a 2 line LCD display so that I could look at the controller and know what it was doing and why !

List of Components

  1. Arduino UNO : Mounted in the control box so that the cell phone power supply USB plug can pass through a hole and attach to the board. This is the power supply for the whole control system.
  2. Cell Phone Charger : 1 amp charger with USB plug used to power the control box.
  3. Relay Board : 5v, bi-stable relay board. Relay contacts need to be rated for your fan. Typically 50w.
  4. LCD Display : Type 1602, 2 line, 16 chr backlit display
  5. Temperature Sensors : DHT11: You need two of these.

LCD Display

This is used to display the house and outside temperatures on line 1. On line 2 is the fan status, and decision made for the current cycle, eg. FAN OFF for 30 minutes, or FAN ON for 10 minutes. This is really useful to check the logic, and for testing, but could be omitted.

Step 2: Control Logic

The control is done by continuously repeating a 30+1 minute cycle.

There is a constant in the software called "comfort temp" which I use as a target for "ideal" house temperature. I have this set to 24 Deg C, and it can be easily altered to suit your requirements.


In summary, the cycle goes like this. The fan runs for 1 minute. If the outside temperature will help to either cool or heat the house towards the ideal temperature (or maintain it) the fan will remain on for the 30 minute cycle. However, if the outside temperature will significantly cool or heat the house away from the ideal temperature, then the fan will be off for the 30 minute cycle. When the outside temperature will have a smaller effect on deviating house temperature away from it's ideal temperature (because it is not too different from the house temperature) the fan will be on for part of the 30 minute cycle, depending on the temperature difference between outside and house temperature.

In More Detail

The cycle can more precisely be described like this;

  1. Switch ON the fan. Default is that the fan is running.
  2. Wait 1 minute. This is the default background ventilation that will always happen, regardless of any temperature.
  3. Read both temperature sensors.
  4. If HT<IT AND OT<(HT-5Deg C) THEN ... Turn fan off. Wait 30 minutes, go to 7.
  5. IF HT>IT AND OT>(HT+5Deg C) THEN ... Turn fan off. Wait 30 minutes, go to 7.
  6. When neither 4 or 5 above are true then ;
    1. Fan stays on for INT (OT-IT)*5 mins
    2. Fan off for INT 30-(OI-IT)*5 mins
  7. Repeat.

Step 3: Software

The code is attached.

The following librarys are called;

  1. For DHT11 : dht.h
  2. For LCD : LiquidCrystal.h

Constants are setup for ideal house temperature, and also the "background" fan run time. I set them at 24 Deg C, and 1 minute per 30 minute cycle.

I suspect that I am not using the DHT11 read calls in the most efficient way, but it does work.

Self Test

I think that one of the joys of using something like an Arduino UNO is that you can easily build in a self test function. This project is no exception !!

Before the main control loop starts, I turn the fan off. Wait a few seconds then turn on the fan for 1 minute, then turn it off for a few seconds. This is long enough to check that the fan is actually doing what it is supposed to do, and primarily that the relay is working ok. Since I use a bi-stable relay which keeps its position even when not powered, you can use this self test as a way to override the auto system. How so ?

If you unplug the arduino power just after the self test has switched on the fan, then the fan will stay on continuously. If you unplug the arduino power just after the self test has switched the fan off, then the fan will stay off continuously too. This is like a manual override mode (I was going to incorporate, but couldn't be bothered with).

Step 4: Testing and Development

I have been running this box for 2 years now and it is working as desired.

I still get a thrill when I hear the fan turn on automatically during a summers evening as the outside temperature falls below the house temperature, and the house starts to get a little extra cooling.

LCD Interference

Testing the system on a bench is one thing, testing it in situ is something else. Since the fan is an electrical motor, it is not a purely resistive load, but inductive too, and as a consequence I found that the switching the fan (220vac supply) caused interference on the LCD display. This nearly drove me crazy!!!! I added some delays in the code to only write to the LCD a second or so after the relay operates, to avoid the interference (display corrupted), but it did not help. I then tried different capacitors in multiple places across the 5v supply from the arduino power supply. Finally I found info on the Arduino forum that a "snubber circuit" across the relay contacts was the solution. It was. If you have similar issues check out "snubber circuit" on the Arduino forums. A snubber circuit is just a capacitor in series with a resistor across the switched contacts of the relay.

Future Development

The DHT11 sensors also measure humidity. Therefore, it would be easy to adapt this system to take account of humidity even though it was not my original intention. Maybe I will some day, or maybe you will ?

Another possibility would be to capture the house temperature and outside temperature data and make that available to some kind of central heating control logic perhaps via IoT ? Hmmm.....