An Arduino fan controller monitors temperature using a sensor and automatically switches a cooling fan on or off — or better yet, smoothly adjusts fan speed based on temperature. This is one of the most practical Arduino projects for Indian makers, useful for cooling 3D printer enclosures, server cabinets, battery packs, and DIY amplifiers.
Project Overview
This project builds a temperature-triggered fan controller using an Arduino, DS18B20 temperature sensor, and a MOSFET to drive a 12V DC fan. The basic version turns the fan on above a threshold temperature. The advanced version uses PID control for smooth, proportional speed regulation. Both versions are suitable for beginners and can be built in under an hour.
Components Required
- Arduino Uno or Nano — ₹193
- DS18B20 temperature sensor module — ₹53
- N-channel MOSFET (IRLZ44N or equivalent logic-level MOSFET)
- 12V DC cooling fan (4010, 5010, or 8025 depending on your application)
- 12V power supply (2A minimum)
- 4.7kΩ pull-up resistor (for DS18B20 data line)
- 1N4007 flyback diode
- Breadboard and jumper wires
- Optional: 10kΩ potentiometer for adjustable threshold
- Optional: I2C OLED display (128×64) for temperature readout
Core Components
Circuit Diagram and Wiring
The circuit is straightforward:
- DS18B20: VCC → 5V, GND → GND, Data → Arduino pin 2 (with 4.7kΩ pull-up to 5V)
- MOSFET (IRLZ44N): Gate → Arduino pin 9 (PWM), Source → GND, Drain → Fan negative wire
- Fan: Positive → 12V supply positive, Negative → MOSFET drain
- Flyback diode: Cathode to fan positive, Anode to fan negative (across the fan terminals)
- Power: 12V supply GND connected to Arduino GND (common ground essential)
The flyback diode protects the MOSFET from voltage spikes when the fan motor switches off. Never omit this component.
Arduino Code: Basic On/Off Control
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2
#define FAN_PIN 9
#define TEMP_ON 40.0 // Fan ON temperature (°C)
#define TEMP_OFF 35.0 // Fan OFF temperature (°C) - hysteresis
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
bool fanRunning = false;
void setup() {
Serial.begin(9600);
sensors.begin();
pinMode(FAN_PIN, OUTPUT);
digitalWrite(FAN_PIN, LOW);
// Set Timer1 PWM to ~31kHz
TCCR1B = TCCR1B & 0b11111000 | 0x01;
}
void loop() {
sensors.requestTemperatures();
float temp = sensors.getTempCByIndex(0);
Serial.print("Temp: ");
Serial.print(temp);
Serial.println(" °C");
if (temp >= TEMP_ON) {
analogWrite(FAN_PIN, 255); // Full speed
fanRunning = true;
} else if (temp <= TEMP_OFF) {
analogWrite(FAN_PIN, 0); // Off
fanRunning = false;
}
delay(2000);
}
The 5°C hysteresis (on at 40°C, off at 35°C) prevents the fan from rapidly cycling on and off when the temperature hovers near the threshold.
Advanced: PID Fan Speed Control
For smooth, proportional fan control, implement a simple PID-like mapping:
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2
#define FAN_PIN 9
#define TEMP_MIN 35.0 // Fan starts spinning
#define TEMP_MAX 60.0 // Fan at full speed
#define PWM_MIN 80 // Minimum PWM to start fan
#define PWM_MAX 255
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
void setup() {
Serial.begin(9600);
sensors.begin();
pinMode(FAN_PIN, OUTPUT);
TCCR1B = TCCR1B & 0b11111000 | 0x01;
}
void loop() {
sensors.requestTemperatures();
float temp = sensors.getTempCByIndex(0);
int pwm = 0;
if (temp >= TEMP_MAX) {
pwm = PWM_MAX;
} else if (temp >= TEMP_MIN) {
pwm = map((int)(temp * 10), (int)(TEMP_MIN * 10),
(int)(TEMP_MAX * 10), PWM_MIN, PWM_MAX);
}
// Kick-start if going from 0 to running
static int lastPwm = 0;
if (lastPwm == 0 && pwm > 0) {
analogWrite(FAN_PIN, 255);
delay(200);
}
analogWrite(FAN_PIN, pwm);
lastPwm = pwm;
Serial.print("Temp: "); Serial.print(temp);
Serial.print(" °C PWM: "); Serial.println(pwm);
delay(2000);
}
Adding an OLED Display
A small I2C OLED display makes the project much more practical by showing the current temperature, fan speed percentage, and status. Connect the OLED to Arduino SDA (A4) and SCL (A5). The Adafruit SSD1306 library handles the display.
Display layout suggestion: large temperature reading in the centre, fan speed bar at the bottom, and a small fan icon that animates when the fan is running.
Recommended Components from Zbotic
Full Project Kit Available on Zbotic
Extending the Project
- Multiple zones: Add more DS18B20 sensors (they share one data wire) to monitor multiple temperature zones and control multiple fans independently.
- Data logging: Add an SD card module to log temperature data over time. Useful for analysing cooling performance.
- WiFi alerts: Upgrade to an ESP32 and send temperature alerts via Telegram or email when temperatures exceed critical thresholds.
- Enclosure: 3D print a project box with mounting points for the sensor, fan, and display.
Frequently Asked Questions
Can I use an LM35 instead of DS18B20?
Yes, the LM35 (₹29 on Zbotic) is an analogue sensor that outputs 10mV per °C. Connect to an analogue pin and read with analogRead(). It is simpler but less accurate than the digital DS18B20.
How many fans can an Arduino control?
An Arduino Uno has 6 PWM pins, so it can control up to 6 fans independently through MOSFETs. For more, use a PCA9685 PWM driver board (₹309) which adds 16 PWM channels.
What power supply do I need?
A 12V 2A supply is sufficient for one fan. For multiple fans, calculate total current draw and add 20% headroom. The Arduino can be powered from the same supply via the Vin pin.
Why does my fan not start at low PWM?
DC fans need minimum torque to start spinning. Set PWM_MIN to at least 80 (out of 255) and add a kick-start burst of 255 PWM for 200ms when transitioning from off to on.
Can I use this for a PC case fan controller?
Yes, this circuit works perfectly for PC fans. Use 12V fans and adjust the temperature thresholds based on your CPU/GPU operating temperatures.
Shop Cooling & Thermal Components at Zbotic
India’s trusted store for electronics components. Fast shipping, genuine products, and expert support.
Add comment