Skip to content
Buy 10+ on select items — save 10% auto-applied
Free US shipping on orders $35+
Order by 3pm ET — ships same-day from the US
Worldwide shipping via DHL
Skip to main content

Arduino Uno DHT11: PWM Fan Speed Control

September 13, 2026 22 views

Arduino Uno DHT11: PWM Fan Speed Control | ShillehTek
Project

Build an Arduino Uno DHT11 thermostat that ramps a DC fan with PWM, shows live readings on an I2C LCD, and avoids chatter with hysteresis by ShillehTek.

45 min Beginner-Intermediate9 parts

Project Overview

Temperature-Controlled Fan with Arduino Uno and DHT11: Build a proportional thermostat where an Arduino Uno reads a DHT11 sensor, shows temperature, humidity, set point, and fan percentage on a 16x2 I2C LCD, and ramps a DC fan with PWM through an L298N motor driver based on a potentiometer set-point knob.

  • Time: ~45 minutes
  • Skill level: Beginner-Intermediate
  • What you will build: A proportional temperature-to-fan controller with an adjustable set point, a hysteresis band so the fan does not chatter, and a live LCD readout.
Arduino Uno temperature-controlled fan setup using a DHT11 sensor and 16x2 LCD to drive a DC fan
Sensor in, decision made, actuator out: the shape of every control project.

Parts List

From ShillehTek

External

  • A 5 V or 12 V brushless DC fan (a 2-wire PC case fan is perfect) and a matching power supply

Note: never drive a fan straight from an Arduino pin. Pins give 20-40 mA and a fan wants hundreds. The L298N takes the PWM signal on its enable pin and switches the fan's own supply. Use a 2-wire (or 3-wire, ignoring the tach wire) fan; 4-wire PWM fans have their own control input and want a 25 kHz signal instead.

Step-by-Step Guide

Step 1 - Wire Sensor, LCD and Knob

Goal: The inputs and the display.

What to do: DHT11: DATA → D2, VCC → 5V, GND → GND. I2C LCD: SDA → A4, SCL → A5, VCC → 5V, GND → GND. Potentiometer: outer pins to 5V and GND, wiper → A0.

Expected result: Three inputs on three pins, one display on the I2C bus.

Step 2 - Wire the Fan Through the L298N

Goal: Safe PWM power for the fan.

What to do: L298N: ENA → D9 (PWM), IN1 → D7, IN2 → D8, OUT1/OUT2 → fan wires (red to OUT1 for the polarity we will set), +12V terminal → fan supply positive (5-12 V), GND → supply negative AND Arduino GND. Remove the ENA jumper so D9 controls it. Leave the 5V-enable jumper on if your supply is 12 V; the board then makes its own logic 5 V.

Expected result: The fan spins only when the Arduino says so.

Step 3 - The Sketch

Goal: Read the DHT11, compute fan speed with hysteresis and proportional control, and show everything on the LCD.

Code:

#include <DHT.h>
#include <LiquidCrystal_I2C.h>
DHT dht(2, DHT11);
LiquidCrystal_I2C lcd(0x27, 16, 2);     // try 0x3F if the screen stays blank

const int POT = A0, ENA = 9, IN1 = 7, IN2 = 8;
const float BAND = 4.0;                 // degrees above set point for 100 % fan
const float HYST = 0.5;                 // fan turns off only 0.5 C below set point
bool fanOn = false;

void setup() {
  dht.begin(); lcd.init(); lcd.backlight();
  pinMode(ENA, OUTPUT); pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT);
  digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW);   // fixed direction
}

void loop() {
  float setPt = 15.0 + analogRead(POT) * 25.0 / 1023.0;   // knob: 15 ... 40 C
  float t = dht.readTemperature();
  float h = dht.readHumidity();
  if (isnan(t)) { lcd.setCursor(0, 0); lcd.print("DHT error       "); delay(2000); return; }

  // hysteresis: switch on above set point, off only below set point - HYST
  if (t >= setPt) fanOn = true;
  else if (t < setPt - HYST) fanOn = false;

  // proportional speed: 0 % at the set point, 100 % at set point + BAND
  int pct = 0;
  if (fanOn) pct = constrain((t - setPt) / BAND * 100.0, 25, 100);   // never below 25 % (fans stall)
  analogWrite(ENA, map(pct, 0, 100, 0, 255));

  lcd.setCursor(0, 0);
  lcd.print("T:"); lcd.print(t, 1); lcd.print("C H:"); lcd.print((int)h); lcd.print("% ");
  lcd.setCursor(0, 1);
  lcd.print("Set:"); lcd.print(setPt, 1); lcd.print(" Fan:"); lcd.print(pct); lcd.print("%  ");
  delay(2000);                          // DHT11 minimum interval
}

What to do: Install the Adafruit DHT library (plus Unified Sensor) and LiquidCrystal_I2C, upload, then turn the knob below the current room temperature.

Expected result: The LCD shows the temperature, humidity, set point and fan %. Dial the set point under room temperature and the fan starts; the further below, the faster it spins, until 100 % four degrees past the set point. Dial it above and the fan stops, but only once the temperature is half a degree under the set point, so it never flutters on the threshold.

Step 4 - Test the Control Loop

Goal: See it react.

What to do: Set the knob about 1 °C above room temperature. Cup the DHT11 in your hands for 30 seconds (it warms slowly; it is a slow sensor). Watch the fan start at 25 %, climb as the reading rises, then fall back and switch off after you let go and the reading drops through the hysteresis band.

Expected result: A controller that responds to temperature in proportion, not just on/off.

Step 5 - Make It a Real Appliance

Goal: From breadboard to useful.

What to do: Aim the fan at what you are cooling (a 3D-printer enclosure, a router shelf, a terrarium) and mount the DHT11 in the airflow's return path, not right in front of the fan. Swap the DHT11 for a DS18B20 or DHT22 for better resolution, or save the set point to EEPROM so it survives power loss. For a heater instead of a fan, flip the logic: turn on below the set point.

Expected result: A proportional thermostat you can drop into any project that gets too warm.

Conclusion

With an Arduino Uno, a DHT11, a set-point knob, hysteresis, and PWM (instead of a simple relay), you built a temperature controller that ramps a DC fan smoothly as conditions change. The same structure can be adapted for humidity control, heaters, pumps, and lighting by swapping the sensor and actuator.

Want the exact parts used in this build? Grab them from ShillehTek.com. If you want help customizing this project or building something for your product, check out our IoT consulting services.

Reference credit: this version is based on the original guide by ronfrtek on Hackster.io.

Parts for this build

Everything used in this tutorial. Uncheck what you already have.

All 9 in stock
0 parts selected $0.00