IF Statement: Comparing two sensor values

Hi everyone,
I am quite new to Arduino and I could solve every problem on my own in the past. I studied Arduino on my own, therfore please be pacient with me if the following problem might be simple to solve...

I have two DHT22 sensors to power a fan with two if-statements, but I can't get it to work propperly. In this example

  • the temperature inside (tempIN) needs to be in between 5 and under 25 degrees of celsius, AND
  • the average temperature outside (averageTempOUT) has to be higher than the temperature inside minus 2 degrees celsius AND
  • the humidity outside (humOUT) has to be smaller or equal to the average humidity inside.
   if ((tempIN < 25 && tempIN > 5) && (averageTempOUT > (tempIN - 2)) && (humOUT <= averageHumIN)) {

When I run the code the fan starts even though the temperature difference is not met. The same with the humidity. In this example the humidity inside should be at least 15% higher than that of the average humidity outside.

((tempOUT < 35 && averageTempOUT > 19) && (humIN > 60 && (averageHumOUT < (humIN - 15))))

Has somebody a suggestion why the statements aren't working?
Thank you!

The problem is in line 12 of your program.

Paul

My guess is your calculation of average is wrong, but it can be anywhere in the code you are hiding from us.
You could print your values to serial monitor as debugging tool.

Paul_KD7HB:
The problem is in line 12 of your program.
Paul

Sorry to ask, but where so you see line 12 in my post? I'm not hiding anything, it's rather long... and I am also a bit embarrassed.

Gonna need a bigger stick

Felipe2017:
Sorry to ask, but where so you see line 12 in my post? I'm not hiding anything, it's rather long... and I am also a bit embarrassed.

The point is the source of your error may be anywhere in your code, not in the few lines you are showing.

Paul

Well, this is the code - IN TWO PARTS - as it is longer than 9000 characters...
PART ONE

// PARAMETERS
#define LOOPS_VENTILATOR 5

// DHT
#include "DHT.h" 
DHT dht22in(3, DHT22);
DHT dht22out(2, DHT22);

// VARIABLES
// [several integers]

int relay_fan(7);                                // Relay for FAN on pin 7

// SETUP
void setup(void) {
  pinMode(7, OUTPUT);                            // Relay FAN
  digitalWrite(7, HIGH);                         // Relay FAN is OFF!
  Serial.begin(9600);                            // Open serial communications

  dht22in.begin();
  dht22out.begin();

// SMOOTHING
  for (int thisReadingTempIN = 0; thisReadingTempIN < SMOOTHING_TEMP_INSIDE; thisReadingTempIN++) {
    ReadingsTempIN[thisReadingTempIN];           // Initialize all readings to 0
  }
  for (int thisReadingTempOUT = 0; thisReadingTempOUT < SMOOTHING_TEMP_OUTSIDE; thisReadingTempOUT++) {
    ReadingsTempOUT[thisReadingTempOUT] = 0;     // Initialize all readings to 0
  }
  for (int thisReadingHumIN = 0; thisReadingHumIN < SMOOTHING_HUMIDITY_INSIDE; thisReadingHumIN++) {
    ReadingsHumIN[thisReadingHumIN] = 0;         // Initialize all readings to 0
  }
  for (int thisReadingHumOUT = 0; thisReadingHumOUT < SMOOTHING_HUMIDITY_OUTSIDE; thisReadingHumOUT++) {
    ReadingsHumOUT[thisReadingHumOUT] = 0;       // Initialize all readings to 0
  }
}

// LOOP
void loop(void) {
  int i = 0;                                     // Integer for operations and calculations
  resetLoopcount++;                              // Counting loops since last reset / new power source
  dayLoopcount++;                                // Counting loops of the day

  float humIN = dht22in.readHumidity();
  float tempIN = dht22in.readTemperature();      // Read temperature as Celsius

  for (tempIN == 0; i < 7; i++) {                // Read sensor 7 times if temp == 0°C
    tempIN = dht22in.readTemperature();
    delay(2000);
  }
  float humOUT = dht22out.readHumidity(); 
  float tempOUT = dht22out.readTemperature();    // Read temperature as Celsius

  for (tempOUT == 0; i < 7; i++) {               // Read sensor 7 times if temp == 0°C
    tempOUT = dht22out.readTemperature();
    delay(2000);
  }

// SMOOTHING
  totalTempIN = totalTempIN - ReadingsTempIN[readTempIN];    // Subtract the last reading
  ReadingsTempIN[readTempIN] = tempIN;               // Read from the sensor
  totalTempIN = totalTempIN + ReadingsTempIN[readTempIN];    // Add the reading to the <totalRadiation>
  readTempIN = readTempIN + 1;                   // Advance to the next position in the array
  if (readTempIN >= SMOOTHING_TEMP_INSIDE) {         // If we're at the end of the array...
    readTempIN = 0;                              // ...wrap around to the beginning
  }
  averageTempIN = totalTempIN / SMOOTHING_TEMP_INSIDE;// Calculate the <averageRadiationA>

  totalTempOUT = totalTempOUT - ReadingsTempOUT[readTempOUT]; // Subtract the last reading
  ReadingsTempOUT[readTempOUT] = tempOUT;                // Read from the sensor
  totalTempOUT = totalTempOUT + ReadingsTempOUT[readTempOUT];// Add the reading to the <totalRadiation>
  readTempOUT = readTempOUT + 1;                 // Advance to the next position in the array
  if (readTempOUT >= SMOOTHING_TEMP_OUTSIDE) {       // If we're at the end of the array...
    readTempOUT = 0;                             // ...wrap around to the beginning
  }
  averageTempOUT = totalTempOUT / SMOOTHING_TEMP_OUTSIDE;        // Calculate the <averageRadiationA>

  totalHumIN = totalHumIN - ReadingsHumIN[readHumIN];        // Subtract the last reading
  ReadingsHumIN[readHumIN] = humIN;              // Read from the sensor
  totalHumIN = totalHumIN + ReadingsHumIN[readHumIN];        // Add the reading to the <totalRadiation>
  readHumIN = readHumIN + 1;                     // Advance to the next position in the array
  if (readHumIN >= SMOOTHING_HUMIDITY_INSIDE) {           // If we're at the end of the array...
    readHumIN = 0;                               // ...wrap around to the beginning
  }
  averageHumIN = totalHumIN / SMOOTHING_HUMIDITY_INSIDE;  // Calculate the average

  totalHumOUT = totalHumOUT - ReadingsHumOUT[readHumOUT];    // Subtract the last reading
  ReadingsHumOUT[readHumOUT] = humOUT;           // Read from the sensor
  totalHumOUT = totalHumOUT + ReadingsHumOUT[readHumOUT];    // Add the reading to the <totalRadiation>
  readHumOUT = readHumOUT + 1;                   // Advance to the next position in the array
  if (readHumOUT >= SMOOTHING_HUMIDITY_OUTSIDE) {         // If we're at the end of the array...
    readHumOUT = 0;                              // ...wrap around to the beginning
  }
  averageHumOUT = totalHumOUT / SMOOTHING_HUMIDITY_OUTSIDE;// Calculate the average

PART TWO

   if ((tempIN < 25 && tempIN > 5) && (averageTempOUT > (tempIN - 2)) && (humOUT <= averageHumIN)) {
    Serial.println(F("      ACTION WARMING: ((tempIN < 25 && tempIN > 5) && (averageTempOUT > (tempIN - 2)) && (humOUT <= averageHumIN))"));
    digitalWrite(relay_fan, LOW);                // LOW = Relay is ON!
  } else if ((tempOUT < 35 && averageTempOUT > 19) && (humIN > 60 && (averageHumOUT < (humIN - 15)))) {
    Serial.println(F("      ACTION HEAVY DEHUMIDIFYING: ((tempOUT < 35 && averageTempOUT > 19) && (humIN > 60 && (averageHumOUT < (humIN - 15))))"));
    digitalWrite(relay_fan, LOW);                // LOW = Relay is ON!!
  } else if ((tempOUT < 35 && averageTempOUT > 18) && (humIN > (humOUT - 5))) {
    Serial.println(F("      ACTION DEHUMIDIFYING: ((tempOUT < 35 && averageTempOUT > 18) && (humIN > (humOUT - 5)))"));
    digitalWrite(relay_fan, LOW);                // LOW = Relay is ON!!
  } else if (tempOUT == 0) {
    Serial.println(F("      ACTION SENSOR OUTSIDE not working propperly! Ventilation stays off."));
    digitalWrite(relay_fan, HIGH);               // HIGH = OFF!!
    defLoopcountOUT++;
    delay(1000);
  } else if (tempIN == 0) {
    Serial.println(F("      ACTION SENSOR INSIDE not working propperly! Ventilation stays off."));
    digitalWrite(relay_fan, HIGH);               // HIGH = OFF!!
    defLoopcountIN++;
  } else {
    if (trackingLoopcount > 0) {
      Serial.print(F("      ACTION VENTILATION now switching OFF. Past loops: "));
      Serial.println(activeLoopcount);
    }
    digitalWrite(relay_fan, HIGH);
  }
}

As several people have a look at it, someone might have an improvement for building the average a more efficient way as the first loops start close to zero, therefore the switching for the fan waits for five loops to start when the if statements are true.
Thank you again for your help!

Good day,
I am a bit surprised that nobody responded... :o Did I mess up everything in the code or does nobody have an idea why the if statements aren't working properly?

Felipe2017:
Good day,
I am a bit surprised that nobody responded... :o Did I mess up everything in the code or does nobody have an idea why the if statements aren't working properly?

I guess people were hoping you'd whittled your code down sufficiently to put in a single post, and, in the process, figure out where you'd gone wrong.

  for (int thisReadingTempIN = 0; thisReadingTempIN < SMOOTHING_TEMP_INSIDE; thisReadingTempIN++) {
    ReadingsTempIN[thisReadingTempIN];           // Initialize all readings to 0
  }

It's a good job they were all already zero, isn't it? :wink:
for (tempIN == 0; i < 7; i++) {Back to "ForLoops:101" for you, my lad.

Has you followed my advice?

Gabriel_swe:
You could print your values to serial monitor as debugging tool.

   if ((tempIN < 25 && tempIN > 5) && (averageTempOUT > (tempIN - 2)) && (humOUT <= averageHumIN)) {
    Serial.println(F("      ACTION WARMING: ((tempIN < 25 && tempIN > 5) && (averageTempOUT > (tempIN - 2)) && (humOUT <= averageHumIN))"));
    digitalWrite(relay_fan, LOW);                // LOW = Relay is ON!
    Serial.print(tempIN);
    Serial.print(averageTempOUT);
    Serial.print(humOUT);
    Serial.println(averageHumIN);

Gabriel_swe:
Has you followed my advice?

Thank you Gabriel,
Yes indeed I did, as a matter of fact I fumbled around another whole day before I wanted to respond with childish problems one can usually solve alone: First I found out that I can delete the codes quoted from you this morning - and it hasn't any negative effect on the sketch in terms of "missing something" for compiling or running on the Arduino.

In my original code I do use the serial monitor to see the results from each sensor and they do a great job (with correct measurements), therefore your last recommendation wasn't necessary to implement even though I did try that as well. The relay does it's job also, nevertheless the temperature or humidity differences still aren't met correctly, e.g. it turns on even if the temperature outside is equal instead of being higher at least two degrees as it is defined with

(averageTempOUT > (tempIN - 2))

Looks to me that I'm stuck with this project at the moment. Could there be another error in the code? Maybe it would be easier to calculate different averages that are used in the if statements; it annoys me also that those values start close to zero the first loop instead of using the actual data from the sensors. Sometimes bigger changes solve the problem at its first place...

That being said I didn't even manage to do the simple math for the percentage the relay is turned on each day after a declaration in the header of the sketch with "float activityPercentage = 0;"

  activityPercentage = (activeLoopcount / dayLoopcount) * 100;

The result, also shown in the serial monitor, is always zero...

The result, also shown in the serial monitor, is always zero...

If activeLoopcount is less than dayLoopcount, zero is the correct result for integer division.

You can avoid this by casting to floats, or rearranging the expression and using long integer math to avoid overflow:

  activityPercentage = 100L*activeLoopcount / dayLoopcount;

Could there be another error in the code?

Have you fixed the ones I pointed out earlier?
Post your revised code, or attach it, if it is too large

jremington:
You can avoid this by casting to floats, or rearranging the expression and using long integer math to avoid overflow:

  activityPercentage = 100L*activeLoopcount / dayLoopcount;

Thank you very much, that is it! You made my day for this feeling of success after being stuck for such a long time! :slight_smile:

Groove:
Have you fixed the ones I pointed out earlier?

Of course, I am grateful for each comment - and it looks like I do have a long way to go regarding my understanding of Arduino! That is what I meant with my posting an hour ago: I simply deleted both of the codes and the sketch is still running as no change happened.

I think the pic in the attachment with the sensor data shows exactly the problem.

Groove:
Post your revised code, or attach it, if it is too large

Here's the new version of my sketch:

#include "DHT.h"
DHT dht22in(3, DHT22);
DHT dht22out(2, DHT22);

int relay_fan(7);

// SMOOTHING
int ReadingsTempIN[SMOOTHING_TEMP_INSIDE];
int readTempIN;
float totalTempIN;
float averageTempIN;
int ReadingsTempOUT[SMOOTHING_TEMP_OUTSIDE];
int readTempOUT;
float totalTempOUT;
float averageTempOUT;
int ReadingsHumIN[SMOOTHING_HUMIDITY_INSIDE];
int readHumIN;
float totalHumIN;
float averageHumIN;
int ReadingsHumOUT[SMOOTHING_HUMIDITY_OUTSIDE];
int readHumOUT;
float totalHumOUT;
float averageHumOUT;

void setup(void) {
  pinMode(7, OUTPUT);                         // Relay FAN
  digitalWrite(7, HIGH);                         // Relay FAN is OFF!

  Serial.begin(9600);                            // Open serial communications
  while (!Serial) {
    ;
  }
  dht22in.begin();
  dht22out.begin();
}

void loop(void) {
  int i = 0;
  float humIN = dht22in.readHumidity();
  float tempIN = dht22in.readTemperature();
  float humOUT = dht22out.readHumidity();
  float tempOUT = dht22out.readTemperature();

// SMOOTHING
  totalTempIN = totalTempIN - ReadingsTempIN[readTempIN];    // Subtract the last reading
  ReadingsTempIN[readTempIN] = tempIN;               // Read from the sensor
  totalTempIN = totalTempIN + ReadingsTempIN[readTempIN];    // Add the reading to the <totalRadiation>
  readTempIN = readTempIN + 1;                   // Advance to the next position in the array
  if (readTempIN >= SMOOTHING_TEMP_INSIDE) {         // If we're at the end of the array...
    readTempIN = 0;                              // ...wrap around to the beginning
  }
  averageTempIN = totalTempIN / SMOOTHING_TEMP_INSIDE;// Calculate the <averageRadiationA>

  totalTempOUT = totalTempOUT - ReadingsTempOUT[readTempOUT];
  ReadingsTempOUT[readTempOUT] = tempOUT;
  totalTempOUT = totalTempOUT + ReadingsTempOUT[readTempOUT];
  readTempOUT = readTempOUT + 1;
  if (readTempOUT >= SMOOTHING_TEMP_OUTSIDE) {
    readTempOUT = 0;
  }
  averageTempOUT = totalTempOUT / SMOOTHING_TEMP_OUTSIDE;

  totalHumIN = totalHumIN - ReadingsHumIN[readHumIN];
  ReadingsHumIN[readHumIN] = humIN;
  totalHumIN = totalHumIN + ReadingsHumIN[readHumIN];
  readHumIN = readHumIN + 1;
  if (readHumIN >= SMOOTHING_HUMIDITY_INSIDE) {
    readHumIN = 0;
  }
  averageHumIN = totalHumIN / SMOOTHING_HUMIDITY_INSIDE;

  totalHumOUT = totalHumOUT - ReadingsHumOUT[readHumOUT];
  ReadingsHumOUT[readHumOUT] = humOUT;
  totalHumOUT = totalHumOUT + ReadingsHumOUT[readHumOUT];
  readHumOUT = readHumOUT + 1;
  if (readHumOUT >= SMOOTHING_HUMIDITY_OUTSIDE) {
    readHumOUT = 0;
  }
  averageHumOUT = totalHumOUT / SMOOTHING_HUMIDITY_OUTSIDE;

   if ((tempIN < 25 && tempIN > 5) && (averageTempOUT > (tempIN - 5)) && (humOUT <= averageHumIN)) {
    Serial.println(F("     WARMING ((tempIN < 25 && tempIN > 5) && (averageTempOUT > (tempIN - 5)) && (humOUT <= averageHumIN))"));
    digitalWrite(relay_fan, LOW);
  } else if ((tempOUT < 35 && averageTempOUT > 19) && (humIN > 60 && (averageHumOUT < (humIN - 15)))) {
    Serial.println(F("HEAVY DEHUM. ((tempOUT < 35 && averageTempOUT > 19) && (humIN > 60 && (averageHumOUT < (humIN - 15))))"));
    digitalWrite(relay_fan, LOW);
  } else if ((tempOUT < 35 && averageTempOUT > 18) && (humIN > (humOUT - 5))) {
    Serial.println(F("      DEHUM. ((tempOUT < 35 && averageTempOUT > 18) && (humIN > (humOUT - 5)))"));
    digitalWrite(relay_fan, LOW);
  } else if ((tempOUT <= 18 && tempIN > 15) && (humIN > 65 && (averageHumOUT - 10))) {
    Serial.println(F(" COLD DEHUM. ((tempOUT < 19 && tempIN > 16) && (humIN > 65 && (averageHumOUT - 10)))"));
    digitalWrite(relay_fan, LOW);                // LOW = Relay is ON!!
  } else {
    digitalWrite(relay_fan, HIGH);
  }

}
  activityPercentage = 100L*activeLoopcount / dayLoopcount;
  delay(5000);
}

Save yourself some typing

// SMOOTHING
  totalTempIN -= ReadingsTempIN[readTempIN];    // Subtract the last reading
  ReadingsTempIN[readTempIN] = tempIN;               // Read from the sensor
  totalTempIN += tempIN;    // Add the reading to the <totalRadiation>
  readTempIN++;                   // Advance to the next position in the array
  if (readTempIN >= SMOOTHING_TEMP_INSIDE) {         // If we're at the end of the array...
    readTempIN = 0;                              // ...wrap around to the beginning
  }

Groove:
Save yourself some typing

That's a good one - learned sth new again and ajusted the code! But, my friend, the problem stays!

Felipe2017:
I think the pic in the attachment with the sensor data shows exactly the problem.

I don't see it. What should I look for? :confused:
20.3 is between 5 and 25.
24 is larger than 20.3, and even much larger than 20.3 - 5 (=15.3)
51.4 is less or equal to 61.0