4-wire fan PWM control using a PIC18F4550


Once again I am playing around with PIC microcontrollers. Now I finished a complete demo that does this:

  • drive a 4-wire fan, in my case a Noctua NF-S12A using PWM
  • read the fan’s tachometer output to determine its speed
  • show the PWM duty cycle and fan speed on a 16×2 LCD

The demo application starts with a duty cycle of 0, where the fan doesn’t rotate and increases the duty cycle by 5% every 5 seconds, until it reaches 95%. Then it decreases the duty cycle by 5% every 5 seconds until it reaches 0. It keeps repeating this sequence forever.

At the same time it counts the pulses coming in from the fan’s tachometer output and displays the calculated speed every second.

The circuit

The circuit on my breadboard is made after this schematic (click to make it bigger):


The circuit to drive the fan and to read the tachometer is really simple. The microcontroller runs at 5 Volt and can directly drive the PWM input from a CCP output. The signal from the tachometer needs to be pulled up to 12V, after which simple resistor divider suffices to get that signal at the required TTL levels.

The firmware

The application is written in MPLAB X and uses Microchip’s xc8 compiler. The LCD module is borrowed and adapted from the “PC Case USB LCD” project by Simon Inns. The source is heavily commented so should be quite easy to understand.

The demo

You can see that the fan starts spinning when the system is powered up, but that it doesn’t move at duty cycles of 0 and 5%. It does start spinning at 10%.

The source


I sincerely hope that this helps someone.

Driving the 4 digit 7 segment display

Here is the documentation of my next step: driving the LED display. The design and the C code were not really difficult; the steps to put the results here were.

As I noted before I use a PIC 16F887, but CadSoft Eagle didn’t have this component in its library, so I drew a 877 which is pin compatible. Now I wanted to get it right and so I started my own library. Copying the 877 to it and then renaming it to 887 was simple enough. The next step was to get my 4 digit 7 segment display (datasheet in PDF)  in Eagle. I did find a 3 segment display that came close and it took me a bit of time to add the fourth digit. Now my custom library contains two components!

Continue reading “Driving the 4 digit 7 segment display”

Step two: add latches

Even though I use a big 40 pin PIC for my experiments I decided to try how sharing output pins for multiple purposes works. To do that I use two 74HCT573 (PDF) octal latches. The goal is to drive 16 outputs from 10 pins. If you add one more octal latch, it only costs one more pin to drive 8 more outputs. So, with 16 pins and 8 octal latches, you could come to 64 outputs.

I also added an output stage with a reed relay. My final goal is to make a variation on the looper project that can be found at jimkim.de.

Continue reading “Step two: add latches”