An RS232-controlled ATtiny2313 based PWM board for up to four 12V fans.


Recently I bought a nice internal hard disk rack for five 3.5″ SATA disks that only occupies three 5.25″ slots in my home server. I really like it, but there is one small problem: it has two fans which are a bit loud, since the server is located in my living room. Without the fans the disks get too hot (I tried, but stopped at about 55° C). So, the fan speed needed to be reduced, which was easily done by putting them in a row, so each would get only 6V instead of 12V. They still work at 6V, but are significantly less noisy. The temperature of the disks is now at approximately 39°-43° C. I could probably live with that.

But of course it would be much nicer to have a temperature-aware fan control.


There is an utterly unused serial port on my server’s mainboard, which would be ideal for controlling a small microcontroller based fan driver circuit. A script on the server can read the hard disks’ temperature via SMART and set the fan speed accordingly. When the script is not running, the fan controller should simply set the fan speed to 100%.


For its current capabilities, an ATtiny45 or 85 would have sufficed, but I chose an ATtiny2313, because I might want to use some extra pins for other stuff one day (like RPM or temperature measurement, for example). Plus, I had a few ATtiny2313 lying around. The fans are driven via an ULN2803A and the communication with the server uses a MAX232 for level conversion. Power is conveniently obtained from an unused floppy power connector (5V for the microcontroller and 12V for the fans). All in all, it’s pretty simple:


I first tried this on a breadboard, and it worked quite well. Since the hardware is quite simple and I don’t intend to build more than one or two units, I did not bother designing and etching a PCB but used perfboard instead. When the board was finished and working, I used two-component epoxy glue to add four screw nuts, so I could easily mount it inside an unused hard drive cage.


Control protocol

Communication with the microcontroller is done via a simple serial protocol at 9600 baud, 8N1. This is nice because you can use any serial terminal program (like minicom or moserial) for controlling the device. Quite convenient for debugging. I wrote a simple command parser that understands the following commands:

info          print name, firmware version and build date
reset         reset (mainly for running the bootloader)
set <n> <v>   set control register n to value v. n is one digit, v is a two-digit hex value
get <n>       get value of control register n
get           get values of all control registers

The control registers are all 8 bit integers and have the following meaning:

0: (reserved)
1: pwm0 (00=off, ff=100%)
2: pwm1 (00=off, ff=100%)
3: pwm2 (00=off, ff=100%)
4: pwm3 (00=off, ff=100%)

All of the control registers can be read from and written to. When writing to a pwm control register, the pwm values of the output pins are automatically updated by the firmware.

Safety measures

When the host software that controls the fan speed is not running, the system should automatically switch the fan speed to a default value; probably 100% is a good choice here. When the firmware is finished, it should set all output ports to default values on system reset, and when there has not been any communication with the host for a specified amount of time  (probably 30 or 60 seconds).


When it’s done, the current firmware can be obtained [here – TODO]. If you have suggestions for improvements, don’t hesitate to send me a patch. If I like it, I’ll include it and post it here.

Host software

I guess this will just be a very simple Python or Ruby script.

To be continued…

Leave a Reply