How to test something that BECOMES as opposed to IS

I have a sketch that I test temperature sensors and based on preset values, change a pin state to turn on an extraction fan. This works until the temp falls below the high value, but I would like for the device to stay on till it reaches the low preset value. So if for example The preset high is 80° and the preset low is 65° and the temp hits 81° or higher, the fun turns on till the temp falls below 80° again. I would like for the fan to activate when the temp hit 81°, but then stay on till the temp is below 65°. This would enable me to maintain a steadier climate. Any feedback? Here is one of the tests, and all other tests use the same approach. The entirety of the sketch is much larger and b/c other things are being done, I feel it would be counter productive to post the whole thing.

  byte f1 = dhtA.readTemperature(true);   // from DHT/A
  byte f2 = dhtB.readTemperature(true);   // from DHT/B
  byte hiMaxTemp = 80;   // temp that triggers heat removal device(s) on
  byte lowMaxTemp = 70;  // temp that triggers heat removal device(s) off
  
  if (f1 >= hiMaxTemp)  //if "f1" is greater than or equal to hiMaxTemp,
  {
    digitalWrite(heatVentA, TURN_ON);  // TURN_ON heatVentA (fan).
    terminal.println("Exhausting the heat from Bloom A"); //  Text printed to terminal monitor
  }

  else if (f1 <= lowMaxTemp)  //  or else if "f1" is less than or equal to lowMaxTemp
  {
    digitalWrite(heatVentA, TURN_OFF); //  TURN_OFF relay E.
  }

Google "hysteresis"

When the temp goes above the max set a boolean variable, let's name it cooling and set it to true. While cooling is true run the fan. When the temp falls below the min set cooling to false and the fan will stop.

The OP's code is already implementing Hysteresis. and is already using a "boolean variable" in the form of the current state of Arduino pin "heatVentA"...

My feedback to the OP would be: explain what you need help with. Explain what your code currently does, assuming it does not do what you wanted (otherwise why would you have posted at all).

Maybe even post all the code, if it doesn't behave as you expect

My apologies, heatVentA is a relay on a digital pin. I think UKHeliBob's advice will work best, thanks Bob! I see the boolean will hold the pin state as I desire until the low value to breached.

myggle: My apologies, heatVentA is a relay on a digital pin. I think UKHeliBob's advice will work best, thanks Bob! I see the boolean will hold the pin state as I desire until the low value to breached.

Actually, looking back at the code snippet that you posted I think it should work as it is.

The code seems to say "if the temperature gets too high turn the fan on and leave it on, but if the temperature gets too low turn the fan off". Is that what it does and is that what you want ?

Mind you, we do not know what is going on elsewhere in the program.

The way I have it spelled out leads me to believe that it would work this way, but it does not ever get to the low value, the fan simply turns off when the temps to the high preset. Here is the entire sketch. This issue can be found in the climateRoutine() function.

Sorry - The sketch plus my post exceed 9000 characters. The INO is attached.

The project is a hydroponics controller. An Ethermega, a DS3231RTC, 2 DHT22 sensors, an 8 channel relay for 120VAC~ and a 12V 8 head peristaltic pump dosing module. Everything else works great, just noticed my low preset values are not being considered. I think Bob’s initial suggestion will give me the outcome I seek. If the boolean is made true when the temp exceed the max preset and remains true until the min preset, I presume this is my answer.

sketch_may06a.ino (13.3 KB)

the fan simply turns off when the temps to the high preset

That implies that it is on until the max temp is reached. That can't be right.

Try setting "lowMaxTemp" to 65 instead of 70. Is the fan capable of pulling temp that low?

UKHeliBob: That implies that it is on until the max temp is reached. That can't be right.

When the temps elevate above hiMaxTemp, the fan turns on. When the fan exhausts the temp back down to below hiMaxTemp, the fan turns off. W/o using a boolean to keep the fan switched on, it will always be switched off b/c the moment that f1 is no longer greater than or equal to hiMaxTemp, there is no longer any logic in keeping the digital write in it's current state. As you said above, using a boolean will give me a fail safe against such conditions. I actually used booleans elsewhere in the sketch regarding timed events and incoming conflicting commands from Blynk, and that has worked well for me. I clearly overlooked that when starting this thread.

there is no longer any logic in keeping the digital write in it's current state.

The "digitalWrite" (the output pin) will stay in its current state until you do another digitalWrite. You don't need to do anything to keep it in the same state. Assuming the code fragment you posted is the only place that the pin is written to (I'm not going to download & read your attachment on my phone) then as long as the temp reading is between hiMaxTemp and lowMaxTemp, then the pin will stay in its current state because no digitalWrite is executed.

W/o using a boolean to keep the fan switched on, it will always be switched off b/c the moment that f1 is no longer greater than or equal to hiMaxTemp, there is no longer any logic in keeping the digital write in it's current state.

Where, apart from when the temp falls below the lower threshold, do you think that the fan is being turned off ?

The general form of your question is "How do I detect when something has CHANGED?".

And the general answer to that question is "Compare it to what it was the last time you checked it". This means you need to store at least one level of history in memory.

PaulRB:
The “digitalWrite” (the output pin) will stay in its current state until you do another digitalWrite. You don’t need to do anything to keep it in the same state. Assuming the code fragment you posted is the only place that the pin is written to (I’m not going to download & read your attachment on my phone) then as long as the temp reading is between hiMaxTemp and lowMaxTemp, then the pin will stay in its current state because no digitalWrite is executed.

So if a condition is met that changes a digital pin from LOW to HIGH, nothing will happen when that condition is no longer met?

UKHeliBob:
Where, apart from when the temp falls below the lower threshold, do you think that the fan is being turned off ?

When the temp is higher than the max threshold, the fan is on.
When the temp is lower than the max threshold, the fan turns off.
The min threshold is not being considered b/c the min threshold is also below max threshold. When I wrote those lines, it made sense to me that THIS condition turns the device on and the device can’t turn off until THAT condition is met. I do not know why it behaves the way it does, especially when you all are essentially confirming what I originally wrote in the code, but the outcome is not what I expected. The exhaust fans turn on when the temp exceeds the max, but as soon as it’s below the max, it’s no longer on. Maybe my board is faulty?

  if (f1 >= hiMaxTemp)  //if "f1" is greater than or equal to hiMaxTemp,
  {
    digitalWrite(heatVentA, TURN_ON);  // TURN_ON heatVentA (fan).
    terminal.println("Exhausting the heat from Bloom A"); //  Text printed to terminal monitor
  }

  else if (f1 <= lowMaxTemp)  //  or else if "f1" is less than or equal to lowMaxTemp
  {
    digitalWrite(heatVentA, TURN_OFF); //  TURN_OFF relay E.
  }

2 problems.

1 - in your posted code, the bloom A humidity check is operating heat vent B. This is probably what is causing your bug. This is a copy/paste problem.

2 - you check the temperature and then you check the humidity. This means that if the humidity is low, then the fan will be turned off irrespective of what the temperature might be. Is that what you want?

So if a condition is met that changes a digital pin from LOW to HIGH, nothing will happen when that condition is no longer met?

Correct. If you want that to happen you must write more code to detect when the condition is no longer met and set the pin to LOW. Otherwise it will stay HIGH forever (or until power disconnected or reset happens).

1 - in your posted code, the bloom A humidity check is operating heat vent B. This is probably what is causing your bug. This is a copy/paste problem.

I only see the error in the comments, not the actual digitalWrite().

//Functions
void climateRoutine()
{
  byte h1 = dhtA.readHumidity();          // f1 and h1 are fahrenheit and humidity readings
  byte f1 = dhtA.readTemperature(true);   // from DHT/A
  byte h2 = dhtB.readHumidity();          // f2 and h2 are fahrenheit and humidity readings
  byte f2 = dhtB.readTemperature(true);   // from DHT/B
  if (isnan(f1) || isnan(f2) || isnan(h1) || isnan(h2)) {
    terminal.println("Failed to read from a DHT sensor");
    terminal.flush();
    return;
  }
  Blynk.virtualWrite(V0, f1);      //  Set Virtual Pin 0 frequency to PUSH in Blynk app
  Blynk.virtualWrite(V1, h1);      //  Set Virtual Pin 1 frequency to PUSH in Blynk app
  Blynk.virtualWrite(V2, f2);      //  Set Virtual Pin 2 frequency to PUSH in Blynk app
  Blynk.virtualWrite(V3, h2);      //  Set Virtual Pin 3 frequency to PUSH in Blynk app
  //-------------------Bloom A Temp Test---------------------------------------//
  if (f1 >= hiMaxTemp)  //if "f1" is greater than or equal to hiMaxTemp,
  {
    digitalWrite(heatVentA, TURN_ON);  // TURN_ON heatVentA (fan).
    terminal.println("Exhausting the heat from Bloom A"); //  Text printed to terminal monitor
  }

  else if (f1 <= lowMaxTemp)  //  or else if "f1" is less than or equal to lowMaxTemp
  {
    digitalWrite(heatVentA, TURN_OFF); //  TURN_OFF relay E.
  }
  //-----------------------Bloom A Humidity Test-------------------------//
  if (h1 >= hiHum)  //if "h2" is greater than or equal to hiHum,
  {
    digitalWrite(heatVentB, TURN_ON);  // TURN_ON heatVentA (fan).
    terminal.println("Exhausting the RH from Bloom A"); //  Text printed to terminal monitor
  }
  else if (h1 <= lowHum)  //  or else if "h1" is less than or equal to lowHum
  {
    digitalWrite(heatVentB, TURN_OFF);
  }
  //-----------------------Bloom B Temp Test-----------------------------//
  if (f2 >= hiMaxTemp)  //if "f2" is greater than or equal to hiMaxTemp,
  {
    digitalWrite(heatVentB, TURN_ON);  // TURN_ON heatVentA (fan).
    terminal.println("Exhausting the heat from Bloom B"); //  Text printed to terminal monitor
  }
  else if (f2 <= lowMaxTemp)  //  or else if "f2" is less than or equal to lowMaxTemp
  {
    digitalWrite(heatVentB, TURN_OFF);
  }
  //-----------------------Bloom B Humidity Test-------------------------//
  if (h2 >= hiHum)  //if "h2" is greater than or equal to hiHum,
  {
    digitalWrite(heatVentB, TURN_ON);  // TURN_ON heatVentA (fan).
    terminal.println("Exhausting the RH from Bloom B"); //  Text printed to terminal monitor
  }
  else if (h2 <= lowHum)  //  or else if "h2" is less than or equal to lowHum
  {
    digitalWrite(heatVentB, TURN_OFF);
  }
  terminal.flush();
}

Are you certain that you are wired correctly?

#define heatVentA 28          //Relay 7/g  
#define heatVentB 29          //Relay 8/h

I'm certain I've wired correctly. However, I think I may have lost some meaning in my variable names, so I will rename a couple, and reposition the relays in the code so as to only turn on A device to deal with the temps and B device to deal with the humidity. It will be a few days before I can access the project and upload the corrected sketch. Thanks everyone for the great observations and your time of course!