Introduction: Arduino Desk Fan Controller

When I recently changed roles within the company, I moved sites, moving from Bradford to our head office in Wakefield. I said goodbye to my faithful old desk with must have desk fan to keep me cool while all around me....... Anyway, the trend in our main office was for small USB powered fans around 4" to 6". So a nice antique brass effect 6" model was swiftly ordered and delivered the next day.

The problem with all fans, whether they have speed settings or mechanical oscillating modes, is they're either on or off, and you end up switching them on and off all of the time. A spark of imagination, combined with a requirement to raise up my monitor by a good 3", and my next project is born. Enter Fanomatic.

I'd played with Arduino for many years, so it was the logical first stop.

Step 1: Shopping List and Case

Shopping List:

  • 1 sheet of 12mm MDF - for the case
  • 1 Arduino Uno - the brains
  • 1 sml breadboard and wires
  • 1 DHT11 - digital temperature and humidity sensor - to sample temperature only
  • 1 .96" OLED display - to display variables - speed, temperature etc
  • 1 IRF520 Mosfet module - to switch the USB power on and off for the fan
  • 4 10k Potentiometers with different coloured knobs - to control fan speed, on time, off time, temp set point
  • 1 power switch
  • 1 sml tin blackboard paint - suitable for MDF with 1 coat
  • 1 usb cable and 1 usb socket


The size of the case was governed by the size of the base of my 24" monitor and 4 port KVM switch at 220mm wide and final height I wanted my monitor set to. Depth was quite flexible, so I went for 180mm to give plenty of room. So 220mmx180mmx60mm was the size. Now to make it and fill it.

The 12mm MDF was cut at home quite easily, before glue and screw to form a working base and front. The front was then drilled to fit 4 10k Potentiometers and 1 over the top on/off switch which would control power to Arduino and fan. A rectangular hole was chiselled out to hold a small smoked grey acrylic panel, behind which I planned to secure one of those cute OLED displays. Halfway through, I wish I'd gone for 3mm ply for the front, instead of 12mm MDF as there was more wood removed than remained.

Once holes had been drilled and chiselled in the back and side for temperature sensor, usb socket and usb power in. A couple of coats of blackboard paint were applied. It's a great paint for mdf as it soaks in well and doesn't need an undercoat. It gives a very unforgiving matt finish, just what I was looking for.

Pots and switches were attached, smoked acrylic hot glued in and Dyno labels produced for that retro look.

Next to the controls...

Step 2: The Controls

All based around an Arduino Uno. I bread boarded the components and made a start on a sketch.

The sketch uses 3 libraries:

  • One to drive the irf520 mosfet to switch the fan on.
  • One to drive the OLED display
  • One to read and translate the temperature data from the DHT11

I'll include the sketch here later, once I've tidied it up a bit, but please be warned, I am NOT a coder, I understand good coding principles, but tend to be a lazy coder. If I can find a way around something and it works, then it works.

There are some great sites out there explaining how to use each.... and will include links to the best (in my opinion) sites to get the best out of each.


A single usb cable provides power to the Arduino AND to the USB fan. The Arduino cannot run the fan as the current it pulls would damage the Arduino (a bit dramatic actually! it would trip the onboard fuse). So we need to find a way of using the Arduino to switch the power to the fan on or off.

A transistor is required, I first ordered a Darlington transistor, but after reading up, plumped for a irf520 MOSFET driver module from Geek Alert!! The IRF520 is great for logic level switching (output from Arduino pins). The voltage sent to the device determines the resistance of the MOSFET, I.E. sending 0 to 255 to a digital pin will drive the fan (or other connected device) from off to full speed.

We'll come back to 0 to 255 later.

So we're switching a fan on with an Arduino, why bother? Well, we don't want it to come on when it's too cold, do we? So if we add a temperature sensor, we can write code and test to see if it's hot and turn the fan on (255) or off (0). I went for a DHT11 as it's dirt cheap, easy to code and accurate enough for this project.

Back to that 0 to 255 business. If we know that a bit of code will turn the fan on (255) if the temperature is high, or off (0) if temperature is low, if we had a value between 0 and 255, the resistance would rise or fall across the MOSFET and speed up or slow down the fan.

Enter a potentiometer connected to an analog pin! When turned, generates a value between 0 and 1023. This value can then be tested in code to change the fan speed!! yipeeeee.

There's one last thing (well, a couple). The motor control library we will use to drive the MOSFET driver accepts 2 parameters, one to set the resistance (for the speed) and another to set duration. So with this magic parameter, we can set how long the fan is on, and how long the fan if off.

So, we have 4 pots to control the 4 variables. Next we'll look at the display.

Step 3: The Display

Does it NEED a display? Not really. So why does it have one? Well, because I wanted a cute display to show the current temperature, fan speed, fan on time, fan off time and temperature set point.

The U8G library is brilliant at driving this tiny OLED display. It took an evening of research and I got my head around the commands to get the font size I wanted for 5 rows and to get the variables to display using the u8g.print() commands. The advantage of this display is that it's not a 2 or 4 'row' display that the Arduino community is so used to, so graphics, fonts are all very doable.

To be honest, most of the code is driving the display. if statements determine values to be displayed, E.G. convert a value from the analog pots (0 to 1023) into a value to display on the screen. In all, there are several sets of statement blocks, determine fan speed from pot, convert to % value for screen and value between 0 and 255 to drive the fan.

Well, that'll do for now folks. I hope you enjoy this first instalment. I'll edit and update with links and the code. If there's anything you'd like detail on, please leave a comment and ask.

Step 4: Code

I promised to upload the sketch when I posted this, 3 years ago, and never did.

So here it is......