Nick Wegener
Published

Arduino PWM-Fan Control - Automatic and Manually

It's a PWM (fan) control which is controllable manually with a pot but can also be used automatically depending on the temp you measure.

IntermediateFull instructions provided2 hours5,809
Arduino PWM-Fan Control - Automatic and Manually

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
RGB Backlight LCD - 16x2
Adafruit RGB Backlight LCD - 16x2
×1
DHT11 Temperature & Humidity Sensor (3 pins)
DHT11 Temperature & Humidity Sensor (3 pins)
×1
Resistor 10k ohm
Resistor 10k ohm
×2
Multi-Turn Precision Potentiometer- 10k ohms (25 Turn)
Multi-Turn Precision Potentiometer- 10k ohms (25 Turn)
×2

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

First Prototype Pic1

Schematics of the layout

This is how you wire it all up!
Grey and Violet Cables are DATA only.
RED ones are for 5V and Black ones are for GND.

First Prototype Pic2

Code

Code without unnecessary comments for experienced tinkerer

Arduino
/*  
 *   PWM-Fan Controller
 *   Connect the 12V to the fan and the PWM Pins to it's
 *   PWM Pin. The Feedbackpin of the Fan goes to 5V through and 10kOhms
 *   Resistor. 
 *   You can find the layout on the feed of this Project on hackster.io
 *   
*/

#include <dht11.h>
#include <LiquidCrystal.h> 

                     
#define ctrl  A0
#define DHT1   2
#define pwm1   3
#define pwm2   5
#define pwm3   6
#define btn1   7                 //menucontrol
#define btn2   8                 //btn2=automatic
#define rpm0   9
#define rpm1  10
#define rpm2  11
 

      dht11 DHT11;
      
int check;
int ctrlval;
int pwm1val = 0;
int pwm2val = 0;
int pwm3val = 0;
int rpm0val = 0;
int rpm1val = 0;
int rpm2val = 0;

float temperature; 


int automatectrl = 0;
int fancontrolmenu = 0;
bool confirmed = false;
bool confirmedautomate = false;

const int rs = 12, en = 11, d4 = A1, d5 = A2, d6 = A3, d7 = A4;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup(){
  Serial.begin(9600);
    pinMode(ctrl,  INPUT);
    pinMode(btn1,  INPUT);
    pinMode(btn2,  INPUT);
    pinMode(pwm1, OUTPUT);
    pinMode(pwm2, OUTPUT);
    pinMode(pwm3, OUTPUT);
  
  lcd.begin(16,2);
  
    lcd.setCursor(0,0);
    lcd.print("Fan Control");
}

void menu(){
  ctrlval = analogRead(ctrl);

  confirmedautomate = false;
  confirmed = false;
  
  switch(fancontrolmenu){
    case 1:  
                  lcd.clear();
                  lcd.setCursor(0,0);
                    lcd.print("Fan Control");
                  lcd.setCursor(0,1);
                    lcd.print("Press Button 1");
             break;
    
    case 2:     
              confirmed = false;           
                pwm1val = ctrlval/4; 
                 lcd.clear();
                 lcd.setCursor(0,0);
                    lcd.print("Fan 1: ");
                    lcd.print(pwm1val);
                        delay(100);
                 lcd.clear();
             break;
             
    case 3:  
                pwm2val = ctrlval/4; 
                 lcd.clear();
                 lcd.setCursor(0,0);
                  lcd.print("Fan 2: ");
                  lcd.print(pwm2val);
                      delay(100);
                 lcd.clear();
             break;

    case 4: 
                pwm3val = ctrlval/4; 
                 lcd.clear();
                 lcd.setCursor(0,0);
                  lcd.print("Fan 3: ");
                  lcd.print(pwm3val);
                      delay(100);
                 lcd.clear();
             break;

    case 5: 
                lcd.clear();
                lcd.setCursor(0,0);
                   lcd.print("Confirm?");
                lcd.setCursor(0,1);
                   lcd.print("Press Button 1");
             break;

    case 6:    
                lcd.clear();
                lcd.setCursor(0,0);
                  lcd.print("Confirmed");
               confirmed = true;
             break;          
                     
  }
}
void automatepwm(){
    ctrlval = analogRead(ctrl);

    confirmedautomate = false;
    confirmed = false;
  
   switch(automatectrl){

     case 1: 
              lcd.clear();
             lcd.setCursor(0,0);
              lcd.print("Automate?");
              
             lcd.setCursor(0,1);
              lcd.print("Press btn2");
            break;                
              
     case 2:
          pwm1val = ctrlval/4;
            lcd.clear();
             lcd.setCursor(0,0);
              lcd.print("Fanspeed@35C+");

              lcd.setCursor(0,1);
               lcd.print(pwm1val);
            break;
            
     case 3:
          pwm2val = ctrlval/4;
            lcd.clear();
             lcd.setCursor(0,0);
              lcd.print("Fanspeed@50C+");

             lcd.setCursor(0,1);
              lcd.print(pwm2val);
            break;   

     case 4:
          pwm3val = ctrlval/4; 
            lcd.clear();
             lcd.setCursor(0,0);
              lcd.print("Fanspeed@60C+");

             lcd.setCursor(0,1);
              lcd.print(pwm3val);
            break;             

     case 5: 
             lcd.clear();
              lcd.setCursor(0,0);
               lcd.print("Confirm?");

              lcd.setCursor(0,1);
               lcd.print("Press btn2");

             confirmedautomate = true;
            break;
     }
}

void outputpwm(){
  analogWrite(pwm1, pwm1val);
  analogWrite(pwm2, pwm2val);
  analogWrite(pwm3, pwm3val);
    lcd.setCursor(0,0);
     lcd.print("OUTPUT");
   Serial.println("OUTPUTXXXXX");  
      
}

void autooutput(){

    if(temperature< 50){
      analogWrite(pwm1, pwm1val);
      analogWrite(pwm2, pwm1val);
      analogWrite(pwm3, pwm1val);
          Serial.println("temp@<50C");
    }
    else if(temperature>50 && temperature<60){
      analogWrite(pwm1, pwm2val);
      analogWrite(pwm2, pwm2val);
      analogWrite(pwm3, pwm2val);
           Serial.println("temp@>50C");
    }
    else if(temperature>60){
      analogWrite(pwm1, pwm3val);
      analogWrite(pwm2, pwm3val);
      analogWrite(pwm3, pwm3val);
           Serial.println("temp@>60C");
    }
}
void loop(){
  
  check = DHT11.read(DHT1);

  temperature = DHT11.temperature;
  
    if(digitalRead(btn1)==HIGH){
     delay(250);
      fancontrolmenu = fancontrolmenu+1;
    }

      if(fancontrolmenu > 6){
          fancontrolmenu = 0;
          lcd.clear();
        }
             
      else if(fancontrolmenu >= 1){  
           menu();
          Serial.println(pwm1val);
          Serial.println(pwm2val);
          Serial.println(pwm3val);
            Serial.println("---"); 
          Serial.println(fancontrolmenu);
            Serial.println("------------");
        }
      if(confirmed == true){
        outputpwm();      
      }
      
    if(digitalRead(btn2)==HIGH){
       delay(250);
        automatectrl = automatectrl+1;               
      }
     
        if(automatectrl <= 5){
               automatepwm();
            }
        else if(automatectrl > 5){
               automatectrl = 0; 
                lcd.clear();
            }
     
        if(confirmedautomate == true){
                autooutput();
             }
     
}

Code with comments to explain the code. It's made for tinker-rookies!

Arduino
/*  
 *   PWM-Fan Controller
 *   Connect the 12V to the fan and the PWM Pins to it's
 *   PWM Pin. The Feedbackpin of the Fan goes to 5V through and 10kOhms
 *   Resistor. 
 *   You can find the layout on the feed of this Project on hackster.io
 *   
*/
                                                                  //Here we include the used Librarys
#include <dht11.h>
#include <LiquidCrystal.h> 

                                                                  //These are the Pins used and connected to the Arduino                     
#define ctrl  A0
#define DHT1   2
#define pwm1   3
#define pwm2   5
#define pwm3   6
#define btn1   7                                                  //menucontrol
#define btn2   8                                                  //btn2=automatik
#define rpm0   9
#define rpm1  10
#define rpm2  11
 

      dht11 DHT11;
                                                                  //Initializing the for the manually control used integers      
int check;
int ctrlval;
int pwm1val = 0;
int pwm2val = 0;
int pwm3val = 0;
int rpm0val = 0;
int rpm1val = 0;
int rpm2val = 0;
                                                                  //Initializing the temperature Variable
float temperature; 

                                                                  //Here we initialize the Variables used for the menu
int automatectrl = 0;
int fancontrolmenu = 0;
bool confirmed = false;
bool confirmedautomate = false;
                                                                  //These two lines are for the pins of the LCD
const int rs = 12, en = 11, d4 = A1, d5 = A2, d6 = A3, d7 = A4;       //line1
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);                            //line2

                                                                  //Here the Serial begin for Serial Monitor, Input/Output modes for the pins and
                                                                  // the LCD get declared
void setup(){
  Serial.begin(9600);
    pinMode(ctrl,  INPUT);
    pinMode(btn1,  INPUT);
    pinMode(btn2,  INPUT);
    pinMode(pwm1, OUTPUT);
    pinMode(pwm2, OUTPUT);
    pinMode(pwm3, OUTPUT);
  
  lcd.begin(16,2);
  
    lcd.setCursor(0,0);
    lcd.print("Fan Control");
}
                                                                  //This function is only for the LCD-Menu OUTPUT and for the change from 1024 
                                                                  //steps of analog-Input from the pot into 256 steps of digital-PWM-Output
void menu(){
  ctrlval = analogRead(ctrl);

  confirmedautomate = false;
  confirmed = false;
  
  switch(fancontrolmenu){
    case 1:  
                  lcd.clear();
                  lcd.setCursor(0,0);
                    lcd.print("Fan Control");
                  lcd.setCursor(0,1);
                    lcd.print("Press Button 1");
             break;
    
    case 2:     
              confirmed = false;           
                pwm1val = ctrlval/4; 
                 lcd.clear();
                 lcd.setCursor(0,0);
                    lcd.print("Fan 1: ");
                    lcd.print(pwm1val);
                        delay(100);
                 lcd.clear();
             break;
             
    case 3:  
                pwm2val = ctrlval/4; 
                 lcd.clear();
                 lcd.setCursor(0,0);
                  lcd.print("Fan 2: ");
                  lcd.print(pwm2val);
                      delay(100);
                 lcd.clear();
             break;

    case 4: 
                pwm3val = ctrlval/4; 
                 lcd.clear();
                 lcd.setCursor(0,0);
                  lcd.print("Fan 3: ");
                  lcd.print(pwm3val);
                      delay(100);
                 lcd.clear();
             break;

    case 5: 
                lcd.clear();
                lcd.setCursor(0,0);
                   lcd.print("Confirm?");
                lcd.setCursor(0,1);
                   lcd.print("Press Button 1");
             break;

    case 6:    
                lcd.clear();
                lcd.setCursor(0,0);
                  lcd.print("Confirmed");
               confirmed = true;
             break;          
                     
  }
}

                                                                  //This function is for the menu and automating of the PWM-Output in relation 
                                                                  //to the measured temperature 
void automatepwm(){
    ctrlval = analogRead(ctrl);

    confirmedautomate = false;
    confirmed = false;
  
   switch(automatectrl){

     case 1: 
              lcd.clear();
             lcd.setCursor(0,0);
              lcd.print("Automate?");
              
             lcd.setCursor(0,1);
              lcd.print("Press btn2");
            break;                
              
     case 2:
          pwm1val = ctrlval/4;
            lcd.clear();
             lcd.setCursor(0,0);
              lcd.print("Fanspeed@35C+");

              lcd.setCursor(0,1);
               lcd.print(pwm1val);
            break;
            
     case 3:
          pwm2val = ctrlval/4;
            lcd.clear();
             lcd.setCursor(0,0);
              lcd.print("Fanspeed@50C+");

             lcd.setCursor(0,1);
              lcd.print(pwm2val);
            break;   

     case 4:
          pwm3val = ctrlval/4; 
            lcd.clear();
             lcd.setCursor(0,0);
              lcd.print("Fanspeed@60C+");

             lcd.setCursor(0,1);
              lcd.print(pwm3val);
            break;             

     case 5: 
             lcd.clear();
              lcd.setCursor(0,0);
               lcd.print("Confirm?");

              lcd.setCursor(0,1);
               lcd.print("Press btn2");

             confirmedautomate = true;
            break;
     }
}


                                                                  //In this function we just Output the PWM-Signal to the pins!
                                                                  //Not hard at all, isnt it? :)
void outputpwm(){
  analogWrite(pwm1, pwm1val);
  analogWrite(pwm2, pwm2val);
  analogWrite(pwm3, pwm3val);
    lcd.setCursor(0,0);
     lcd.print("OUTPUT");
   Serial.println("OUTPUTXXXXX");  
      
}

                                                                  //This function is called when we confirmed the choosen PWM-Values depending 
                                                                  //of the temperature and outputs the signal!
void autooutput(){

    if(temperature< 50){
      analogWrite(pwm1, pwm1val);
      analogWrite(pwm2, pwm1val);
      analogWrite(pwm3, pwm1val);
          Serial.println("temp@<50C");
    }
    else if(temperature>50 && temperature<60){
      analogWrite(pwm1, pwm2val);
      analogWrite(pwm2, pwm2val);
      analogWrite(pwm3, pwm2val);
           Serial.println("temp@>50C");
    }
    else if(temperature>60){
      analogWrite(pwm1, pwm3val);
      analogWrite(pwm2, pwm3val);
      analogWrite(pwm3, pwm3val);
           Serial.println("temp@>60C");
    }
}

                                                                  //This loop just checks everything. It's for changing between modes, changing the side
                                                                  //of the menu you are in and after you confirmed it it will call the functions which
                                                                  //will output your wished signal.
                                                                  //This is the Hearth of the code. So dont destroy it! ;)
                                                                  
void loop(){

  check = DHT11.read(DHT1);

  temperature = DHT11.temperature;
  
    if(digitalRead(btn1)==HIGH){
     delay(250);
      fancontrolmenu = fancontrolmenu+1;
    }

      if(fancontrolmenu > 6){
          fancontrolmenu = 0;
          lcd.clear();
        }
             
      else if(fancontrolmenu >= 1){  
           menu();
          Serial.println(pwm1val);
          Serial.println(pwm2val);
          Serial.println(pwm3val);
            Serial.println("---"); 
          Serial.println(fancontrolmenu);
            Serial.println("------------");
        }
      if(confirmed == true){
        outputpwm();      
      }
      
    if(digitalRead(btn2)==HIGH){
       delay(250);
        automatectrl = automatectrl+1;               
      }
     
        if(automatectrl <= 5){
               automatepwm();
            }
        else if(automatectrl > 5){
               automatectrl = 0; 
                lcd.clear();
            }
     
        if(confirmedautomate == true){
                autooutput();
             }
     
}

Credits

Nick Wegener

Nick Wegener

1 project • 1 follower
I am currently 19, and got into programming with 16. Based in Germany. You can contact me if you want to know anything about my projects!

Comments