Temperature controlled fan using PIC 16F877A

Temperature-controlled-fan-pic-16f877a-microcontroller-dc-motor
Temperature Controlled DC motor

You might have come across several applications where we need to control a specific device based on analog parameter. This Embedded system works in a similar concept where we are about to control the speed of a DC motor using based on the external temperature. The rise in temperature will result in increase in speed of the motor and vice versa. These type of Temperature controlled fan systems can generally be used to maintain temperature of a room or object automatically.

 DESIGN OF TEMPERATURE CONTROLLED FAN SYSTEM:

  • The temperature is measured by means of a temperature sensor LM35.
  • The output voltage of the sensor is fed to the A/D channel of the Microcontroller.
  • Based on the sensed temperature the speed of the motor is controlled using PWM .
  • Several temperature ranges was set in the code to vary the motor speed based on the level of temperature sensed.
  • The speed of the motor is controlled by using PWM.
  • The motor is driven using a driver IC l293D, See a brief explanation on its working and wiring here.

LM35:

LM35-pin-diagram-temperature-sensor
LM35 Pin Diagram

Lm 35 is used to sense the external temperature which is capable of sensing temperature ranges from -55 to 150 C. The output voltage is proportional to the temperature hence there is no need of trimmers to calibrate the reading. The output voltage of this sensor varies by 10mv per degree change in temperature.

CALIBRATION:

We are using a 10 bit ADC and Vcc as Vref to the ADC module of the Controller. So in order to determine the step size we have to divide the Vref by our resolution that is 2^10 ( 1024 ).

Step Size = 5 / 1024 = 4.83mV

We obtain a change of 10mV with each rise or fall in temperature from the sensor. And value in the ADC register will alter by two steps with each degree change in the sensor since two increments of step size i.e 4.833mV * 2 = 9.96mV which is approximately equal to 10mV. So in order to obtain the original value we have to divide the contents in the ADC register by 2

Real value = ADC value / 2

CODE:

This code was built using CCS compiler for PIC Microcontrollers.

#include <16F877A.h>
#device ADC=10                              //Setting ADC bits
#FUSES NOWDT               
#FUSES NOBROWNOUT          
#FUSES NOLVP                
#use delay(crystal=20000000)
#byte lcd=0x08
#byte TRIS_lcd=0x88
#bit rs=0x06.2
#bit en=0x06.3
#bit TRIS_rs=0x86.2
#bit TRIS_en=0x86.3
long int adc_value,real_value;        
int i;
char value[4];
unsigned char text[]="Temperature:";
void display(unsigned char a, int b);
void motor();
void main()
{
  TRIS_lcd=TRIS_rs=TRIS_en=0;
  display(0x38,0);
  display(0x01,0);
  display(0x0c,0);
    for(i=0;i<=12;i++)
    {
     display(text[i],1); 
    }
  setup_timer_2(T2_DIV_BY_16,255,1);    //Setting timers for PWM      
  SETUP_ADC_PORTS(AN0);                   //Setting ADC PORTS
  SET_ADC_CHANNEL(0);                       //Selecting Channel
  SETUP_ADC(ADC_CLOCK_INTERNAL);
     while(TRUE)
      {
        delay_us(20);
        adc_value=READ_ADC();            //Reading ADC value
        delay_us(10);
        real_value=adc_value/2;           //Obtaining real value
        motor();
        sprintf(value,"%lu",real_value);  //Changing int to char
        display(0x8c,0);
          for(i=0;i<=3;i++)
           {
             display(value[i],1);
           }   
      }
 }
void display(unsigned char a,int b)         //LCD sub routine
  {
    lcd=a;
    rs=b;
    en=1;
    delay_ms(10);
    en=0;
    delay_ms(10);
  }
 
void motor()
{
  if(real_value<10)
   {
   setup_ccp1(CCP_OFF);             
   }
  if(real_value>10)
   {
     setup_ccp1(CCP_PWM);
      if(real_value>=10&&real_value<=29)
      {
        set_pwm1_duty((int16)204);         //20% duty cycle PWM
      }
      else if(real_value>=30&&real_value<=69)
     {
       set_pwm1_duty((int16)510);         //50% duty cycle PWM 
      }
      else if(real_value>=70&&real_value<=99)
      {
         set_pwm1_duty((int16)715);      //70% duty cycle PWM
       }
      else if(real_value>=100&&real_value<=150)
       {
         set_pwm1_duty((int16)919);     //90% duty cycle PWM
       }
    }
 }

The above code uses built in functions in the CCS compiler to use the A/D and PWM feature in the Microcontroller. The received analog value is calibrated to display the temperature in the LCD. The “real_value” int value is converted to character using “sprintf” in order to display the temperature values.

The temperature ranges and duty cycle of the PWM is given using the subroutine “.motor”. So the microcontroller runs a check on the temperature every time and alters the speed of the motor based on it.


99 Comments

  1. Anonymous

    Firstly, why we need 12V for L293D and i set up circuit it works but fan speed doesnt change anytime, what is the problem i didn’t get.

    Reply
    1. Frank DonaldFrank Donald (Post author)

      If your DC fan is rated 12v then you need to supply 12v for L293D. Basically you supply L293D equivalent to your DC motor rating

      Reply
  2. Anonymous

    The resistor in the circuit diagram is that potentiometer ??

    Reply
    1. Frank DonaldFrank Donald (Post author)

      Yes it is

      Reply
  3. Dila

    I compile this coding on MPLAB but it fail. Can you please tell me why?

    Reply
    1. Frank DonaldFrank Donald (Post author)

      It is because this code was compiled using CCS compiler

      Reply
      1. Anonymous

        may I know what all other requirements for getting the code run on mplab too

        Reply
        1. Frank DonaldFrank Donald (Post author)

          As far as I know, MPLAB uses its own set of libraries and I would suggest you to understand this and write your own in MPLAB.

          Reply
  4. Syafiqah

    How to include the speed of fan in coding? I have tried many time. Can you help me sir.

    Reply
    1. Frank DonaldFrank Donald (Post author)

      Hi Syafiqah,
      I am not sure whether you can determine the speed at which this DC motor runs using the code. The challenge lies in determining its position and I don’t see any way to find it without using any external gadgets or devices.

      Reply
  5. solomon kassahun

    how the code will look like using mikroc compiler please show me if you can.

    Reply
  6. Maha Medhat

    Is this project use the Memory feature or the EEPROM feature ???
    And if yes would you please explain it briefly ????

    Reply
    1. Frank DonaldFrank Donald (Post author)

      Maha,

      Please clarify your question couldn’t get you

      Reply
      1. Maha Medhat

        what are the modules used in this project ?

        Reply
        1. Frank DonaldFrank Donald (Post author)

          Maha,
          LCD, L293D and PIC controller, LM35 and Motor are the ones used. There is no need of EEPROM as we are not doing any data logging of the temperature.

          Reply
  7. NIYA SHARMA

    Our purpose in this project is to sense the temperature and show it on LCD display and to varying the DC fan speed accordingly by using PIC16F877A microcontroller.(by presetting the speed of fan with temperature).

    Reply
    1. Syafiqah

      Hi niya. Did you get the answer because my project same with you.

      Reply
      1. Frank DonaldFrank Donald (Post author)

        Hi Niya and Syafiqah,
        If I understand your question right. I think this project works exactly as per your requirement. Kindly elaborate the question.

        Reply
  8. Melric

    I can only see on the LCD the temperature but i did not see the speed of the fan.

    Reply
    1. Frank DonaldFrank Donald (Post author)

      Melric,

      Only the temperature of the fan was added in the code. Speed of fan was not included.

      Reply
      1. Syafiqah

        How to include the speed of fan in coding? I have tried many time. Can you help me sir.

        Reply
  9. Melric

    THANK YOU FOR THE SCHEMATIC I FINALLY MAKE IT WORKING 😀

    Reply
    1. Frank DonaldFrank Donald (Post author)

      Melric,
      Great, happy to hear that 🙂

      Reply
    2. syaf

      hi Melric,
      i have tried the circuit in breadboard but my project not function. i think have wrong connection in the circuit. can you help me for the true connection of the project?

      Reply
      1. Frank DonaldFrank Donald (Post author)

        Hi Syaf,

        Would you mind posting the connection you have made. There might be some error.

        Reply
  10. Melric

    did I need to put crystal ossiciliator on the circuit ?

    Reply

Leave a Comment

Your email address will not be published. Required fields are marked *