PWM Fan Control Help

Hello all,

I have just completed building this http://www.electroschematics.com/9540/arduino-fan-speed-controlled-temperature/

Everything works as it should but I would like to see if I could to make a change to how the fan starts?

What it is doing is as the temperature rises the fan initially tries to start but the temperature must increase a bit before the fan actually starts to spin due to the permanent magnets in the motor being less stronger than the generated magnetic field, I can manually flick the fan when it doesn’t have enough power to start it and once I do this it will spin at the lower voltage.

What I am hoping someone can help me with is a piece of code that when the temperature is higher than the minimum temperature where the PWM starts the fan would there be a way to pulse the fan at full power for a split second to get it started, hope that makes sense?

On a side note I didn’t use the full code off the site as I didnt use a LCD or LED on my build so my current sketch is below, thanks in advance for any help.

    int tempPin = A1;   // the output pin of LM35
    int fan = 11;       // the pin where fan is
    int temp;
    int tempMin = 30;   // the temperature to start the fan
    int tempMax = 70;   // the maximum temperature when fan is at 100%
    int fanSpeed;
     
    void setup() {
      pinMode(fan, 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
           analogWrite(fan, fanSpeed);  // spin the fan at the fanSpeed speed
       }
    }
     
    int readTemp() {  // get the temperature and convert it to celsius
      temp = analogRead(tempPin);
      return temp * 0.48828125;
    }

Hi,

Welcome to the forum.

 fanSpeed = map(temp, tempMin, tempMax, 32, 255);

I think you just need to change the 32 a bit at a time in the map function until your fan starts reliably. 32 is the PWM duty for the minimum speed that it starts at.

Hope that helps.. Tom... :)

Maybe you can include a flag (ie. a status value), such as temperature_flag.

So whenever your software detects that the temperature is below the fan’s turn-on temperature, then set this temperature_flag to zero. Eg. previous_temp_flag = 0.

When the temperature reaches or exceeds your fan turn-on temperature, then set the flag to 1.

Eg. previous_temp_flag = 1.

Then, in your ‘if’ statement for turning on the fan… put an extra if statement within it… such as:

       if(temp < tempMin) {   // if temp is lower than minimum temp
           fanSpeed = 0;      // fan is not spinning
           previous_temp_flag = 0;  //reset flag to zero here
           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
       if(previous_temp_flag == 0) {
         previous_temp_flag = 1;
         analogWrite(fan, 100);      //run the fan at PWM value of 100
         delay(1000);      //run at the above fan speed for 1 second
       }
    analogWrite(fan, fanSpeed);  // spin the fan at the fanSpeed speed
}

Also… in your code below, may I ask why your comment says “the actual speed of fan”? It just seems to me that ‘fanSpeed’ is not actual speed of fan, but is instead ‘desired’ speed of fan?

fanSpeed = map(temp, tempMin, tempMax, 32, 255); // the actual speed of fan
analogWrite(fan, fanSpeed);  // spin the fan at the fanSpeed speed

Alternatively, to overcome motor ‘deadzone’, you can always find out what your minimum PWM value is for reliable start-up of the fan…so whenever you turn on the fan, you should always run the fan at least at that PWM value (and not below it).

Also… in your code below…

if((temp >= tempMin) && (temp <= tempMax))

Would it be better to just have the condition: if(temp >= tempMin) ?

Something more to experiment with (untested). Added some hysteresis and startup pulse:

int tempPin = A1;    // the output pin of LM35
int fan = 11;        // the pin where fan is
int temp;
int tempMin = 30;    // the temperature to start the fan
int tempMax = 70;    // the maximum temperature when fan is at 100%
int fanSpeed;
byte hysteresis = 1; // small hysteresis to prevent start/stop oscillation at tempMin
boolean stopped = true;

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

void loop() {
  temp = readTemp();   // get the temperature
  if (temp < (tempMin - hysteresis)) { // if temp is lower than minimum temp
    fanSpeed = 0;      // fan is not spinning
    digitalWrite(fan, LOW);
    stopped = true;
  }
  if ((temp >= tempMin) && (temp <= tempMax)) { // if temperature is higher than minimum temp
    if (stopped) {
      fanSpeed = 255;
      delay(400);      // 400ms fan startup pulse
      fanSpeed = 0;
      stopped = false;
    }
    fanSpeed = map(temp, tempMin, tempMax, 32, 255); // the actual speed of fan
    analogWrite(fan, fanSpeed);  // spin the fan at the fanSpeed speed
  }
}

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

Yes.... the hysteresis behaviour will be really good. This stops the fan from switching on and off really fast at the temperature boundary (between fan on an fan off) due to noise or fluctuations in the sensor readings. So if the fan is initially OFF and the temperature is rising, then the fan should be programmed to turn on at a particular temperature temperature. And, when the fan is ON, and the temperature is falling, then the fan should be programmed to turn off at a temperature that is less than the minimum turn-on temperature.

Thanks for the reply's everyone, I have things to try now, I'm pretty new to Arduino and appreciate the help.