Air conditioners and computer fans don't just switch on and off: they speed up as it gets warmer. In this lesson you build a desk fan that does the same. A DS18B20 thermometer measures the room, a knob sets the temperature where the fan starts, and the L293D motor driver changes the motor speed with PWM. Above the start temperature the fan begins slowly and reaches full speed 6 °C higher.
What you'll learn
- How a motor driver lets the UNO control a motor safely
- How to change a motor's speed with PWM
- How to make the output grow with the input between two limits
- Why motors need a "kick" to start at low speed
What you need
- UNO R3 board and USB cable (UNO R3 Starter Kit)
- 3–6 V DC motor and L293D motor driver (UNO R3 Starter Kit)
- 10 kΩ potentiometer (UNO R3 Starter Kit)
- DS18B20 temperature module (45-in-1 Sensor Kit)
- The printed parts from the 3D printing box below (fan blades and motor stand), or the cardboard version described there
- Breadboard and jumper wires (UNO R3 Starter Kit)
Wiring

| From | To |
|---|---|
| L293D pin 1 (EN1) | UNO pin 5 |
| L293D pin 2 (IN1) | UNO pin 7 |
| L293D pin 7 (IN2) | UNO pin 8 |
| L293D pins 3 and 6 (OUT1, OUT2) | The two motor terminals |
| L293D pins 4, 5, 12 and 13 | GND |
| L293D pins 8 and 16 (VCC2, VCC1) | 5V |
| DS18B20 module S | UNO pin 4 |
| DS18B20 module + and − | 5V and GND |
| Potentiometer outer pins | 5V and GND |
| Potentiometer middle pin | UNO pin A0 |
The L293D has a notch at one end. With the notch on the left, pin 1 is bottom left and the pins are counted anticlockwise. The chip sits across the middle gap of the breadboard.
Sensor modules from different makers can label and order their pins differently. Always follow the labels printed on your module.
Safety: keep fingers, hair and cables away from the blades while the fan runs. The fan is powered from USB, so it is gentle, but the blades can still flick.
The sketch
In the Arduino IDE, open Library Manager and install OneWire and DallasTemperature (by Miles Burton).
#include <OneWire.h>
#include <DallasTemperature.h>
const int EN_PIN = 5; // speed (PWM)
const int IN1_PIN = 7; // direction
const int IN2_PIN = 8;
const int KNOB_PIN = A0;
const float RANGE = 6.0; // full speed this many degrees above the start temperature
const int SLOWEST = 110; // lowest PWM that still turns the fan
OneWire oneWire(4);
DallasTemperature thermometer(&oneWire);
int speed = 0;
void setSpeed(int newSpeed) {
if (speed == 0 && newSpeed > 0) {
analogWrite(EN_PIN, 255); // a short kick to get the motor going
delay(300);
}
speed = newSpeed;
analogWrite(EN_PIN, speed);
}
void setup() {
Serial.begin(9600);
pinMode(EN_PIN, OUTPUT);
pinMode(IN1_PIN, OUTPUT);
pinMode(IN2_PIN, OUTPUT);
digitalWrite(IN1_PIN, HIGH); // always the same direction
digitalWrite(IN2_PIN, LOW);
thermometer.begin();
}
void loop() {
thermometer.requestTemperatures();
float celsius = thermometer.getTempCByIndex(0);
if (celsius == DEVICE_DISCONNECTED_C) {
Serial.println("Thermometer not found");
setSpeed(0);
delay(1000);
return;
}
// the knob sets the start temperature: 18 to 30 degrees
float start = 18.0 + analogRead(KNOB_PIN) * 12.0 / 1023.0;
int newSpeed = 0;
if (celsius >= start) {
float share = constrain((celsius - start) / RANGE, 0.0, 1.0);
newSpeed = SLOWEST + share * (255 - SLOWEST);
}
setSpeed(newSpeed);
Serial.print(celsius, 1);
Serial.print(" °C, starts at ");
Serial.print(start, 1);
Serial.print(" °C, speed ");
Serial.print(speed * 100 / 255);
Serial.println(" %");
delay(1000);
}
Try it
- Open the Serial Monitor at 9600 baud. Turn the knob until the start temperature is a little below the room temperature: the fan starts slowly.
- Hold the DS18B20 between your fingers. As it warms up, the fan speeds up.
- Turn the knob up again and the fan stops.
How it works
The UNO's pins can only give about 20 mA, much too little for a motor, and the motor's electrical noise could reset the board. The L293D is a motor driver: it switches the motor's bigger current from the 5V supply, while the UNO only sends it small signals. IN1 and IN2 choose the direction, and the PWM on EN1 sets the speed.
The speed is worked out as a share of the range: 0 at the start temperature, 1 at 6 °C above it, and constrain() keeps it between those limits. A motor needs more power to start than to keep turning, so when the fan is standing still setSpeed() gives it full power for 300 ms first. Without that kick, a slow speed would just make the motor hum.
Try this next
- Add a button that switches between automatic and "always on".
- Add the 1602 LCD to show the temperature and the speed.
- Use the ESP32 instead and set the start temperature from a web page, like in the web-controlled fan.
Troubleshooting
-
The motor hums but doesn't turn: make
SLOWESTbigger (try 140). - The fan blows the wrong way: swap the two motor wires, or turn the blades round.
- "Thermometer not found": check the S wire on pin 4 and the module's power pins.
- The UNO resets when the motor starts: use a good USB port, and check that pins 4, 5, 12 and 13 of the L293D are all on GND.
- A printed part is too tight or too loose: printers differ by a few tenths of a millimetre. Sand or file a tight hole, and fix a loose part with a drop of hot glue or a strip of tape.