Build a temperature-controlled desk fan

Print fan blades and a motor stand, then let a DS18B20 thermometer decide how fast the fan spins. A knob sets the temperature where it starts.
  • Level:Intermediate
  • Duration: 1 h
  • Ages 11+
  • Platform: Arduino

Tools for this lesson

Helpful for this build. Open a tool to see tips and more projects that use it.

Build a temperature-controlled desk fan – EEMENTOR STEM™ lesson

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

Breadboard wiring diagram: Build a temperature-controlled desk fan
Breadboard view. Check each connection against the wiring table below.
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

  1. 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.
  2. Hold the DS18B20 between your fingers. As it warms up, the fan speeds up.
  3. 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 SLOWEST bigger (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.

Build it yourself

Everything used in this lesson comes in one kit, with parts tested by our engineers.

UNO R3 Starter Kit | Arduino IDE Compatible | Free Tutorials $56.00

Shop the kit