Home Projects PC related 8 Channel software controlled fanbus with PWM


8 Channel software controlled fanbus with PWM
author: Robin Bjerregaard Jensen - dthought@drunkardswalk.dkwww.drunkardswalk.dk

Project CK II – version 2.1

Around a year ago I revealed Project CK, a 5-channel software-controlled fanbus. A short while later I was contacted by Morten Givskov (d_morten), and we discussed lots of possible improvements before reaching this new version, which we have developed together. d_morten is primarily responsible for the hardware part, while I’ve concentrated on the programming side.


Well, what is it?
Like Project CK it is a software-controlled fanbus with parallel port interface, but now with 8 channels and pulse-width-modulated outputs, which means that each output can be controlled a lot better than just 0-5-7-12 volts.

The fanbus is as mentioned software controlled, and the outputs can either be adjusted manually, or automatically adjust up and down depending on the temperature of the system sensors, as monitored by Alexander van Kaam’s ”Motherboard Monitor”.
An extra effect is the possibility of setting the outputs to randomly “flicker”, which opens up a whole new kind of case mod effects.

The fanbus being software controlled of course means that you should NOT use it for critical fans – as the fans will not start before Windows has loaded and the program started, and they will probably also stop if the machine crashes.
However, the fanbus can be equipped with a ”manual override” switch so you can turn (pre) selected outputs on full if need be.

Project CK II, version 2.1 features:

The power of each output can be adjusted in steps from 10% to 25%, depending on how many steps are chosen.

Pulse-width-modulated outputs – see d_morten’s explanation about this.

The pulse time (common for all out outputs) can be adjusted between app. 1 and 25 milliseconds. 5 milliseconds seem to be the best setting. Most fans will begin “whining” if you use a faster setting, and with longer pulses they might begin “chopping/growling/humming”. This is actually the only disadvantage of PWM – a few fans do not like those pulses and will begin to shake and vibrate, so you’ll have to mount them so the resonance is squelched.

The problem primarily shows up when using very powerful fans (due to their high torque (?)), and you’ll have to run them at at least 40-50% power to eliminate the resonance/drown the noise..

Each output can be adjusted three different ways:

Manually. (old-school). However, this fanbus has the advantage that many fans can run slower using PWM instead of traditional power limiting. Some can even start and run as little as 10% power, most do require at least 20%, though.

Automatically – depending on sensor temperatures read by Motherboard Monitor.
When the minimum temperature is reached an output is activated at a certain individually adjustable power level, and the power is then increased if the temperature increases, until the maximal power is applied at the “maximum power at” temperature.
Each output can be connected to an optional sensor.

Random ”flicker” with adjustable intensity. This setting gives a cool ”flickering” effect if your case has a window lighted by Lazer LED’s. We imagine a lot of possibilities for annoying others at LAN parties :P

My webcam is not light-sensitive enough to capture the effect very well, but here are two short clips that may give an impression of it.:

We’ve got several other settings under development/consideration – but any ideas are highly welcome.

Other settings:
Almost all PC’s parallel port has the address 0x378h, and it is also the default value for the program. If necessary it can easily be changed to the other standard values for parallel ports, namely 0x278h or 0x3BCh.

Last setting is to tell the program to start up minimized to the system tray.

The program:

The program is written in C/C++ using Borland C++ Builder 4, and is optimised for Windows 2000/XP. It does also work in 9x/Me, but not optimally.


For the program to work under NT-based operating systems the file ”porttalk.sys” MUST be copied to ”Windows Directory”/system32/drivers , which is usually /WINNT/system32/drivers

The code is not really written in a structured way, it has just “evolved” over time as I kept working on it, but then again it’s only a hobby project and not “professional” code. Furthermore I don’t have any (completed) education in programming (nor anything else), and I flunked my last programming test, so it’s “take it or leave it”. If anyone wishes to improve the code they are welcome, but the changed code must be publicly available.

Code explanation, licenses, comments:


Most of us use Windows NT-based operating systems, and NT protects the I/O ports better than the old DOS-based operating systems.

The first problem I had to overcome was therefore to find some code so I could access the parallel port – and at http://www.beyondlogic.org/ I found some code samples for the ”Porttalk” driver, which enabled me to proceed.

This code is freely available, albeit with these limitations:

/* Copyright © 2002 Craig Peacock. Craig.Peacock@beyondlogic.org              */
/* Any publication or distribution of this code in source form is prohibited  */
/* without prior written permission of the copyright holder. This source code */
/* is provided "as is", without any guarantee made as to its suitability or   */
/* fitness for any particular use. Permission is herby granted to modify or   */
/* enhance this sample code to produce a derivative program which may only be */
/* distributed in compiled object form only.                                 

So that means I am only allowed to release the compiled .exe.However, I was given permission to also release the source code showing my implementation – thanks a lot, Craig Peacock.


Somewhere on the Internet I found a little piece of Delphi-kode with a simple trayicon I could import and use with Borland C++ Builder. This code seems to be abandoned freeware, written by Pete Ness, http://ourworld.compuserve.com/homepages/peteness/ This code is in trayicon.zip


MBM Integration:

I got access to Motherboard Monitors (http://mbm.livewiredev.com/) “shared memory” using code with this license:

// ---------------------------------------------------------------------------
// --------------------------------------- Copyright 2001 A@majland.org ------
// --------------------------------------- Alteration for use in Visual C ----
// --------------------------------------- By Chris Zahrt techn0@iastate.edu -
// ---------------------------------------------------------------------------
//  Version     : 0.1
//  Date        : 02-27-2002
//  MBM         : version 5.1
//  Author      : Chris Zahrt techn0@iastate.edu (visual c alterations)
//                http://techn0.dhs.org/programming/vcmbmsm.html
//                Anders@Majland.org (author of original c code)
//                http://www.majland.org/sw/mbmcaf
//  Licence     : Cardware. (Send me a note/email if you find it usefull.)
//                Basically you may use it as you see fit as long as the origin
//                of the code remains clear

Code explanation:

The program is visually composed of two forms, Unit1.cpp (main GUI) and About.cpp (the About-box). Technically the program is multithreaded, with one thread being the main GUI, the other in WriteThread.cpp.



When the program is started it is first checked if another instance is already running (by checking a Mutex, whatever that is ;P), and the new instance is closed if that is the case.

Then the OS is detected, so the program knows whether it can write directly to the ports (under Win9x or WinCrappyME), or if the ”Porttalk” driver has to be used (under NT, Win2000 or WinXP).

Then the settings are read from the file CKControl2.INI, placed in the Windows directory. If it doesn’t exist (for instance at first start up) defaults are used. (Ok, .INI files are obsolete and against Microsoft’s specifications, they want you to use the registry instead, but if anyone wishes to use the registry instead then go ahead and rewrite the code.)

After that various variables, structs  and arrays are initialised, and the various graphical components are adjusted.

If it’s a NT-based OS a check for the existence of Porttalk is performed, and it’s activated. Finally WriteThread is activated – the thread being responsible for doing the actual port output.

The program has two timers..

One takes care of minimizing the program to the system tray if that option is chosen, the other timer fires every 1.5 seconds, reads the temperatures from Motherboard Monitor and performs any necessary adjustments to the current settings.  Apart from that there are just various ”Event Handlers” taking care of what should happen when you click/adjust the components. When the program is closed the settings are saved in the .INI file, and all outputs are set low.


The biggest problem I’ve had during development of this program has been to write to the port with decent regularity.

The solution I’ve finally implemented is to use a separate thread running with High Priority, which after each update is paused with a call to ”Sleep ()”.

The various variables in the program are a judicious mixture of global variables and static arrays. The GUI takes care of adjusting the “high level output settings”, the thread messes with the low level (bit-level) details. Data is shared between the GUI and the thread using “extern int”.

Despite the confusing mixture of code fragments, various ”hacks” and lack of skill and ability on the part of the programmer the program does work absolutely flawless in our tests.

 >> Download Executable Program <<


<< Introduction [Previous Page]                                                        [Next Page] Hardware >>



120x90 spot



Search Site | Advertising | Contact Us
Elektrotekno.com | Free Schematics Search Engine | Electronic Kits