NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » Fan control troubleshooting

January 12, 2012
by Jacp
Jacp's Avatar

Hello.

I have got this little project where I want to control a fan using an LM34 temp sensor and a computer fan with model number : ASB0912L. I used a 2N7000 mosfet transistor as a switch.

I want my fan to run at 35% duty cyle when the temperature is above 77 fahrenheit and to run at 0% duty cycle when temperature is equal to or less then 77 fahrenheit. I tried using the code below but the fan keeps running all the time.

Anyone got a solution?

My code:

    // fan_controller.c
    // for NerdKits with ATmega168

    #define F_CPU 14745600
    #define PWM_fanspeed_2 12915 //For 7ms high time = 35% duty cycle
    #define PWM_fanspeed_START 0

    #include <stdio.h>
    #include <math.h>

    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/pgmspace.h>
    #include <inttypes.h>

    #include "../libnerdkits/delay.h"
    #include "../libnerdkits/lcd.h"
    #include "../libnerdkits/uart.h"

    // PIN DEFINITIONS:
    //
    // PC0 -- temperature sensor analog input
    //Denne funksjonen velger sammenlingningsverdien til telleren
    void pwm_set(uint16_t x) {
      OCR1B = x;
    }

    //Denne funksjonen setter opp instillingene for FAST PWM mode 15
    void pwm_init(){

        //Setter perioden til å være 20 ms  
        OCR1A = 36864;

        //Setter servoen til midtposisjon
        pwm_set(PWM_fanspeed_START);
        /*
        //Har under skrevet til to ulike registre for å aktivere dei forskjellige instillingene
        //Skriver til registeret TCCR1B for å sette opp prescaleren til 8.
        TCCR1B = (1<<CS11);
        // WGM13, WGM12, WGM11, WGM10 -- for Fast PWM with OCR1A as TOP value //Setter videre opp til Waveform generation mode 15
        TCCR1B = (1<<WGM13);
        TCCR1B = (1<<WGM12);

        TCCR1A = (1<<WGM11);
        TCCR1A = (1<<WGM10);

         // COM1B1 -- for non-inverting output
        TCCR1A = (1<<COM1B1);
        */
         TCCR1A = (1<<COM1B1) | (1<<WGM11) | (1<<WGM10);
        TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS11);
    }

    void adc_init() {
      // set analog to digital converter
      // for external reference (5v), single ended input ADC0
      ADMUX = 0;

      // set analog to digital converter
      // to be enabled, with a clock prescale of 1/128
      // so that the ADC clock runs at 115.2kHz.
      ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);

      // fire a conversion just to get the ADC warmed up
      ADCSRA |= (1<<ADSC);
    }

    uint16_t adc_read() {
      // read from ADC, waiting for conversion to finish
      // (assumes someone else asked for a conversion.)
      // wait for it to be cleared
      while(ADCSRA & (1<<ADSC)) {
        // do nothing... just hold your breath.
      }
      // bit is cleared, so we have a result.

      // read from the ADCL/ADCH registers, and combine the result
      // Note: ADCL must be read first (datasheet pp. 259)
      uint16_t result = ADCL;
      uint16_t temp = ADCH;
      result = result + (temp<<8);

      // set ADSC bit to get the *next* conversion started
      ADCSRA |= (1<<ADSC);

      return result;
    }

    double sampleToFahrenheit(uint16_t sample) {
      // conversion ratio in DEGREES/STEP:
      // (5000 mV / 1024 steps) * (1 degree / 10mV)
      //    ^^^^^^^^^^^      ^^^^^^^^^^
      //     from ADC         from LM34
      return sample * (5000.0 / 1024.0 / 10.0);  
    }

    int main() {

    //Nye variabler
    uint16_t pos = PWM_fanspeed_START;

    //////Koblinger
        // Set PB2 as output
        DDRB |= (1<<PB2);// | (1<<PB3);

        /////Utførelser
         // Start PWM
        pwm_init();

      // start up the LCD
      lcd_init();
      FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
      lcd_home();

      // start up the Analog to Digital Converter
      adc_init();

      // start up the serial port
      uart_init();
      FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
      stdin = stdout = &uart_stream;

      // holder variables for temperature data
      uint16_t last_sample = 0;
      double this_temp;
      double temp_avg;
      uint8_t i;
      double temp;

      while(1) {
        // take 100 samples and average them!
        temp_avg = 0.0;
        temp = 0.0;
        for(i=0; i<100; i++) {
          last_sample = adc_read();
          this_temp = sampleToFahrenheit(last_sample);

          // add this contribution to the average
          temp_avg = temp_avg + this_temp/100.0;
          temp = ((temp_avg - 32) /1.8);
        }

        // write message to LCD
        lcd_home();
        lcd_write_string(PSTR("ADC: "));
        lcd_write_int16(last_sample);
        lcd_write_string(PSTR(" of 1024   "));

        lcd_line_two();
        fprintf_P(&lcd_stream, PSTR("Temperature: %.2f"), temp_avg);
        lcd_write_data(0xdf);
        lcd_write_string(PSTR("F      "));

        lcd_line_three();
        fprintf_P(&lcd_stream, PSTR("Test"));
        lcd_write_data(0xff);
        lcd_write_string(PSTR("JACP er kul")); // , temp_avg

        lcd_line_four();
        fprintf_P(&lcd_stream, PSTR("Temp: %.2f"),temp);
        lcd_write_data(0xdf);
        lcd_write_string(PSTR("Celsius")); // , temp_avg

        // write message to serial port
        printf_P(PSTR("%.2f degrees F\r\n"), temp_avg);

        //Fan control
        if(temp_avg > 77){
            pos = PWM_fanspeed_2;
        }
        else{
            pos = PWM_fanspeed_START;
        }

      }

      return 0;
    }
January 12, 2012
by treymd
treymd's Avatar

should you be calling pwm_set() somewhere around line 174?

January 12, 2012
by Jacp
Jacp's Avatar

Yes, you are correct, i forgot that line. However I still seem to get the same problem after adding it.

Thanks for replying.

January 12, 2012
by treymd
treymd's Avatar

Out of curiosity, is your MOSFET gate "floating" or do you have a resistor pulling it to ground when the MCU is not powering it?

January 12, 2012
by Jacp
Jacp's Avatar

The mosfet gate is connected directly to the MCU.

January 12, 2012
by treymd
treymd's Avatar

Look at the schematic on this page: http://www.nerdkits.com/videos/motors_and_microcontrollers_101/ , it shows a "pull down" resistor connected to the MCU pin and ground. I'm not saying that this is your problem, but It's my guess that it could be a problem. floating gates tend to do whatever you don't want them to, like triggering the mosfet when it shouldn't be.

January 12, 2012
by Jacp
Jacp's Avatar

Thanks mate, I have seen the schematic before, but I thought that the mosfet had large resistant on the gate so that this would not be a problem. I'l ask some of my classmates tomorrow!

January 12, 2012
by hevans
(NerdKits Staff)

hevans's Avatar

Hi Jacp,

Did you try your circuit out to make sure your MOSFET is connected correctly as a switch. Connecting the gate directly to GND and then to +5 should give you an idea if your system will do the right thing once you start using the MCU.

Humberto

January 12, 2012
by Jacp
Jacp's Avatar

Hey Humberto.

It seems after testing your tip that the fan keeps running whether I connect the gate to ground or to +5. Have I connected the fan wrong?

January 12, 2012
by Ralphxyz
Ralphxyz's Avatar

Jacp, lets see your wiring diagram!

Ralph

January 12, 2012
by Jacp
Jacp's Avatar

![circuit]http://i.imgur.com/UaSaG.jpg

January 12, 2012
by Jacp
Jacp's Avatar

January 12, 2012
by treymd
treymd's Avatar

I would think you would want to connect black to the drain, source to ground, and leave blue unconnected.

January 12, 2012
by treymd
treymd's Avatar

Some computer fans have 3 leads, black being ground, red 5V and yellow 12V. I'm not sure what blue and red are on your fan.

January 12, 2012
by Ralphxyz
Ralphxyz's Avatar

I would try hooking the fan up like Mike and Humberto did in their Motor Tutorial.

The blue wire is probable a feedback so leave it disconnected for now just to get the fan controlled by the mcu.

We will worry about feedback (fan speed) later on once we have the fan operating.

Ralph

January 13, 2012
by Jacp
Jacp's Avatar

Allright I finally did it, after measuring and testing and a lot of good help from you guys at this forum. Thanks to all of you!

Following changes where made: 1.I connected black cable from fan to Drain 2.Installed a diode(1N4148) in parallell with the fan 3.Red cable from fan was connected to 9V 4.100K ohm resistor from gate to ground

Software changes: (Added different speeds for different temperatures)

//Fan control
    if((temp_avg > 75) & (temp_avg < 77)){
        pos = PWM_fanspeed_1;
        pwm_set(pos);
    }
    else if((temp_avg >= 77) & (temp_avg < 78)){
        pos = PWM_fanspeed_2;
        pwm_set(pos);
    }
    else if((temp_avg >= 78) & (temp_avg < 80)){
        pos = PWM_fanspeed_3;
        pwm_set(pos);
    }
    else if(temp_avg >= 80){
        pos = PWM_fanspeed_4;
        pwm_set(pos);
    }
    else{
        pos = PWM_fanspeed_START;
        pwm_set(pos);
    }

Some pictures: display

circuit

circuit diagram

January 14, 2012
by BobaMosfet
BobaMosfet's Avatar

Jacp-

What model/power/rating info is on the sticker on the fan please? I have a hunch that fan does a something else really cool you haven't played with, but probably want to: I'm betting that blue wire is for rotary encoder built into the fan- so you could read the fan speed (RPM).

BM

January 19, 2012
by Jacp
Jacp's Avatar

BobaMosfet-

The sticker has following information:

DC Brushlless [SB]
Model ASB0912L
DC 12V 0.15A -F00
Delta Electronics .INC

By the way reading the fan speed sound awesome!

January 20, 2012
by Ralphxyz
Ralphxyz's Avatar

Jacp, if you bought your fan from Amazon there is a RPM sensor.

Product Description
Delta ASB0912L 
Brushless Low Noise Case Fan 92mm x 92mm x 25mm, 
2 pin connector Model ASB0912L Size (mm) 92mm x 92mm x 25mm 
RPM 2100 
Airflow 37 cfm 
Noise 25 dBA 
Wire length 8" 
Connector 2 Pin RPM Sensor 
no Screws Included 
Voltage 12v Amps .08

Do you have a spec sheet?

Ralph

January 20, 2012
by Jacp
Jacp's Avatar

Ralph-

I haven't got a spec sheet since I took the fan from my old HP computer. However the fan from Amazon looks pretty much like mine.

January 20, 2012
by Ralphxyz
Ralphxyz's Avatar

You "might" be able to trace the circuit from your motherboard. I have seen different specsheets for that fan on the web, none that I have found are very informational some even for that model only list a red and black wire.

I guess you'll have to look at other fan speed sensor code and wing it from there.

Ralph

April 30, 2012
by jimlundborg
jimlundborg's Avatar

Could someone please help me understand the pull-up / pull-down resistors? I'm a total electronics newb. I tried to copy the the schematic from the motor tutorial but I don't have the diode running parallel to the fan.

I have almost the exact problem as above. I have a 12V 100MA fan powered by a 12V 200MA wall wart going into the 2N7000 MOSFET. I have a 100k resistor off the center pin (gate) of the MOSFET between it and the MCU. The positive is connected directly to the fan and the ground to the drain pin then the ground of the fan to the Source pin.

I'm not trying to do PWM I'm just trying to turn the fan on when temp gets to 81f. The problem is the fan starts spinning, not full speed, right away. When the temp hits 81 then the fan speeds up to normal so I think the code is correct but I don't think the voltage is being pulled down correctly.

April 30, 2012
by hevans
(NerdKits Staff)

hevans's Avatar

Hi jimlundborg,

Try separating the problem a little bit, and try to debug just the circuit that is driving your motor. With the motor and mosfet set up (not connected to your MCU), you should be able to use a wire to connect the gate of the mosfet directly to GND (this should cut power to your motor), then take the wire and connect it to the +5 rail (this should start your motor running). If that is not the case then you probably misswired something. If you include a schematic of what you have, or a picture, we can try to help you.

Humberto

April 30, 2012
by jimlundborg
jimlundborg's Avatar

OK I tried your test and sure enough the fan came on even when the gate was connected directly to ground. I'm not sure what I did but I just started over on that part of the circuit and it's now working as expected. Thanks for your help :)

Post a Reply

Please log in to post a reply.

Did you know that binary numbers use base 2 to represent numbers, and these are important for understanding microcontroller registers? Learn more...