PWM Computer Fan Controller
I made a computer fan controller because the stock fan came on too loud. The stock 2 wire fan had only off and fully on, sounded like a jet engine when it came on- very startling. The idea was to measure the fan speed, measure the exhaust air temperature, and use pwm to control the fan speed. The easy way to do this is to use a quiet 4 wire fan. The 4 wire fan has fan tachometer output, and uses pwm as input to control speed. No driver transistor is required, it is internal to the fan on 4 wire types.
Supplies
NodeMCU (ESP8266) -Amazon.
.96 inch White OLED module 128 x 64 I2C -Amazon
TMP36 -Amazon
4 wire Fan (buy dimensional size according to need) -Amazon
5 volt regulator 78L05 sot89 -Aliexpress
small wires - scrap from old television
servo extension wires 50 cm -Aliexpress
female header pins -Aliexpress
male header pins -Aliexpress
M2 2mm nuts and bolts iExcell 250 piece set -Amazon
3D printer -Anycubic i3 Mega -Aliexpress
ABS clear transparent filament -Amazon
Arduino IDE -free online
Fusion 360 -free for non commercial use online
Cura slicer - free online
Construction
I soldered header strips on perfboard to match the male header pins on the NodeMCU microcontroller, then trimmed the perfboard to just the area of NodeMCU. This ensures it will fit into the 3D printed enclosure. Next, solder 3 wires to the perfboard for the TMP36, install a surface mount 5 volt regulator on the perfboard next to the Vin pin of the NodeMCU, and connect the 4 wires for the OLED display, and solder ground and 12 vdc wires which will extend to a spare PC power connector. An additional 4 wires go to the fan (ground, +12v, tach, and pwm). The wires for the OLED come out the end of the NodeNCU with the USB connector, while all other wires get installed towards the back end of the NodeMCU. Note that .1uF surface mount capacitors need to be mounted on the perfboard where the TMP36 wires attach (between 3.3v and ground, and between sensor pin and 3.3 volts- look closely at picture, caps are smaller than a grain of sand), otherwise stray RF will cause the temperature to read random values rather than the temperature. The TMP36 was soldered to some servo extension wires (male pins) after the plastic surround was removed from around the pins, and then 2 pins were swapped so the color code matched the TPM36 pins (red for 3.3v, white for Vout, and black for ground). Download the code via the Arduino IDE. Install the fan, and attach the TMP36 to the air exit of the case the fan serves. I just used tape, but will glue it on later. The OLED display gets attached to the 3D printed case with 2 mm s.s. hex bolts an nuts. The case bottom needs 2 ea. small holes drilled straight through (actually drilled through top and bottom when held together) and 2 small screws will then be fitted to hold top and bottom together. I printed the case in clear ABS.
Conclusion
Test the actual rpm output vs. displayed value via a handheld tach. Mine read within 50 rpm, close enough. Measure the air temperature, and adjust code if necessary. The ADC in the NodeMCU isn't linear near the ends (0 volts and 3.3 volts), but that won't be a problem. I used 3.0 volts rather than actual 3.3 volts as the reference voltage in code to make the temperature reading come out correctly. Note there is a minimum rpm, to insure air flow across the TMP36. The fan I chose used considerably less current than the stock fan, so the pwm duty cycle required for full rpm is only 50%, while a high capacity, high current fan will require almost 100% duty cycle. Fan pwm frequency didn't seem to matter much, but be aware that the higher the pwm frequency (like 20 kHz) the less individual duty cycle steps between 0 and 100%. I think there were 15 steps at 20kHz. There wasn't much audible difference between steps.
It works great and very quiet!