I need some help with a fan controller.

Hello,

I'm sure experienced programmers on this forum are sick of people like me asking questions that to them seem remedial. But I'm a professional PLC programmer and can't for the life of me understand C++. I have been trying for weeks now to get an Arduino UNO to act as a fan controller with a temp sensor and I just can't get it. I have tried searching and when I find a tutorial and try to paste the code it never seems to work.

Anyway the project is using an automotive 2 wire temp sensor with a 1K ohm resistor as a voltage divider to activate and deactivate digital outputs at certain points. So far I have managed to turn one relay on but I can't figure out how to get it to turn off when I need it to. This is what I have so far.

void setup() {
  pinMode(8, OUTPUT);
  pinMode(A0, INPUT);
}

void loop() {
  if(analogRead(A0) > 512) {
    digitalWrite(8, HIGH);
  }
  else {
    digitalWrite(8, LOW);
  }
}

I don't need a temp reading in the program because the sensor isn't linear anyway. So the basic sensor values are fine. I'll test the sensor in boiling water later to match the real world temps with the sensor output numbers. Anyway this code works with a pot in place of the temp sensor for now to turn on a relay at sensor value 512 and above.

Now the next step is I need that relay to stay on until the senor value goes down to lets say 350. And then it would turn back on again at 512. Think of a cooling fan turning on at 200 deg F and off at 180 deg F. So how would I shut it off at that point?

It's frustrating because this is so very simple in Ladder Logic but to me seems impossibly complicated in C++.

Thanks in advance for anyone's help!

Instead of the “else “ , have another “if” , such that if the reading is less than 350 turn the output low . Once an output is set hi or lo , it will stay in that state until it’s changed.

You might want to add a digital write low for pin 8 in setup , so you can be sure of the startup state .

I tried that at one point but couldn't get it to work. The brackets mess me up. In fact I think they are my biggest issue 99% of the time. I'll try that again when I get home and I'll post back with what happened.

Just to check though is this what you mean.

void setup() {
  pinMode(8, OUTPUT);
  pinMode(A0, INPUT);
  digitalWrite(8, LOW);
}

void loop() {
  if(analogRead(A0) > 512) {
    digitalWrite(8, HIGH);
  }
  if {(analogRead(A0) < 350)
    digitalWrite(8, LOW);
  }
}

I'm sure those brackets aren't right but I don't know how to make them right.

You have a curly bracket after an "if", remove it. Also after an initial if use an else if.

void SomeFunction()
{
  if (some condition is true)
  {
  Do some stuff;
  }
  else if (some condition is true)
  {
  Do some stuff;
  }
  else
  {
  Do some stuff;
  }
}

Ok so I tried this

void setup() {
  pinMode(8, OUTPUT);
  pinMode(A0, INPUT);
  digitalWrite(8, LOW);
}

void loop() {
  if(analogRead(A0) > 512)
    digitalWrite(8, HIGH);
  }
else if {(analogRead(A0) < 350)
    digitalWrite(8, LOW);
  }
}

When I click verify I get an error.

exit status 1
expected unqualified-id before 'else'

Any thoughts?

I have tried moving these brackets a bunch of different ways and am not finding the spot it wants them to be in.

So I moved some things around but still no luck.

void setup() {
  pinMode(8, OUTPUT);
  pinMode(A0, INPUT);
  digitalWrite(8, LOW);
}

void loop() {
  if(analogRead(A0) > 512)
    digitalWrite(8, HIGH);
  }
  {
else if(analogRead(A0) < 350)
    digitalWrite(8, LOW);
    }
void setup() {
  pinMode(8, OUTPUT);
  pinMode(A0, INPUT);
  digitalWrite(8, LOW);
}

void loop() {
  if (analogRead(A0) > 512)
  {
    digitalWrite(8, HIGH);
  }
  else if (analogRead(A0) < 350)
  {
    digitalWrite(8, LOW);
  }
}

Think of it like this

void SomeFunction()
{ // open curly bracket we are in the function
 if (condition A is true)
  { // open curly bracket we are in the condition A
   Do stuff associated with condition A;
   } // close curly bracket we out of condition A
  else if (condition B is true)
   { // open curly bracket we are in the condition B
     Do stuff associated with condition B;
      // you can also have another condition here
     if (condition C is true)
     {// open curly bracket we are in condition B&C
      Do stuff associated with condition B&C;
      } // close curly bracket out of condition C but in B
     } // close curly bracket we are out of condition B
   else // all remaining possible conditions
    { // we are in all the possible remaining conditions
      Do remaining stuff;
    } // we are out of all remaining conditions
 } // we are out of the void SomeFunction

You might use the forum search feature and look for "dead band" for past similar discussions.

You should always use constants for values used more than once in the program. If you decided to move the relay to another pin then only the constant would have to change, not every line in the code that writes to it.

I find it really helpful to write my logic in comments, that often makes it clear whether my code supports the logic.

Print statements can be very useful to see what is actually going on in the code, otherwise you are guessing.

Below is my translation of your requirements in post #1, check it out.

const byte RELAY_PIN = 8;
const byte TEMP_PIN = A0;

const int ON_TEMP =  512;    // turn on fan
const int OFF_TEMP = 350;    // turn off fan when cooled

void setup() {

  pinMode(RELAY_PIN, OUTPUT);
  pinMode(TEMP_PIN, INPUT);
  Serial.begin(9600);

}

void loop() {

  int temp = analogRead(TEMP_PIN);  // read sensor

  // is fan on?
  if ( digitalRead(RELAY_PIN) == HIGH )
  {
    // yes, turn off if necessary
    if ( temp < OFF_TEMP )
    {
      digitalWrite(RELAY_PIN, LOW);
      Serial.print("turning off, reading = ");
      Serial.println(temp);

    }

  } else {

    // no, turn on if necessary
    if ( temp >= ON_TEMP )
    {
      digitalWrite(RELAY_PIN, HIGH);
      Serial.print("turning on, reading = ");
      Serial.println(temp);
    }

  }

}

EDIT: temps change to ints based on post #13, thanks JCA34F

Thanks everyone for all the help. I got it working "kind of" and that was with everyone's help. I still have some more functions to add but now I'm having some hardware issues. I think I have a short or a bad UNO. Or at least a faulty pot. I'm going to replace some parts tomorrow and see what happens. I'm just excited that I saw it work.

Hello Phobos84,

Proietti:
You have a curly bracket after an "if", remove it. Also after an initial if use an else if.

void SomeFunction()

{ // open curly bracket we are in the function
if (condition A is true)
 { // open curly bracket we are in the condition A
  Do stuff associated with condition A;
  } // close curly bracket we out of condition A
 else if (condition B is true)
  { // open curly bracket we are in the condition B
    Do stuff associated with condition B;
     // you can also have another condition here
    if (condition C is true)
    {// open curly bracket we are in condition B&C
     Do stuff associated with condition B&C;
     } // close curly bracket out of condition C but in B
    } // close curly bracket we are out of condition B
  else // all remaining possible conditions
   { // we are in all the possible remaining conditions
     Do remaining stuff;
   } // we are out of all remaining conditions
} // we are out of the void SomeFunction

Note that this code :

void SomeFunction()
{ // open curly bracket we are in the function
 if (condition A is true)
 { // open curly bracket we are in the condition A
 Do stuff associated with condition A;
 } // close curly bracket we out of condition A
  else
 {
 if (condition B is true)
 { // open curly bracket we are in the condition B
 Do stuff associated with condition B and (not A);
 // you can also have another condition here
 if (condition C is true)
 {// open curly bracket we are in condition B&C&(notA)
 Do stuff associated with condition B&C&(notA);
 } // close curly bracket out of condition C but in B
 } // close curly bracket we are out of condition B
 else // all remaining possible conditions
 { // we are in all the possible remaining conditions with (notB)&(notA)
 Do remaining stuff;
 } // we are out of all remaining conditions
 } 
 } // we are out of the void SomeFunction

void SomeFunction()
{ // open curly bracket we are in the function
if (condition A is true)
{ // open curly bracket we are in the condition A
Do stuff associated with condition A;
} // close curly bracket we out of condition A
else
{
if (condition B is true)
{ // open curly bracket we are in the condition B
Do stuff associated with condition B and (not A);
// you can also have another condition here
if (condition C is true)
{// open curly bracket we are in condition B&C&(notA)
Do stuff associated with condition B&C&(notA);
} // close curly bracket out of condition C but in B
} // close curly bracket we are out of condition B
else // all remaining possible conditions with (notB)&(notA)
{ // we are in all the possible remaining conditions
Do remaining stuff;
} // we are out of all remaining conditions
}
} // we are out of the void SomeFunction

is exactly the same than Proietti's code, with different indentations and some more curly brackets and comments.
Regards,
bidouilleelec

512 and 350 won't fit in an 8 bit byte, max is 255:

void setup() {
pinMode(8, OUTPUT);

}

void loop() {
if(analogRead(A0) > 512){
digitalWrite(8, HIGH);
}
if(analogRead(A0) < 350){
digitalWrite(8, LOW);
}
}

JCA34F:
512 and 350 won't fit in an 8 bit byte, max is 255:

void setup() {
pinMode(8, OUTPUT);

}

void loop() {
if(analogRead(A0) > 512){
digitalWrite(8, HIGH);
}
if(analogRead(A0) < 350){
digitalWrite(8, LOW);
}
}

Can you elaborate on this? The program works with numbers over 255. I thought the UNO was 10 bit.

This is what worked until I had a short and the relays started blinking like crazy. Oh and all of a sudden now my pot works backwards and the pin 13 led came on (not on before)

void setup() {
  pinMode(8, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(4, OUTPUT);

  pinMode(A0, INPUT);

  digitalWrite(8, LOW);
  digitalWrite(7, LOW);
  digitalWrite(4, LOW);
}

void loop() {
  if(analogRead(A0) > 500)  //fan 1 on
    {digitalWrite(8, HIGH);}
  
else if(analogRead(A0) < 400)  //fan 1 off
    {digitalWrite(8, LOW);}

 if(analogRead(A0) > 700)  //fan 2 on
    {digitalWrite(7, HIGH);}

else if(analogRead(A0) < 600)  //fan 2 off
    {digitalWrite(7, LOW);}

 if(analogRead(A0) > 900)  // warning light on
    {digitalWrite(4, HIGH);}

else if(analogRead(A0) < 800)  // warning light off
    {digitalWrite(4, LOW);}


    }

Sorry I put my brackets in odd places. 20 years of plc programming has me looking at this from a different perspective than most I'm sure.

analogRead returns an int in the 0 to 1023 range, so 512 and 350 are both fine.

Hello Phobos84

Phobos84:
. I thought the UNO was 10 bit.

JCA34F's message seems not justified.
ATmega328p is 8 bits. Type int is 16 bits.

Regards,
bidouilleelec

Phobos84:

void setup() {

pinMode(8, OUTPUT);
 pinMode(7, OUTPUT);
 pinMode(4, OUTPUT);

pinMode(A0, INPUT);

digitalWrite(8, LOW);
 digitalWrite(7, LOW);
 digitalWrite(4, LOW);
}

void loop() {
 if(analogRead(A0) > 500)  //fan 1 on
   {digitalWrite(8, HIGH);}
 
else if(analogRead(A0) < 400)  //fan 1 off
   {digitalWrite(8, LOW);}

if(analogRead(A0) > 700)  //fan 2 on
   {digitalWrite(7, HIGH);}

else if(analogRead(A0) < 600)  //fan 2 off
   {digitalWrite(7, LOW);}

if(analogRead(A0) > 900)  // warning light on
   {digitalWrite(4, HIGH);}

else if(analogRead(A0) < 800)  // warning light off
   {digitalWrite(4, LOW);}

}




Sorry I put my brackets in odd places.

You have to study more carefuly if else statements.

Please explain what you want :

Fan 1 ON between x1 and y1
Fan 2 ON between x2 and y2
Light ON between x3 and y3

Regards,
bidouilleelec

bidouilleelec:
You have to study more carefuly if else statements.

Please explain what you want :

Fan 1 ON between x1 and y1
Fan 2 ON between x2 and y2
Light ON between x3 and y3

Regards,
bidouilleelec

Well the idea is to control dual cooling fans in a car. The temp sensor that is screwed into the passenger side cylinder head is a variable resistor. With a fixed 1K ohm resistor I will make a voltage divider and have that feed analog data into the Arduino. I need the board to turn fan 1 on at 190 deg F and off at 180 Deg F. Then turn fan 2 on at 210 deg F and off at 195 deg F. Then I would like a warning light to come on at 230 deg F and off at 215 Deg F.

This is all so I can "reclaim" two used outputs in the Holley Terminator X ECU. If I can use the Arduino to control fans then I can use the PWM of the Holley computer to control nitrous oxide. This is for use in a race car.

I know that building a voltage divider using a variable resistor "thermistor" and a fixed 1K ohm resistor will not give me a linear reading. That's okay considering I truly only have to read accurately between 150 to 250 deg F. So the plan is after I get some code that seems to work with a pot then I will do some testing with a GM coolant temp sensor. I'm going to wire the voltage divider as explained and put the sensor in heated water with a temp probe. So as the temp increases I will watch the serial monitor so I can see what value from the sensor is the equivalent to what real world temp and go from there.

Sorry this was so long winded. Any way I removed all my wiring and blew off the board with compressed air and now everything is back up an running. I have 3 relays working as they should. Other than the pot I have on it seems to jump a little.

You guys are awesome! I would never have got this running without this forums help. I'm sure after more work on this I will have more questions. To be honest I'm just having fun learning how to write code in a language I have never used before.

My reply was in response to @Blue Eyes' original reply which contained:

const byte ON_TEMP =  512;    // turn on fan

const byte OFF_TEMP = 350;    // turn off fan when cooled