How to independently check more than one variable?

Viewed 104

This is the part of the code with the error:

  int value = analogRead(LM351);
  float Temperature = value * 500.0 / 1023.0;
  lcd.setCursor(6,0);
  lcd.print(Temperature); 
  lcd.setCursor(11,1);
  int value1 = analogRead(LM352);
  float Humidity = value1 * 500.0 / 1023.0;
  lcd.setCursor(10,1);
  lcd.print(Humidity); 
  

  if (Temperature > 24){
    digitalWrite(motor, HIGH);
    digitalWrite(LedRed, HIGH);
    digitalWrite(LedGreen, LOW);
    lcd.print("");
  }
  else {
    digitalWrite(motor, LOW);
    digitalWrite(LedRed, LOW);
    digitalWrite(LedGreen, HIGH);
    lcd.print("");
  }
  
  if (Humidity > 10){
    digitalWrite(motor, HIGH);
    lcd.print("");
  }
  else {
    digitalWrite(motor, LOW);
    lcd.print("");
  }
  
   delay(1000);
}

By right, the motor should spin if the temperature is more than 24 or humidity is more than 10. But when I ran this code, the motor only spun if the humidity was more than 10. But when humidity was less than 10 and temperature was more than 24, motor did not spin.

The reason for this is as I am checking one variable after the other, is there a way in which I can check each variable independentaly from the other?

5 Answers

Your logic checks one thing and reacts, then checks the other thing.
You can either check both things at once, identify one among 4 situations and then react, or check one thing after the other, but only make decisions instead of reacting immediatly, then react later.

I think you ask specifically about checking separatly, so go with decision making.

// no decisions yet
bool NeedMotor = false;

if (Temperature > 24)
{ 
    NeedMotor = true;
    digitalWrite(LedRed, HIGH);
    digitalWrite(LedGreen, LOW);
    lcd.print("");
} else
{
    digitalWrite(LedRed, LOW);
    digitalWrite(LedGreen, HIGH);
    lcd.print("");
}
  
if (Humidity > 10){
    NeedMotor = true;
    lcd.print("");
} else
{
    lcd.print("");
}

if (NeedMotor)
{
    digitalWrite(motor, HIGH);
} else
{
    digitalWrite(motor, LOW);
}

This way the humidity decision does not overwrite the temperature decision, it just potentially decides to use the motor if the temperature did not cause that yet. If the motor is needed it will be switched on, otherwise off.

Note, I am unsure about the purpose of the lcd printing. I left it as it is in your code.

You could include both conditions in the first if-else statement:

if (Temperature > 24 || Humidity > 10){
    digitalWrite(motor, HIGH);
    digitalWrite(LedRed, HIGH);
    digitalWrite(LedGreen, LOW);
    lcd.print("");
}
else {
    digitalWrite(motor, LOW);
    digitalWrite(LedRed, LOW);
    digitalWrite(LedGreen, HIGH);
    lcd.print("");
}

The issue here is that both statements are in if...else clause.

Let's take the case when temperature is above 24 and humidity is below 10.

The program enters temperature if block, checks the condition, it passes, so it executes the block within the if clause, the one below:

if (Temperature > 24){
    digitalWrite(motor, HIGH);
    digitalWrite(LedRed, HIGH);
    digitalWrite(LedGreen, LOW);
    lcd.print("");

Next it checks the condition in humidity if clause, it does not pass because the humidity is below 10 so it executes the else block:

 else {
    digitalWrite(motor, LOW);
    lcd.print("");
  }

So the motor does start spining but is almost immediatly stoped by the else block in humidity if...else clause.

To fix this you would need to refactor the code to check both condition with OR ( || ).

If ( Temperature > 24 || Humidty > 10 )
{
    //spin
    if ( Temperature > 24 )
    {
        //set LEDs
    }
}
else
{
    // do not spin
}

You will also require a nested if clause to set the LEDs only in case the Temperature >24.

This way the code will be executed everytime either

Temparature > 24 or Humidty > 10

I would start by inverting logic, the two things that the conditions have in common is that they are both off when they are below threshold, if the condition is met when neither is below threshold then turn on the fans, and then have a nested conditional statement which checks if it's the temperature.

Disclaimer: There is probably a cleaner way of doing this.

//If the temperature or humidity are below threshold then
//turn off the motor and the red LED, and turn on the green LED
if(Temperature <= 24 && Humidity <= 10)
{
  digitalWrite(motor, LOW);
  digitalWrite(LedRed, LOW);
  digitalWrite(LedGreen, HIGH);
}
else //the temperature or humidity are above threshold
{
  //turn on the motor
  digitalWrite(motor, HIGH);
  
  //if the temperature is above threshold turn off the Green LED
  //and turn on the red led
  if (Temperature > 24)
  {
    digitalWrite(LedRed, HIGH);
    digitalWrite(LedGreen, LOW);
  }
  //if the humidity and temperature are both above threshold and the
  //temperature falls back below threshold, invert the LEDs.
  else
  {
    digitalWrite(LedRed, LOW);
    digitalWrite(LedGreen, HIGH);
  }

  //clear the LCD
  lcd.print("");
}

You literally described required code but you didn't implement it in actual code.

bool MotorRequired = (Temperature > 24) || (Humidity >10);

Or separately:

bool MotorRequired = (Temperature > 24);

MotorRequired = MotorRequired || (Humidity >10);

when reaching point where motor can be used

if(MotorRequired)
   // power motor on
else
   // power motor off

Which can be shorter branch-free:

digitalWrite(motor, (MotorRequired) ? HIGH : LOW );

That is just same as

if(Temperature > 24 || Humidity >10)

So whole logic looks like

digitalWrite(motor, (Temperature > 24 || Humidity >10) ? HIGH : LOW );

Those conditions are independent but your action depends on BOTH of them, so you have to perform logical operation on both.

Related