Apparent flaws in multiple if/else statements and map functions

Hello everyone! I am trying to design a temperature control device for a unit on my entertainment center. The unit with my HTPC and game consoles gets hot and I have to leave the door open to try to manage temps.

The design is a pair of 12 volt fans wired to an Arduino Uno through a pair of 3205 Mosfets using a TMP 35 sensor. A 16X2 display will display temperature in celcius and farenheight on the top line and fan speeds on the bottom line.

The code is a mosaic of "borrowed" bits, examples and my personal attempts.

What I was trying to do is have the Arduino read the temperature, and have two thresholds. A lower one activates a slower, quiet fan. If temps continue to climb, the second noisier fan activates. The fans would be mapped to the temperature and controlled with PWM. I also wanted to set a "temp off" lower than the "temp on" so the fans wouldn't pulse on and off at the borderline threshold but I cut it out to try to troubleshoot.

My code, for your consideration:

#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
const int sensePin = A0;   // the output pin of LM35
int sensorInput;
const int fan1 = 13;
const int fan2 = 10;
const int fan1tempON = 27;
const int fan1tempMax = 70;
const int fan2tempON = 50;
const int fan2tempMax = 90;
int fan1Speed = 0;
int fan2Speed = 0;
int fan1LCD;
int fan2LCD;
double temp;

void setup() {
  pinMode(fan1, OUTPUT);
  pinMode(fan2, OUTPUT);
  pinMode(sensePin, INPUT);
  lcd.begin(16,2);

}

void loop() {
  sensorInput = analogRead(sensePin);    //read the analog sensor and store it
  temp = (double)sensorInput / 1024;       //find percentage of input reading
  temp = temp * 5;                 //multiply by 5V to get voltage
  temp = temp - 0.5;               //Subtract the offset 
  temp = temp * 100;               //Convert to degrees 

  if(temp  >= fan1tempON) {
      fan1Speed = map(temp, fan1tempON, fan1tempMax, 60, 255); // the actual speed of fan 
      fan1LCD = map(temp, fan1tempON, fan1tempMax, 0, 100); // speed of fan to display on LCD 
      analogWrite(fan1, fan1Speed); // spin the fan at the fanSpeed speed 
}
  if(temp >= fan2tempON) {
      fan1Speed = map(temp, fan1tempON, fan1tempMax, 80, 255); // the actual speed of fan 
      fan2Speed = map(temp, fan2tempON, fan2tempMax, 60, 255);
      fan1LCD = map(temp, fan1tempON, fan1tempMax, 0, 99); // speed of fan to display on LCD 
      fan2LCD = map(temp, fan2tempON, fan2tempMax, 0, 99);
      analogWrite(fan1, fan1Speed); // spin the fan at the fanSpeed speed 
      analogWrite(fan2, fan2Speed);
  }
  else {
      digitalWrite(fan1, LOW);
      digitalWrite(fan2, LOW);
}
   lcd.setCursor(0,0);
   lcd.print("Temp:");
   lcd.print(temp,1);      // display the temperature
   lcd.print("C ");
   lcd.setCursor(11,0);
   lcd.print(temp*1.8+32,1);
   lcd.print("F ");
   lcd.setCursor(0,1);   // move cursor to next line
   lcd.print("Fan1:");
   lcd.print(fan1LCD);    // display the fan speed
   lcd.print("%");
   lcd.setCursor(8, 1); // bottom right
   lcd.print("Fan2:");
   lcd.print(fan2LCD);
   lcd.print("%");
   delay(1000);
   lcd.clear();   
}

Ive tried researching and rewriting the code, and got kinda close (I think), but it still doesn't work correctly. The temperature displays and works well. But the fans wont engage until the fan2tempON condition has been met. Also, the fan speed mapping doesn't cap at 99%. Plus, I'm sure the code is ugly...

Thanks for looking, I appreciate any help I can get!

1 Like

i simulated your code

when temp > 90, both if conditions are met, the first sets fan1 and the 2nd if sets fan1 and fan2.

it would make more sense to do the 2nd if case, temp > 50, first and make the original if an else if (temp > 27. In other words only one condition can be met and the first is the greater of the 2

your else case covers the case when neither condition is met, but i think the new else if (temp > 27) needs to set fan2 off.

Your logic needs to be a series of if/elseif statements. If your current temperature is below fan2ON, then your second if() statement will be false so the else clause will execute which turns both fans off.

Also, map() does not constrain the values to be within the range you specify. You can use constrain() for that prior to using map()