arduino temperature fan speed control

Fan Speed Controlled by Temperature and Arduino

I made this project because I wanted a way to automatically control the speed of a DC fan according to the temperature read by a LM35 sensor. I had a few problems with the PWM part mainly because the fan made a disturbing noise so I had to add a simple RC filter at the output of the PWM pin on the Arduino board.

Schematic of the Automatic Fan Speed Controller

arduino temperature fan speed control

Arduino Sketch

LiquidCrystal lcd(7,6,5,4,3,2);
int tempPin = A1;   // the output pin of LM35
int fan = 11;       // the pin where fan is
int led = 8;        // led pin
int temp;
int tempMin = 30;   // the temperature to start the fan
int tempMax = 70;   // the maximum temperature when fan is at 100%
int fanSpeed;
int fanLCD;

void setup() {
  pinMode(fan, OUTPUT);
  pinMode(led, OUTPUT);
  pinMode(tempPin, INPUT);

void loop() {  
   temp = readTemp();     // get the temperature
   if(temp  < tempMin) { // if temp is lower than minimum temp 
      fanSpeed = 0; // fan is not spinning 
      digitalWrite(fan, LOW); 
   if((temp  >= tempMin) && (temp <= tempMax)) { // if temperature is higher than minimum temp 
      fanSpeed = map(temp, tempMin, tempMax, 32, 255); // the actual speed of fan 
      fanLCD = map(temp, tempMin, tempMax, 0, 100); // speed of fan to display on LCD 
      analogWrite(fan, fanSpeed); // spin the fan at the fanSpeed speed 
   if(temp  > tempMax) {        // if temp is higher than tempMax
     digitalWrite(led, HIGH);  // turn on led 
   } else {                    // else turn of led
     digitalWrite(led, LOW); 
   lcd.print("TEMP: ");
   lcd.print(temp);      // display the temperature
   lcd.print("C ");
   lcd.setCursor(0,1);   // move cursor to next line
   lcd.print("FANS: ");
   lcd.print(fanLCD);    // display the fan speed

int readTemp() {  // get the temperature and convert it to celsius
  temp = analogRead(tempPin);
  return temp * 0.48828125;

test setup

I used an LCD shield to display the current temperature and speed of the fan, but you can use the circuit without the LCD display. You also need to select the transistor by the type of fan that you use. In my case I used the well-known BD139 transistor and a 9V battery to provide power to the fan and transistor. The LM35 temperature sensor and red led are powered with 5V from the Arduino board.

How does the circuit works?

As you can see in the sketch on the first line I included the LiquidCrystal library (header) that includes useful functions to use when an LCD is connected to the Arduino board. Then I set the pins for the sensor, led and fan.

The most important part is to set the variables tempMin and tempMax with your desired values. tempMin is the temperature at which the fan starts to spin and tempMax is the temperature when the red led lights warning you that the maximum temp was reached. For example if you set tempMin at 30 and tempMax at 35 then the fan will start spinning at 30°C and reach its maximum speed at 35°C.

We store the temperature value in the temp variable and then use some if() functions to check if temp is lower than tempMin and if so let the fan OFF (LOW). The next if() is to check if temperature is higher than the minTemp and lower than the tempMax and if so then use the map() function to re-map the temp value from one value to another. In our case fanSpeed will have a value of 32 at tempMin and 255 at tempMax. These values are used to control the speed of the fan using PWM and the analogWrite().

The fanLCD re-maps the temp to allow the display of fanSpeed in a 0 to 100% range so you can say that the speed of the fan is directly dependent of the LM35’s temperature. When the temperature reaches the value set in tempMax the fan will be at its maximum spinning velocity and the LCD will display FANS: 100% even though the temperature might increase above tempMax.

The rest of the explanation can be read in the comments area of the Arduino sketch.

In the next project I will make a temperature protection circuit that will turn off the power of a equipment when its temperature has reached a certain value.


Related Products: Thermal Management | Fan Cooler


Join the conversation!

Error! Please fill all fields.
  • Steve_Robbins

    Just out of curiosity, what Arduino board are you running here?

  • ae_g

    The BD139 only have a hFE of about 40, are you still able to saturate it? Guess it can run a bit hot if not. I thought of using it driving a couple of leds but i think ill add a smaller transistor to get it to work like a darlington.

  • imalan54yahoo-com

    What type of capacitor is used in your circuit? It appears to be non polarized. This looks to be a great circuit to cool my power supply. Thanks for sharing.

  • gaba2kalanggmail-com

    What is the purpose of the transistor here?

  • fsmitkpnmail-nl

    Hello, this works great no questions there, but i have connected a 12v fan to this and it not runs on full speed, howto make this work for 12v fan instead of 9v ?
    Thank you, great project !!

  • imalan54yahoo-com

    I want to build this to use on my Bi-Polor power supply to keepit cool. Can u point me to a wirring diagram or tutorial for the LCD hook up? All I can find is ones that use pins 2,3,4,5,11, and 12. The code shows pins 2,3,4,5,6, and 7 is this the only pins used for the lcd, other than power and contrast?

  • imalan54yahoo-com

    I am very interested in this circuit to controll a cooling fan for a power supply. My fan is 12V at 0.30 A which is equal to 3.6 watts. What transistor would you recamend?

    • T.K.Hareendran

      You can drive your 80mm/120mm fan (even its rating is higher than 0.3 A @12V) without changing any components in the circuit. Author used BD139 here,capable of handling collector current upto 1.5A (typical). Else, try the TO-18 package 2N2222 (collector current 0.8A).

      This is only a suggestion from me. Hope the author may come up with his own solution.

  • sandbirdgmail-com

    Hi, great guide! I wanted to do something similar to cool my router that is sitting inside a box on the balcony during the summer. I have an arduino pro micro (5v) already set up with a dht22 sensor. Currently i have a 5v mini fan (similar to the ones we use inside pcs).
    Do i need the db139 for that ? I mean the Pro micro has 5v output. Is it really necessary ? I am guessing the 1N4007 and the capacitor are there to protect the arduino. I just dont get why the db139 is needed.(yes i am a total noob :P)

    • sandbirdgmail-com

      Thanks for answering. I created a filter for the PWM as i noticed the sound you mentioned. Unfortunately i dont have a BD139, but i had a 2N3904. Can i use that instead ? I did a small test and seems to work fine with it.

    • P. Marian

      The diode is to protect the transistor and the capacitor is used to filter the PWM signal coming from the Arduino board. BD139 is used because the fan that I used requires 12V and 100 mA, so a total power dissipation of 1,2W

  • mohsinus1992gmail-com

    I am trying to connect the JHD 162A LCD DISPLAY CAN YOU PLZ help me how to connect it properly. I tried to connect the it by looking at the Manuel but its not working. I am going to attach the the file thats what i am getting. can anyone help plz?

  • lchartshotmail-com

    Just for anyone who might have the same trouble as me: fans just vibrate and don’t move no matter how much base current you put into the transister. Spent ages trying to fix this, turned out my power supply ground and arduino ground were not connected, so my voltages weren’t reference to the same point -_-

Looking for the latest from TI?