Fan controller acting strange

Ok, so I’ve made a simple sketch to make the arduino control a fan by ‘analogreading’ a thermistor in a voltage divider and calculating the corresponding temperature based on the properties of the thermistor. What I’ve found out is that when I upload the sketch or when I open or close the serial monitor, the fan spins up regardless of temperature. I’m not able to find the cause of this. The sketch is shown below and I would also highly appreciate any feedback on the code in general.

/*
Fan controller based on analog input from thermistor

Regular resistor (10kOhm) placed between A0 and ground.
Thermistor (TTC05103) placed between +5V and A0. (10kOhm at 25 deg C).
Steinhart - Hart coefficients determined from http://en.wikipedia.org/wiki/Steinhart%E2%80%93Hart_equation and datasheet.
 */


#include <math.h>
#define interval 500  // [ms] Interval for measuring and temperature
#define R2 10000 // Resistor value in voltage divider
#define fanPin 12 // Pin which goes to mosfet
long previousMillis = 0; // For delay (See "Blink without delay").
float onTemp = 25.0; // Temperature [C] to start fan
float offTemp = 0.95 * onTemp; // Temperature [C] to stop fan
int fanState = LOW; // On/off

void setup(){
  pinMode(fanPin, OUTPUT);
  Serial.begin(9600);
  Serial.print("On temperature: ");
  Serial.print(onTemp, 2);
  Serial.println(" [C]");

  Serial.print("Off temperature: ");
  Serial.print(offTemp, 2);
  Serial.println(" [C]");

  delay(2000); // Add delay to display the on / off temperatures

}

void loop(){

  unsigned long currentMillis = millis(); 
  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis; 

    // Loop:
    float temp = calcTemp();
    if (temp > onTemp) {
      fanState = HIGH;
    }
    if (fanState == HIGH && temp < offTemp) {
      fanState = LOW;
    }
    digitalWrite(fanPin, fanState); // Fan control
    
    Serial.print(calcTemp(),2);
    Serial.print('\t');
    Serial.println(fanState);
  }
}

// Calculating resistance of thermistor:
int readResistance(){
  int adcVal = analogRead(A0);
  float voltage = adcVal * 5.0 / 1023.0;
  int R = (5.0 / voltage - 1.0) * R2;

  return R;  // Return resistance
}

// Calculate the temperature based on resitance:
float calcTemp(){
  int R = readResistance();

  // Steinhart-Hart coefficients:
  const float A = 1.28e-3;
  const float B = 2.11e-4;
  const float C = 1.71e-7;  

  // Steinhart-Hart equation:
  float T = 1/(A+B*log(R)+C*pow(log(R),3)) - 273.15;

  return T; // Return Temperature in degrees Celcius
}

Code looks quite good, one small remark in loop

void loop()
{
  unsigned long currentMillis = millis(); 
  if(currentMillis - previousMillis > interval)
  {
    previousMillis = currentMillis; 

    float temp = calcTemp();
    
    if (temp > onTemp) fanState = HIGH;
    else if (temp < offTemp) fanState = LOW;
    digitalWrite(fanPin, fanState); 

    Serial.print(currentMillis); // added timestamp
    Serial.print('\t');
    Serial.print(temp, 2);  <<<<<  print the temp used for the logic, not a new calculation
    Serial.print('\t');
    Serial.println(fanState);
  }
}

don;t know if the readResistance() is correct.
Can you post schematic?

The symptoms suggest that when the fan control pin is configured as an input, the driver circuit is powering the fan. You could confirm that theory by running a sketch which leaves the fan pin as an input. Maybe there's a design flaw in your driver circuit which causes it to power the fan when the control input is floating. How are you driving the fan?

robtillaart:
Code looks quite good, one small remark in loop

void loop()

{
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval)
  {
    previousMillis = currentMillis;

float temp = calcTemp();
   
    if (temp > onTemp) fanState = HIGH;
    else if (temp < offTemp) fanState = LOW;
    digitalWrite(fanPin, fanState);

Serial.print(currentMillis); // added timestamp
    Serial.print(’\t’);
    Serial.print(temp, 2);  <<<<<  print the temp used for the logic, not a new calculation
    Serial.print(’\t’);
    Serial.println(fanState);
  }
}




don;t know if the readResistance() is correct. 
Can you post schematic?

Thanks for reply! Ok, so I corrected the call for calcTemp, I don’t know why I left that in there, probably forgot to change it :).

Also I tried to put a pull-down resistor in the circuit, which basically removed the problem with the fan spinning up. I can faintly hear a ‘tick’ from the fan though, so there is probably a short spike there still. Are the values for resistors ok?

I think the resistance reading is correct, I’ve checked with multimeter and it seems spot on. The resistance error is approx +/- 50 ohms due to the adc, corresponding to approx 0.1 deg C, but that’s ok for me. It’s not like I’m going to put the arduino up there to measure my fever. I have a couple of nanos lying around, but still no :slight_smile:

Btw, do you think this sketch will be possible to run on an attiny85?

Hi, just to get the symptom right. When you upload, or open or close the monitor, the motor MOMENTARILY runs. This will be due to the arduino resetting. Declare the pinMode(fanPin, OUTPUT); then digitalWrite(fanPin,LOW); as the first things you do in setup. I presume that it works okay once everything settles down?

Tom...... :)