Controlling fan speed with a PIC

Discussion in 'Programmer's Corner' started by Juf, Mar 21, 2010.

  1. Juf

    Thread Starter New Member

    Mar 21, 2010
    1
    0
    Hey guys,
    I bought this kit and it works pretty nicely.:D

    I'm now trying to make it so that at certain temperatures different fan speeds would go off.
    Code ( (Unknown Language)):
    1.  
    2.     if(tempA>300&&tempA<400) { //300 equals 30°C
    3.  //set speed
    4. }else if(tempA>=400){
    5. //set speed 2
    6.                 }
    The kit I bought is below

    http://tinyurl.com/yf7dngw

    and here is the C source
    Code ( (Unknown Language)):
    1. //==========================================================================
    2. //    Author                : Cytron Technologies        
    3. //    Project                : Temperature Control System using LM35
    4. //    Project description    : This project will use PIC16F876A to control NPN power transistor (BD135)
    5. //                          further drive DC brushless fans, LEDs and buzzer when the certain
    6. //                          temperature was detected.
    7. //==================inckude=================================
    8. #include<pic.h>
    9.  
    10. //===============configuration==============================
    11. __CONFIG (0x3F32);
    12.  
    13. //==========define IO port=========
    14. #define        lcd            PORTC
    15. #define        RS            RA2
    16. #define        E            RA5
    17. #define        CHANNEL0    0b10000001    // AN0
    18. #define        CHANNEL1    0b10001001    // AN1
    19. #define        buzzer        RB5
    20. #define        fanA        RB4
    21. #define        fanB        RB3
    22. #define        ledA        RB2
    23. #define        ledB        RB1
    24.  
    25. //==============FUNCTION PTOTOTYPE==============
    26. void e_pulse(void);
    27. void delay(unsigned short i);
    28. void send_char(unsigned char data);
    29. void send_config(unsigned char data);
    30. void lcd_goto(unsigned char data);
    31. void lcd_clr(void);
    32. void dis_num(unsigned long data);
    33. void increment(unsigned long data);
    34. void read_adc(void);
    35. unsigned short read_temp(void);
    36.  
    37. unsigned short result;
    38. unsigned short temp,tempA,tempB;
    39.  
    40. void main(void)
    41. {
    42.     ADRESH=0;                    //clear A/D result
    43.     ADRESL=0;                    //clear A/D result
    44.  
    45.     //setting ADCON1 Register
    46.     ADCON1=0b11000101;            // A/D result right justified,                
    47.                                 // configure RA2 and RA5 as digital I/O
    48.  
    49.     TRISA=0b11011011;            //configure PORTA I/O direction
    50.     TRISB=0b00000000;            //configure PORTB as output
    51.     TRISC=0b00000000;            //configure PORTC as output
    52.  
    53.     PORTA=0;
    54.     PORTB=0;
    55.    
    56.     while(1)                    
    57.     {
    58.         send_config(0b00000001);        //clear display at lcd
    59.         send_config(0b00000010);        //Lcd Return to home
    60.         send_config(0b00000110);        //entry mode-cursor increase 1
    61.         send_config(0b00001100);        //diplay on, cursor off and cursor blink off
    62.         send_config(0b00111000);        //function set
    63.        
    64.         lcd_goto(0);                    //cursor start from beginning
    65.        
    66.         //display character on LCD
    67.         send_char(' ');
    68.         send_char('T');
    69.         send_char('E');
    70.         send_char('M');
    71.         send_char('P');
    72.         send_char('.');
    73.         send_char('A');
    74.         send_char('=');    
    75.  
    76.         lcd_goto(20);                    //cursor go to 2nd line of the LCD
    77.  
    78.         //display character on LCD
    79.         send_char(' ');
    80.         send_char('T');
    81.         send_char('E');
    82.         send_char('M');
    83.         send_char('P');
    84.         send_char('.');
    85.         send_char('B');
    86.         send_char('=');    
    87.  
    88.         while(1)                        //infinity loop
    89.         {
    90.         //sensor A
    91.         ADCON0=CHANNEL0;                //CHANNEL1=0b10001001
    92.         lcd_goto(8);
    93.                
    94.         read_adc();
    95.  
    96.         temp=read_temp();
    97.         dis_num(temp/10);
    98.         send_char('.');
    99.         dis_num(temp%10);
    100.         send_char(0b11011111);
    101.         send_char('C');
    102.         send_char(' ');
    103.         send_char(' ');
    104.        
    105.         tempA=temp;
    106.        
    107.         //sensor B
    108.         ADCON0=CHANNEL1;                //CHANNEL0=0b10000001            
    109.  
    110.         lcd_goto(28);
    111.                
    112.         read_adc();
    113.  
    114.         temp=read_temp();
    115.         dis_num(temp/10);
    116.         send_char('.');
    117.         dis_num(temp%10);
    118.         send_char(0b11011111);
    119.         send_char('C');
    120.         send_char(' ');
    121.         send_char(' ');
    122.  
    123.         tempB=temp;
    124.    
    125.             if((tempA>400)&&(tempB<350))        //    *****************************************
    126.                 {                                //    *    LED A and Fan A activated only for     *
    127.                     ledA=1;                        //    *    temperature A greater than 40'C        *
    128.                     ledB=0;                        //    *    and temperature B less than 35'C    *
    129.                     fanA=1;                        //    *****************************************
    130.                     fanB=0;
    131.                     buzzer=0;
    132.                 }    
    133.  
    134.             else if((tempB>350)&&(tempA<400))     //    *****************************************
    135.                 {                                //    *    LED B and Fan B activated only for     *
    136.                     ledA=0;                        //    *    temperature A less than 40'C and    *
    137.                     ledB=1;                        //    *    temperature B greater than 35'C        *
    138.                     fanA=0;                        //    *****************************************
    139.                     fanB=1;
    140.                     buzzer=0;
    141.                 }    
    142.  
    143.             else if((tempB>350)&&(tempA>400))     //    *****************************************************
    144.                 {                                //    *    All LED A & LED B, Fan A & Fan B and Buzzer        *
    145.                     ledB=1;                        //    *    activated for temperature A greater than 40'C    *
    146.                     ledA=1;                        //    *    and temperature B greater than 35'C                *
    147.                     fanA=1;                        //    *****************************************************
    148.                     fanB=1;
    149.                     buzzer=1;
    150.                 }    
    151.  
    152.             else if((tempB<350)&&(tempA<400))    //    *****************************************************
    153.                 {                                //    *    All LED A & LED B, Fan A & Fan B and Buzzer        *
    154.                     ledB=0;                        //    *    disactivated for temperature A less than 40'C    *
    155.                     ledA=0;                        //    *    and temperature B less than 35'C                *
    156.                     fanA=0;                        //    *****************************************************
    157.                     fanB=0;
    158.                     buzzer=0;
    159.                 }    
    160.  
    161.         delay(2000);
    162.    
    163.         }
    164.    
    165.     }
    166.        
    167. }
    168.        
    169.                    
    170.  
    171. //==================subroutine LCD setting ==========================
    172.  
    173. void send_config(unsigned char data)
    174. {
    175.      RS=0;
    176.     lcd=data;
    177.     delay(500);
    178.     e_pulse();
    179. }
    180.  
    181. void e_pulse(void)
    182. {
    183.     E=1;
    184.     delay(500);
    185.     E=0;
    186.     delay(500);
    187. }
    188.  
    189. void send_char(unsigned char data)
    190. {
    191.      RS=1;
    192.     lcd=data;
    193.     delay(500);
    194.     e_pulse();
    195. }
    196.  
    197.  
    198. void lcd_goto(unsigned char data)
    199. {
    200.      if(data<16)
    201.     {
    202.          send_config(0x80+data);
    203.     }
    204.     else
    205.     {
    206.          data=data-20;
    207.         send_config(0xc0+data);
    208.     }
    209. }
    210.  
    211.  
    212. void lcd_clr(void)
    213. {
    214.     RS=0;
    215.      send_config(0x01);
    216.     delay(600);    
    217. }
    218.  
    219.  
    220. void dis_num(unsigned long data)
    221. {
    222.     unsigned char hundred_thousand;
    223.     unsigned char ten_thousand;
    224.     unsigned char thousand;
    225.     unsigned char hundred;
    226.     unsigned char tenth;
    227.  
    228.     hundred_thousand = data/100000;                    
    229.     data = data % 100000;
    230.     ten_thousand = data/10000;
    231.     data = data % 10000;
    232.     thousand = data / 1000;
    233.     data = data % 1000;
    234.     hundred = data / 100;
    235.     data = data % 100;
    236.     tenth = data / 10;
    237.     data = data % 10;
    238.  
    239.     if(hundred_thousand>0)
    240.     {
    241.         send_char(hundred_thousand + 0x30);    //0x30 added to become ASCII code
    242.         send_char(ten_thousand + 0x30);
    243.         send_char(thousand + 0x30);
    244.         send_char(hundred + 0x30);
    245.         send_char(tenth + 0x30);
    246.         send_char(data + 0x30);
    247.     }
    248.  
    249.     else if(ten_thousand>0)
    250.     {
    251.         send_char(ten_thousand + 0x30);    //0x30 added to become ASCII code
    252.         send_char(thousand + 0x30);
    253.         send_char(hundred + 0x30);
    254.         send_char(tenth + 0x30);
    255.         send_char(data + 0x30);
    256.     }
    257.     else if(thousand>0)
    258.     {
    259.          send_char(thousand + 0x30);    //0x30 added to become ASCII code
    260.         send_char(hundred + 0x30);
    261.         send_char(tenth + 0x30);
    262.         send_char(data + 0x30);
    263.     }
    264.     else if(hundred>0)
    265.     {
    266.          send_char(hundred + 0x30);    //0x30 added to become ASCII code
    267.         send_char(tenth + 0x30);
    268.         send_char(data + 0x30);
    269.     }
    270.     else if(tenth>0)
    271.      {
    272.         send_char(tenth + 0x30);    //0x30 added to become ASCII code
    273.         send_char(data + 0x30);
    274.     }
    275.     else send_char(data + 0x30);    //0x30 added to become ASCII code
    276. }
    277.  
    278. void increment(unsigned long data)
    279. {    
    280.     unsigned short j;
    281.     for(j=10;j>0;j--)
    282.     {    lcd_goto(32);
    283.         data=data+1;
    284.         dis_num(data);
    285.         delay(10000);
    286.     }
    287.  
    288. }
    289.  
    290. //==================subroutine ADC=========================
    291.  
    292. void read_adc(void)
    293. {
    294.     unsigned short i;
    295.     unsigned long result_temp=0;
    296.     for(i=2000;i>0;i-=1)            //looping 2000 times for getting average value
    297.     {
    298.         ADGO = 1;                    //ADGO is the bit 2 of the ADCON0 register
    299.         while(ADGO==1);                //ADC start, ADGO=0 after finish ADC progress
    300.         result=ADRESH;
    301.         result=result<<8;            //shift to left for 8 bit
    302.         result=result|ADRESL;        //10 bit result from ADC
    303.  
    304.         result_temp+=result;        
    305.     }
    306.     result = result_temp/2000;        //getting average value
    307.  
    308. }
    309.  
    310. unsigned short read_temp(void)
    311. {
    312.     unsigned short temp;
    313.     temp=result;
    314.     return temp;
    315.  
    316. }
    317.  
    318.  
    319. void delay(unsigned short i)
    320. {    
    321.     for(;i>0;i--);
    322. }
    323.  
    324.  
    How do I change it from just turning on the fan to controling the fan speed?
     
  2. Tahmid

    Active Member

    Jul 2, 2008
    344
    25
    Hi,
    For changing fan speed, use PWM.
    For mikroBASIC in say 18F452, something like this can be done:
    Code ( (Unknown Language)):
    1. program FanSpeedTemp
    2. dim ADRead as word
    3. const Temp30 61
    4. main:
    5.    TRISC = 0
    6.    TRISA = 0xFF
    7.    PWM_Init(5000) 'Set PWM frequency at 5kHz
    8.    PWM_Set_Duty(128) 'Set PWM duty cycle at 50%
    9.    PWM_Start() 'Start PWM
    10.    while true
    11.       ADRead = ADC_Read(0)
    12.       if ADRead > Temp30 then 'If ADC reads a temp value greater than 30'C
    13.          PWM_Set_Duty(192) '75% duty cycle
    14.       else
    15.          PWM_Set_Duty(64) '25% duty cycle
    16.       end if
    17.    wend
    18. end.
    19.  
    Code ( (Unknown Language)):
    1. Set Duty cycle as:
    2. PWM_Set_Duty(val)
    3. val = Required duty cycle * 256
    4. So, for 90%, val = 0.9 * 256 = 230
    Hope this helps.
    Tahmid.
     
Loading...