Help with IF and Else

Hi,

I am looking into playing around with IF and Else. However I seem to be having issues. Below is my code. I want the built in LED to be on when temp is 21 or above and low if below. The LED does turn on when its above 21 however doesn’t seem to turn off.

Is it the delay() thats causing the issue?

float tempC;
int reading;
int tempPin = 0;

void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
analogReference(INTERNAL);
Serial.begin(9600);
}

void loop()
{
reading = analogRead(tempPin);
tempC = reading / 9.31;
Serial.println(tempC);
delay(10000);

if(tempC>=21)
{
digitalWrite(LED_BUILTIN, HIGH);
}
else if(tempC<=20)
{
digitalWrite(LED_BUILTIN, HIGH);
}
}

both your digitalwrite() statements set LED_BUILTIN to HIGH - one of them should be LOW ?

AWKWARD!!!!!

Sorry!

cbirchy87:
Hi,

I am looking into playing around with IF and Else. However I seem to be having issues. Below is my code. I want the built in LED to be on when temp is 21 or above and low if below. The LED does turn on when its above 21 however doesn’t seem to turn off.

Is it the delay() thats causing the issue?

float tempC;

int reading;
int tempPin = 0;

void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
analogReference(INTERNAL);
Serial.begin(9600);
}

void loop()
{
reading = analogRead(tempPin);
tempC = reading / 9.31;
Serial.println(tempC);
delay(10000);

if(tempC>=21)
{
digitalWrite(LED_BUILTIN, HIGH);
}
else if(tempC<=20)
{
digitalWrite(LED_BUILTIN, HIGH);
}
}




![](https://cdn-learn.adafruit.com/assets/assets/000/000/476/original/temperature_tmp36fritz.gif?1447975816)

Couple things I see is that with your if - else

right now you are ignoring a whole degree in there where nothing will happen between 20 and 21

You should be able to write it like this to get the whole range:

if(tempC>=21)
{
digitalWrite(LED_BUILTIN, HIGH);
}
else
{
digitalWrite(LED_BUILTIN, HIGH);
}

By leaving out the second if anything from negative to 21 degrees will be the if condition and then anything above 21 such as 21.000001 will be else.

and yes as someone else said the If and Else are doing the same thing so you will never know if it is changing.

I would also say the delay(10000) is in the wrong place. Take reading, wait 10 sec, turn on/off LED. Would it not be better to take reading, turn LED on/off, wait 10 sec?

bsohn:
right now you are ignoring a whole degree in there where nothing will happen between 20 and 21

I assumed the two if() statements were to give some Hysteresis in the ON/OFF control otherwise you could get the LED flickering on/off around the 21degree temperature set point

horace:
I assumed the two if() statements were to give some Hysteresis in the ON/OFF control otherwise you could get the LED flickering on/off around the 21degree temperature set point

That is true so that would work if that is what is intended.. and you could tighten it up if you wanted less than a degree of hysteresis.

Just about if-else, and one tip – while coding use the AutoFormat tool (ctrl-t) often as it checks syntax. It’s easier to keep code straight a little at a time than write up a load of code and then start debugging all the problems at once.

 if(tempC>=21)
  {
    digitalWrite(LED_BUILTIN, HIGH);
  }
  else if(tempC<=20)
  {
    digitalWrite(LED_BUILTIN, HIGH); // so no change?
  }

Your code has no hole but the if(tempC<=20) isn’t needed since everything not >= 21 must be < 21 (<= 20).
The compiler very likely does not code the second if().

Practice pruning and it won’t be long before you won’t have to… much… you will be able to read code much easier.

The else if is for when you want to chain if()'s.
Here the if-else-if-else… chain slices possible values for tempC from the top down. Once everything >= 21 are taken, everything >= 18 can only be 18, 19 or 20. Every cut[/] takes away from what’s left and the last else gets that.
Here’s the routine in pseudo-snippet:
```

  • if(tempC>=21)
      {
        digitalWrite(LED_BUILTIN, HIGH);
      }
      else if(tempC >= 18)
      {
        mySoftPWMfunction(LED_BUILTIN, 190);
      }
      else if(tempC >= 15)
      {
        mySoftPWMfunction(LED_BUILTIN, 127);
      }
      else if(tempC >= 12)
      {
        mySoftPWMfunction(LED_BUILTIN, 63);
      }
      else
      {
        digitalWrite(LED_BUILTIN, LOW);
      }*
    ```

GoForSmoke:
Your code has no hole but the if(tempC<=20) isn’t needed since everything not >= 21 must be < 21 (<= 20).
The compiler very likely does not code the second if().

What if tempC is between 20 and 21, such as 20.5? It’s a float variable, after all.

christop:
What if tempC is between 20 and 21, such as 20.5? It’s a float variable, after all.

I though it was analog read results, my bad, yes it should be >= 21.0 or < 21.0

When using integer constants, will the float value get converted before the compare?

GoForSmoke:
When using integer constants, will the float value get converted before the compare?

Along those lines, what is the result of the adc conversion formula tempC = reading / 9.31; that is float = int / float?

I avoid problems like this so I don't have to remember all the nuances.

do a web serach on C operand promotion

horace:
do a web serach on C operand promotion

The OP can tackle that (unless someone wants to provide the answer). I don't care to look it up, AFAIK there is an issue. I just cast the ADC integer reading as a float and move on with life.

to quote “if either operand is a float, the other operand is converted to float”

adwsystems:
Along those lines, what is the result of the adc conversion formula tempC = reading / 9.31; that is float = int / float?

I avoid problems like this so I don’t have to remember all the nuances.

a float.

and then

if ( float < 21 )

I’d use the read to work with directly. It’s faster and easier, takes less code and RAM.
Turning it into more digits does not improve the accuracy. Only convert to show to humans.

PS: AVR datasheet, ADC Absolute Accuracy is +/- 2 LSB’s. The read can be off +/- 2.