 # 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
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).

``````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