My brother plans to install a desktop computer in his kitchen. He’d like to hide the computer in a cabinet so that the computer doesn’t take up valuable counter space. The computer monitor requires a cable, but the keyboard and mouse will be wireless.
Heat buildup is a concern anytime a major electrical device is installed in an enclosed space. For the computer in the kitchen cabinet, he plans on adding some external fans in the rear board of the cabinet and perhaps in the front baseboard. However, it isn’t desirable to have the fans turned on all the time, because that would be noisy, dusty, and not very energy efficient.
Over the course of a weekend, I cobbled together some leftover robot parts to create a simple dual-fan controller. The board turns on the first fan when the temperature reaches a user-adjustable dial setting, and it turns on a second fan if the temperature exceeds an additional 5 degrees Fahrenheit. With this method, only a single fan is used if the temperature can be kept under control with only one fan, but both fans will kick on if necessary.
Each fan turns off when the temperature drops 5 degrees below its turn-on temperature. For example, if the dial is set to 80 degrees, the fan turns on at 80 degrees and turns off at 75 degrees. This prevents the fan from cycling on and off rapidly, which would occur if the fan turned on at 80, started to cool the cabinet, and then immediately turned off at 79.
Close-up of fixed resistor and thermistor voltage divider read by ATtiny45 microcontroller
An 8-pin Atmel ATtiny45 microcontroller uses one of its analog-to-digital pins to measure the voltage divided between a 4700 ohm fixed resistor in series with a BC Components 2322 640 66103 NTC 10 kilohm thermistor (DigiKey BC1482 $0.68). The thermistor changes resistance in a predictable way based on the temperature.
Schematic of fixed resistor with thermistor voltage divider, and potentiometer voltage divider, read by an Atmel ATtiny45 microcontroller
The voltage between +5 VDC and GND (0 VDC) is divided between R1 (fixed resistor) and R2 (thermistor) depending on the temperature. If R1 and R2 have the same resistance they’ll both have the same voltage, and the point between them will be halfway between 5 V and 0 V = 2.5 V. If R2 has a higher resistance, then the voltage at that point will be higher. If R2 has a lower resistance, then the voltage at that point will be lower. So, that’s the point we want to measure with an analog-to-digital voltage pin of the ATtiny45 (IC1).
The user-adjustable potentiometer (R3) follows the same method to convert its resistance into a voltage. The first pin is connected to 5 V, the third pin is connected to 0 V, and the pin in the middle connects to another analog-to-digital voltage pin on the ATtiny45.
After being read into the microcontroller, the thermistor voltage is represented as an 8-bit number (0 to 255). The C code looks up the 8-bit analog-to-digital number in an array, to convert the thermistor value to a temperature in Fahrenheit:
temperatureInFahrenheit = gTemperatureFahrenheitTable [ 255 - ADCGetSingle8Bit(TEMPERATURE_ADC_PIN) ];
const unsigned char gTemperatureFahrenheitTable [ ] =
{ 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 3,
6, 8, 10, 12, 13, 15, 17, 19,
20, 22, 23, 25, 26, 27, 29, 30,
31, 33, 34, 35, 36, 37, 38, 40,
41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 52, 53, 53, 54, 55,
56, 57, 58, 59, 60, 60, 61, 62,
63, 64, 65, 65, 66, 67, 68, 69,
69, 70, 71, 72, 72, 73, 74, 75,
75, 76, 77, 78, 78, 79, 80, 81,
81, 82, 83, 83, 84, 85, 86, 86,
87, 88, 88, 89, 90, 91, 91, 92,
93, 93, 94, 95, 95, 96, 97, 98,
98, 99, 100, 100, 101, 102, 102, 103,
104, 105, 105, 106, 107, 107, 108, 109,
110, 110, 111, 112, 112, 113, 114, 115,
115, 116, 117, 117, 118, 119, 120, 120,
121, 122, 123, 123, 124, 125, 126, 127,
127, 128, 129, 130, 131, 131, 132, 133,
134, 135, 135, 136, 137, 138, 139, 140,
141, 141, 142, 143, 144, 145, 146, 147,
148, 149, 150, 151, 152, 153, 154, 155,
156, 157, 158, 159, 160, 161, 162, 163,
164, 165, 166, 168, 169, 170, 171, 173,
174, 175, 176, 178, 179, 180, 182, 183,
185, 186, 188, 189, 191, 193, 194, 196,
198, 200, 201, 203, 205, 207, 209, 212,
214, 216, 219, 221, 224, 226, 229, 232,
235, 238, 242, 245, 249, 253, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255 };
Instead of using a table, the microcontroller could have been programmed to perform the actual voltage-divider-to-Fahrenheit calculation. But, the calculation is very complex. The code would have consumed more space than the table and it would have been a lot slower. It’s easier for a desktop computer to perform the calculations in Excel and then for me to copy and paste the resulting table into the embedded code.
It is highly unlikely that the temperature in the kitchen cabinet will be lower than 0 degrees or greater than 255 degrees Fahrenheit. So, I only used temperature values between 0 and 255, as they will fit nicely into an unsigned char, which saves memory over using an int or a short.
The beginning values (multiple 0s) and ending (multiple 255s) values in the table do not reflect the actual temperatures at those extremes, but have been pinned to the minimum and maximum values that can be represented by an unsigned char. I could have used a couple of IF statements to ignore really low and really high values before looking them up in the table, but the code itself would use memory, it would be slower, and it would be slightly more difficult to maintain.
The potentiometer allows a user to adjust the temperature at which the first fan will turn on. Although technically possible, it would be a little silly to allow the user a range of 0 degrees to 255 degrees Fahrenheit. Instead, a little math is performed on the value after it is read from the potentiometer to convert it into a narrower range of 65 to 130 degrees. Not only is this range a little more practical, but tiny adjustments of the dial no longer swing the trip point by tens of degrees.
#define TRIP_LEVEL_MINIMUM_IN_FAHRENHEIT 65
#define TRIP_LEVEL_MAXIMUM_IN_FAHRENHEIT 130
tripLevel = CL_ADCGetSingle8Bit ( TRIP_LEVEL_ADC );
tripLevelInFahrenheit = (unsigned char)
(((((unsigned short)tripLevel) *
(TRIP_LEVEL_MAXIMUM_IN_FAHRENHEIT
- TRIP_LEVEL_MINIMUM_IN_FAHRENHEIT ) ) / 255 )
+ TRIP_LEVEL_MINIMUM_IN_FAHRENHEIT);
The fans are standard brushless PC box fans with a 12 V wire and a ground wire. They only need to be turned on or off. A full h-bridge (coast, brake, forward, reverse) is unnecessary.
I used my favorite International Rectifier FU5505 power MOSFET transistor to provide 12 V or off. To drive each MOSFET (one per fan), I used a variation of my favorite driver chip, the IXYS IXDI404PI. (See Intermediate Robot Building chapters 9 and 10.)
PC fan driver circuit with IXYS MOSFET driver and International Rectifier FU5505 power MOSFETs
My brother need only insert a 12 VDC power source in the first screw-terminal connector pair, and wire the fans to the other screw terminals. Then, with the computer operating, he can simply adjust the dial on the potentiometer until the first fan turns on. After that, the dual fan controller will power the fans off and on as necessary.
This nifty little device is about the size of a pack of playing cards. Since the tiny microcontroller is running at only 1.2 MHz and most of the other components are powered off when idle, it doesn’t use much power.
I thought this was a pretty good solution. However, my brother thought otherwise. He objected to the lack of a protective case, the lack of a printed circuit board for the fan driver circuit (as opposed to the point-to-point wiring on perf board), the lack of a power switch, and the lack of fuses or other safety features.
Normally, I would have told him a proverb about a gift horse. However, his 40th birthday was coming up and I could think of no better present than something handmade yet polished.
It took me about a month and a half of weekends and evenings, and about $200 of the highest quality parts, to create the most over-engineered dual fan controller in the history of humankind (with the possible exception of military devices). What follows is the Professional Dual Fan Controller.
Professional dual fan controller with temperature display and speaker alarm
The Professional Dual Fan Controller consists of four major parts:
DPS120200U-P5P-TK 12VDC switching power supply adapter
The power supply accepts standard household power (100-240 VAC 50/60 Hz) and provides up to 2 amps of 12 VDC. It looks like an ordinary wall wart, but it actually contains a switching regulator capable of over 75% efficiency. This feature reduces the amount of wasted electricity and generates less heat.
The power supply also contains safety features like over-voltage, over-current, over-shoot, and short-circuit protection. This act as the first line of defense in the case of serious failure. If I made a mistake in my project, the commercial power supply’s safety features will limit the maximum power that can be drawn from the household power line.
Part #DPS120200U-P5P-TK (DigiKey T939-P5P-ND $14.88).
The Fan Controller has a master power switch that turns on the entire unit when the switch is toggled towards the LEDs.
Front of the fan controller showing master power switch and status LEDs.
The green LED indicates power is on.The Fan Controller is encased in a commercial cast aluminum enclosure (DigiKey 377-1466 $17.44). I had to drill the holes and add the rubber grommet (to prevent the wires from getting scratched up). During drilling, I tried a trick that Terry Surma recommends - use kerosene as the lubricant/coolant on aluminum. It works beautifully!
Circuit board inside of the fan controller showing safety features, MC33887DH motor fan driver, and PT5101N 5V switch regulator.
There are two printed circuit boards in the Fan Controller. I designed the circuits and sent them to a PCB manufacturer to obtain commercial PCBs.
The top board is the internal power supply and motor driver board. Similar to the hacked-up fan controller, this has the same type of screw terminals (1) for the power input and fan outputs. (DigiKey ED1973 $0.67)
For safety and performance, the power supply portion of the board contains a self-resetting circuit breaker and p-channel reversed-battery protection (2). It also has a variety of bypass/decoupling capacitors (3) and an overvoltage-protecting zener diode. (To learn more about these techniques and to get part numbers, see Intermediate Robot Building chapters 7 and 8.)
The Freescale MC33887DH motor/fan drivers (4) have short-circuit, undervoltage, and over-temperature protection. They are capable of 5 amps continuous output and provide current feedback information to the microcontroller, so that it can check for stall or lack of a fan. (See Intermediate Robot Building pages 199-206.)
Unlike standard 5 volt regulators, this Fan Controller board contains a PT5101N (5) (DigiKey $12.25) switching regulator. Although it is ten times the price of a 7805, it is able to convert most of the incoming 12 volts down to 5 volts, as opposed to just throwing away the extra 7 volts as heat. That’s an important feature to have when making a device that is supposed to keep things cool.
Two PCB circuit boards mounted back-to-back
The second board in the Fan Controller is attached to the underside of the first board using the same technique I used on Roundabout (see pages 343-358 in Intermediate Robot Building). The second board contains an Atmel ATMega168 running at 8 MHz with a battery voltage monitor, I2C bus connection, and a BC1482 thermistor.
The thermistor is located in the Fan Controller case, not the Display Head, because the Fan Controller is likely to be mounted in the cabinet, whereas the Display Head is likely to be mounted in a more visible location.
BC Components thermistor with thermal transfer heat sink compound mounted by screwing it against an aluminum case.
The bottom of the thermistor is coated with some white heat-sink compound (to improve thermal transfer) and is screwed against the aluminum Fan Controller case for maximum thermal transfer through physical contact. Since the displayed temperature corresponds to the Fan Controller case temperature, it is best to locate the Fan Controller case nearest to the hottest point of the item that is to be temperature regulated.
The Fan Controller case is made of thermally-conductive aluminum. This means the case’s temperature will follow the ambient temperature. Additionally, because of the large size of the case, it acts as a thermal capacitor - absorbing brief changes in air temperature. This reduces cycling the fans off and on.
The Fan Controller contains everything it needs to do the job: power supply, temperature sensor, microcontroller brain, and fan drivers. The Display Head communicates to the Fan Controller via an I2C two-wire serial bus. However, after the user has selected the desired on/off trip point settings, the Display Head could actually be cut off and the Fan Controller would continue to operate the fans. In fact, since the settings are stored in the ATMega168’s non-volatile EEPROM, the last entered settings are retained even after power off.
Solid brass display head with four-digit numeric blue LEDs.
I’m really proud of the way the Display Head turned out. Unlike the Fan Controller case, this was not purchased commercially. Both the brass face and black box were hand made by me. The Display Head will likely be mounted such that only the brass face, buttons, and numeric display will be visible.
There are complete details on machining the brass face and buttons, but what follows is a quick summary:
The brass face was roughly cut to size from a solid brass bar using a hacksaw. The size was finished and the edges were squared on a milling machine. The button holes and recessed screw holes were drilled on the milling machine (used as a drill press).
The brass buttons started as a 1/4 inch diameter solid brass rod. The end of the rod was first chamfered on a bench grinder, and then an appropriate length from the end of the rod was cut off with a cut-off saw. This process was repeated to produce four buttons. (When I got a lathe, I developed a more refined method of making one-piece flanged buttons.)
For the numeric display area, I began by drilling out the inside corners of the brass bar as best I could with a tiny 2 mm drill. Then, the remaining area was drilled out with a larger drill, milled square, and finally the inside corners were squared up with a square file. The oversized cover window was cut from polycarbonate on a milling machine.
Finally, the edges of the entire brass assembly were deburred and smoothed with a rotary tool (a Dremel) using a buffing wheel with polishing paste.
Standard 1 inch headers on a numeric LED display face circuit board slid onto pads on the primary circuit board.
Inside the Display Head, I soldered standard single and double-row, 1-inch spaced, male headers to a small board that contains only the blue Lite-On LTD-2701B LED displays (DigiKey 160-1520-5-ND $7.24 per multiplexed pair) and push buttons. That board is then mounted perpendicular (90 degrees) to the primary board by soldering the tips of the headers to copper pads on the top and bottom of the primary circuit board.
Male headers soldered onto pads allow two circuit boards to be attached at 90 degrees (perpendicular).
This arrangement results in a fairly low profile. It is very sturdy, which is important in handling the physical forces of buttons being pressed.
The display contains four buttons.
Solid-brass button controls with polycarbonate window.
The Mode Back and Mode Forward buttons move through a menu of different features and settings. The exact function of the Adjust Down and Adjust Up buttons differ based on the particular mode.
At power up and after the display has been idle (no buttons pressed) for over a minute, the modes/adjustments are locked out to prevent settings alteration by playful children, smart dogs, and people with big butts leaning up against it. To unlock, simply press the Mode Back and Adjust Up buttons at the same time.
After the display has been idle (no buttons pressed, no fans active) for over a minute, it will return to locked mode and a screen saver kicks in to prevent LED burn out. Pressing any button will return to displaying the temperature.
(Click the picture for a 1MB video of the screen saver in action)
The screen saver really is necessary. If the screen stayed fixed on “72 F” all the time, then those LED segments would gradually dim and fade. By having the screen saver briefly step through each segment in the entire display, not only will all the segments retain their brightness longer due to decreased usage, but the fading should be relatively equal across all segments.
Since no more than one segment is turned on at any one time during screen saver mode, the device uses much less power (less than half a watt, total). Less power means less heat. I had considered blanking the screen completely, but having at least one segment lit indicates the device is powered on. And, lighting different segments over time indicates that the microcontroller is functioning.
(Click the picture for a 1MB video with audio of the Professional Dual Fan Controller powering on)
In some ways, despite creating dozens of robots before this, the fan controller is the most complex embedded project I have created to date.
The project really turned out well and I learned a lot. I’m looking forward to seeing it in action.