Need to ventilate a room? This article will show you how I made a relay-operated, GPS-timed fan to vent out the moist air in my boat's cabin. It is controlled with a PIC16F628A and has an LCD.

Let The Air Flow

In small rooms where there is little to no ventilation, air tends to stand still. If the air is a little moist, you'll definitely have mold and fungi in certain places.

Mold and fungi are found in nature and are necessary to break down leaves, wood, and other plant debris. Since I've got a whole lot of wood in my boat, I will certainly have mold and fungi there. I cannot prevent them from coming in, but I can take some measures to try to keep the environment inside my boat as hostile for the mold and fungi as possible.



There are at least two ways to deal with this. One way is to wash and clean on a tight schedule. Now, how fun is that? Being the geek that I am, I nerded something up instead: a fan which circulates and vents out the moist air on a fixed, timed basis.


Designing the System

I want the system to do the following:

  • Circulate the air
  • Automatically turn on/off, in a steady interval
  • Run from a car battery
  • Contain a battery charger to charge the battery
  • Contain a display that shows time and other info


To make such a system, I'll need the following parts:

  • A 12v fan
  • A microcontroller
  • A 12v battery, and a 12v battery charger
  • 2 relays, something to track time and screw terminals.
  • Other parts, according to part list below


I want the fan to run for five minutes each hour. That will be hard coded in the software.

The setup will run from a car battery. My fan is rated 12v 4.5A. To ensure that the battery is always top-charged, I'll connect it to a battery charger. To ensure that the battery charger is not overloaded when the fan is running, I'm going to make the system “disconnect” the charger while the fan is running. One relay will operate the fan, and the other relay will operate the battery charger. When the fan is running, the battery is not charged, and when the fan is not running, the battery is charged.

To keep track of time, I'm using a GPS module. In this project, I'll use the Skylab SKM53-series module (PDF). This unit sends several NMEA sentences over UART each second. The datasheet recommend to use a 10K pull-up resistor on both RXD and TXD. This will increase the serial data stability. I did not do that, and I've not noticed any instability. I might be lucky. On the same page in the datasheet it says that suitabe decoupling capasitors should be added. A 10uF electrolytic and a 0.1uF ceramic. When I breadboarded the circuit, I used only a 0.1uF ceramic.


Screenshot from the Skylab datasheet (PDF).


I'm using the "RMC" sentence to get the time. An example of an RMC sentence is the following:




The first numbers after $GPRMC are the time. In this example, the time is 07:57:47. We'll be needing that info.





The next thing we'll need is the prefix that tells us if the GPS module has a valid position fix. In the example above, it's the capital A after the three zeros.





An "A" indicates a valid fix and a "V" indicates an invalid fix. In my software, I check for a valid fix. These letters are case sensitive.

To structure projects, I like to make a block diagram. This way I “visualize” what I want to do.



In the above block diagram, I've split everything down into their own block. This is also helpful if I need to troubleshot the schematic or circuit.



The schematic diagram is based on the block diagram. I've reproduced all the blocks in the block diagram to reflect the components and their connections in the circuit.



In the datasheet for the LM7805 regulator, it's stated that for a standard application you'd only need a 0.33uF on the input pin, and a 0.1uF on the output pin. So why do I use different valued caps and some extra? I'm using them for smoothing the input and the output. It might be a little too much, but I have a very good experience with this regulator configuration. If you don't use any capacitors, the regulator might start to oscillate. The LM7805 regulator is an old linear regulator. Why not use a modern switching regulator? The switching regulators are a lot more efficient than the linear regulators. This is what I had laying around.



































I could have saved up on parts and space, with just using one relay. I want two relays. One of the reasons for using two relays, is that I want to have a little timeframe between the charger is cut, and the fan starts.

I've imported the parts list from BOM.ULP into OpenOffice Calc and removed some of the unnecessary columns:



Not showing in the schematic are my fuses. I have a 12v 8A rated fuse on the fans positive wire, and I have the same on the battery chargers positive wire.




You can download the C-source from the download link at the end of this article. The code is well commented, but I'll do some extra highlights here.

When I make a program, I follow a certain structure. This diagram shows the structure:



The code starts with including the necessary libraries, followed by the configuration bits. It is considered as good programming practice to include the configuration bits in the source code. Then it will be a lot easier to see what you've done and for others to help troubleshoot. Besides, if you pick up on a project after a few months, then you'll see the bits straight away.

When the configuration bits are OK, I move on to the definitions. Here I define the crystal speed I've connected to the circuits. The microcontroller's ports are defined, as well.

The next thing is the variables: All variables are declared here.

Now it's time to prototype the functions. Here I list all functions the program uses. Some programmers consider this a waste of time, but I like it and I keep it. It is actually necessary if you structure the program with the functions after the main program loop.

Next come the functions. Now it's really important to start commenting. I usually have a few lines over each function that tell what the function does in general. I also comment code lines inside the functions.

One example is the function that initializes the UART port in this project:


                    // FUNCTION TO INIT THE UART PORT
void uart_init(void)
TXSTAbits.BRGH = 0; // high baud selection bit, 1=high, 0=low
TXSTAbits.SYNC = 0; // USART mode selection bit, 1=sync mode, 0=async mode
TXSTAbits.TX9 = 0; // 9-bit selection bit, 1=9-bit transmission, 0=8-bit transmission
RCSTAbits.CREN = 1; // Continous receive enable bit, 1=enable continous receive
Calculate the SPBRG with 16MHz crystal
16000000 /9600 = 1666.6666
1666.6666 / 64 = 26.0416
26.0416 - 1= 25.0416
25.041 = 25
SPBRG = 25; // 9600-n-8-1
PIE1bits.RCIE = 1; // USART receive interrupt enable bit, 1=enable
RCSTAbits.SPEN = 1; // Serial port enable bit, 1=serial port enable
TXSTAbits.TXEN = 1; // transmit enable bit, 1=transmit eanble


You'll see the first comment line explaining what the function does. Then all the code lines are commented, so I know what's going on.

When all functions are in place, it's time for the main program. The main program starts with a few statements before it enters a loop that is run forever.


  Download Code  


In this article, I've tried to make the environment in my boat as hostile for mold and fungi as I can with a fan that blows and circulates the air. The fan is connected to a pipe that goes out of the cabin. I've used a GPS module to keep track of the time and I've used two relays to turn the fan on/off. To ensure the battery remains charged, I've used another relay to switch a battery charger on and off.

I leave it to the reader to take this circuit to the next level and display the date.

Why use a GPS module? I could have used the microcontroller as a simple timer. Then I had to make some sort of interface, to set the time. Or I'd be happy with it running without regards to real time. It would run for 5 minutes each whole hour. With the GPS I can programmically set it to run five minutes to each whole hour.






  • catalin_cluj 2017-01-20

    The GPS is about as useful in this case as a diesel engine to power your fan.

  • splud 2017-01-20

    I have some suggestions.

    1. you might introduce a humidity sensor into your project.  Then, if the humidity crosses a threshold, you run the circulation system, and do so until the humidity drops below a threshold.  With a DHT11 or DHT22 sensor, you can add temperature to the mix and calculate dewpoint.  This data could be displayed to your LCD if you were so inclined.

    2. As someone just posted as I went to reply, the GPS is overkill for this application.  Further, if you’re running the whole lot off of battery, that’s another drain you could probably do without.  Your uC should be able to enter low power sleep for designated periods, wake up, check whether it should be driving the fans (whether that is a humidity sensor or ‘x’ of the timed sleep cycled), and go back to sleep as appropriate.  Mold and mildew doesn’t care if there’s a few second shift to the cycle over the course of a week.  If this circulation system were presented as one block of a larger automation system which really had need for a GPS, it could be justified, but the system would be more applicable to a larger audience if it wasn’t designed with a reliance on a single component which likely has a BOM cost higher than anything else in the project.

    3. While relays afford versatility in what type of device you drive, since your fans are driven from DC, you could simply use mosfets instead (which are IMO a better choice here than BJTs).  If a given application necessitates it, the mosfet output could drive a relay (or an optocoupler to triac) instead of directly driving your load.  This has the benefit of reducing the current draw and reducing the potential for mechanical failure (the contacts of the relays themselves can erode over time).  This further reduces your BOM cost, and there’s no “click” noise when it switches on and off.  I do appreciate you’ve got diodes across the relay solenoids.

    4. You’re using a linear regulator and you know you should be using a switchmode.  Let me underscore that you should be using a switchmode - it looks like you ordered some parts anyway, and if everything is stuff you had laying around, then you need to order some switchmode regulators so you have them laying around for future projects.  You’re running off of battery - the difference between the linear and the switchmode is significant.  Your uC, the GPS, the LCD, and the BJTs are all being driven through your linear, and it doesn’t look like you’re powering down the GPS to conserve power (which of course would be a mistake anyway because you’d have to wait for multiple satellite locks to get a valid time).  Have you characterized the power draw of your circuit?  if you’re running from a 12V battery at say 12.5V, and you’re pulling 200mA constant (let’s ignore power on the fans and LEDs), you may be using 0.2A * 5.0V = 1W in your circuit, but your regulator is burning 0.2A * ( 12.5V - 5.0V ) = 1.5W, and the total circuit is consuming 2.5W.  A switchmode would bring that down much closer to the 1W constant.  Using sleepmode on the uC instead of GPS would delete the GPS load and reduce the uC load.  uC can turn off the LCD when not awake (you could use a button to interrupt the sleep and update the display), and these in turn would reduce the overall power draw.

    5. If you’re recharging the battery, you’re likely doing this when your system is connected to AC (generator, or dock) - having the battery charger simply implemented as a trickle charger would likely suffice - if your battery has dropped low enough that your relays don’t actuate, you can put yourself into a situation where you can’t turn on an external charger, so removing that logic simplifies things.  However, if you changed to mosfets, your system would work down to around 5V + the dropout of your linear regulator (yea, another reason to switch to a switchmode).

    What you have here is something not too different (except for relays, BJTs, GPS, and choice of uC) from what I use for a greenhouse monitor (driving heater and fans).