LCD display ON or OFF ? (temp/fan)

I just can't figure out how to properly display digitalWrite on my LCD in my sketch.

When the temperature goes in between min and max fan status disappaere from my display, no matter if it is LOW or HIGH(ON or OFF), but if it goes out of that range it shows normally.

How do I solve this, I searched for bool, but I get confused, how to implement it

#include <Wire.h>
#include "DHT.h"
#include "LiquidCrystal.h"
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
#define DHTPIN 8
#define DHTTYPE DHT22
DHT sensor(DHTPIN, DHTTYPE);

const int vent = 12;        // ventilation relay pin
const int humy = 11;        // humidifier relay pin

//values to turn off and on ventilation based on temperature (and RH which doesn't works for me too)
float maxTemp = 28.50;
float minTemp = 26.80;
float maxHumy = 55.00;
float minHumy = 53.00;

//values to turn off and on humidifier based on RH
float maxHumy1 = 48.00;
float minHumy1 = 45.00;

void setup() {
  lcd.begin(16, 2);
  sensor.begin();
  digitalWrite(vent, HIGH);
  pinMode(vent, OUTPUT);
  digitalWrite(humy, HIGH);
  pinMode(humy, OUTPUT);
}

void loop() {
  lcd.clear();
  float t = sensor.readTemperature();    //reading the temperature from the sensor
  float h = sensor.readHumidity();       //reading the humidity from the sensor
  h = map(h, 21.8, 91.2, 15.6, 77.6);    //calibration I did to match my hygrometers
  // Checking if the sensor is sending values or not
  if (isnan(t) || isnan(h)) {
    lcd.print("Failed");
    return;
  }
  lcd.setCursor(0, 0);
  lcd.print("T:");
  lcd.print(t);
  lcd.print("C");
  lcd.setCursor(0, 1);
  lcd.print("H:");
  lcd.print(h);
  lcd.print("%");

  //control for ventilation 
  if (t >= maxTemp) {
    digitalWrite(vent, LOW);
    lcd.setCursor(9, 0);
    lcd.print("V:On");
  }
  else if (t <= minTemp) {
    digitalWrite(vent, HIGH);
    lcd.setCursor(9, 0);
    lcd.print("V:Off");
  }

  //controll for humidifier 
  if (h <= minHumy1) {
    digitalWrite(humy, LOW);
    lcd.setCursor(9, 1);
    lcd.print("H:On");
  }
  else if (h >= maxHumy1) {
    digitalWrite(humy, HIGH);
    lcd.setCursor(9, 1);
    lcd.print("H:Off");
  }
}
double map(double x, double in_min, double in_max, double out_min, double out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
  if (t >= maxTemp) {
    digitalWrite(vent, LOW);
    lcd.setCursor(9, 0);
    lcd.print("V:On");
  }
  else if (t <= minTemp) {
    digitalWrite(vent, HIGH);
    lcd.setCursor(9, 0);
    lcd.print("V:Off");
  }
  else {
    //Do something for “normal” here
   }

I get what are you pointing out, but consider range, the temperature is raising from min to max, fan is not working, then other case temperature is decreasing from max to min, fan is working? or if the temperature is decreasing from max to min, but fan isn't working?

See if this works:

#include <Wire.h>
#include "DHT.h"
#include "LiquidCrystal.h"
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
#define DHTPIN 8
#define DHTTYPE DHT22
DHT sensor(DHTPIN, DHTTYPE);

const int vent = 12;        // ventilation relay pin
const int humy = 11;        // humidifier relay pin

//values to turn off and on ventilation based on temperature (and RH which doesn't works for me too)
float maxTemp = 28.50;
float minTemp = 26.80;
float maxHumy = 55.00;
float minHumy = 53.00;

//values to turn off and on humidifier based on RH
float maxHumy1 = 48.00;
float minHumy1 = 45.00;

void setup() {
  lcd.begin(16, 2);
  sensor.begin();
  digitalWrite(vent, HIGH);
  pinMode(vent, OUTPUT);
  digitalWrite(humy, HIGH);
  pinMode(humy, OUTPUT);
  lcd.clear();
}

void loop() {
  //lcd.clear(); <<<< this is your problem, moved to end of setup()
  float t = sensor.readTemperature();    //reading the temperature from the sensor
  float h = sensor.readHumidity();       //reading the humidity from the sensor
  h = map(h, 21.8, 91.2, 15.6, 77.6);    //calibration I did to match my hygrometers
  // Checking if the sensor is sending values or not
  if (isnan(t) || isnan(h)) {
    lcd.print("Failed");
    return;
  }
  lcd.setCursor(0, 0);
  lcd.print("T:");
  lcd.print(t);
  lcd.print("C");
  lcd.setCursor(0, 1);
  lcd.print("H:");
  lcd.print(h);
  lcd.print("%");

  //control for ventilation
  if (t >= maxTemp) {
    digitalWrite(vent, LOW);
    lcd.setCursor(9, 0);
    lcd.print("V:On "); // added a space so both strings are same length
  }
  else if (t <= minTemp) {
    digitalWrite(vent, HIGH);
    lcd.setCursor(9, 0);
    lcd.print("V:Off");
  }

  //controll for humidifier
  if (h <= minHumy1) {
    digitalWrite(humy, LOW);
    lcd.setCursor(9, 1);
    lcd.print("H:On");
  }
  else if (h >= maxHumy1) {
    digitalWrite(humy, HIGH);
    lcd.setCursor(9, 1);
    lcd.print("H:Off");
  }
}
double map(double x, double in_min, double in_max, double out_min, double out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

Maybe better?

#include <Wire.h>
#include "DHT.h"
#include "LiquidCrystal.h"
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
#define DHTPIN 8
#define DHTTYPE DHT22
DHT sensor(DHTPIN, DHTTYPE);

const int vent = 12;        // ventilation relay pin
const int humy = 11;        // humidifier relay pin

//values to turn off and on ventilation based on temperature (and RH which doesn't works for me too)
float maxTemp = 28.50;
float minTemp = 26.80;
float maxHumy = 55.00;
float minHumy = 53.00;

//values to turn off and on humidifier based on RH
float maxHumy1 = 48.00;
float minHumy1 = 45.00;

void setup() {
  lcd.begin(16, 2);
  sensor.begin();
  digitalWrite(vent, HIGH);
  pinMode(vent, OUTPUT);
  digitalWrite(humy, HIGH);
  pinMode(humy, OUTPUT);
  lcd.clear();
}

void loop() {
  //lcd.clear(); <<<< this is your problem, moved to end of setup()
  float t = sensor.readTemperature();    //reading the temperature from the sensor
  float h = sensor.readHumidity();       //reading the humidity from the sensor
  h = map(h, 21.8, 91.2, 15.6, 77.6);    //calibration I did to match my hygrometers
  // Checking if the sensor is sending values or not
  if (isnan(t) || isnan(h)) {
    lcd.print("Failed");
    return;
  }
  lcd.setCursor(0, 0);
  lcd.print("T:");
  lcd.print(t);
  lcd.print("C");
  lcd.setCursor(0, 1);
  lcd.print("H:");
  lcd.print(h);
  lcd.print("%");
  lcd.setCursor(9, 0);   //NEW
  if(digitalRead(vent))  //NEW
    lcd.print("V:Off");  //NEW
   else                  //NEW 
    lcd.print("V:On ");  //NEW added a space so both strings are same length

  lcd.setCursor(9, 1);   //NEW
  if(digitalRead(humy))  //NEW
    lcd.print("H:Off");  //NEW
   else                  //NEW 
    lcd.print("H:On ");  //NEW added a space so both strings are same length  
  //control for ventilation
  if (t >= maxTemp) {
    digitalWrite(vent, LOW);
    //lcd.setCursor(9, 0); // commented out
    //lcd.print("V:On ");  // commented out
  }
  else if (t <= minTemp) {
    digitalWrite(vent, HIGH);
    //lcd.setCursor(9, 0); // commented out
    //lcd.print("V:Off");  // commented out
  }

  //controll for humidifier
  if (h <= minHumy1) {
    digitalWrite(humy, LOW);
    //lcd.setCursor(9, 1); // commented out
    //lcd.print("H:On");   // commented out
  }
  else if (h >= maxHumy1) {
    digitalWrite(humy, HIGH);
    //lcd.setCursor(9, 1); // commented out
    //lcd.print("H:Off");  // commented out
  }
}
double map(double x, double in_min, double in_max, double out_min, double out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

sone0121:
I get what are you pointing out, but consider range, the temperature is raising from min to max, fan is not working, then other case temperature is decreasing from max to min, fan is working? or if the temperature is decreasing from max to min, but fan isn't working?

And what do you want it to display in each of these cases?

If you want it to display the last thing that was displayed, the simple answer, as JCA34F points out, is not to call lcd.clear() in loop which is erasing them.
But then you must make sure that any time you print something to the LCD, if it is printing where something else can be displayed, you print enough characters to erase what may have been there first.

Or you separate your state change logic from your display logic as in the second example. Although JCA34F forgot to comment back in the lcd.clear() for that case, which is what I think was intended.

Thank you @JCA34F, this works just as I wanted.
Is it possible that lcd.clear() blocked my every attempt or was it that I followed wrong examples? Or just that empty space? I tried with digitalRead but I wrote it differently than this.

I thought without lcd.clear() I wouldn't refresh my readings. . .

But yes, I wanted to display only the state of digitalWrite.

Sorry if I'm not expressing correctly, but I'm a total newb to code and still learning all of this.

PS atm I'm also banging my head how to control both high temperature and high humidity with ventilation, without losing range

Learn to “step through” your code a line at a time and “debug” it in your head.
Using your original code....

Ask what if t = 27 and h = 54?
lcd.clear() clears the LCD so it is completely blank.
Then you display the current t and h readings.
Then you check if t is greater than the max, or less than the min and display something in each case. If it is neither you do NOTHING.
Then you check if h is greater than the max, or less than the min and display something in each case. If it is neither you do NOTHING.

Now ask yourself what is displayed where the H an V ON/OFF should go when these conditions are met? What may have been printed there previously or the blank space you started with after lcd.clear()?

TBH it is better not to clear the LCD unless you want to delete everything. Even if you redraw exactly what was there previously it will possibly flicker when you do this.

Yes, thank you very much, now I see much better, and already have an idea in my head.
I always tried to do it the other way around then you explained now :slight_smile:

I didn't have much time to reconfigure my sketch, this is quick mock up, just want to check if I'm on the right trail?

   if (t == Ts && h == Hs)    //added temperature and humidity set point (Ts and Hs)
    if (t > maxTemp){
     lcd.setCursor(10, 0);
     lcd.print("+");
    }
    else if (t < minTemp){
      lcd.setCursor(10,0);
      lcd.print("-");
    }
    else {
       lcd.setCursor(10,0);
       lcd.print(" ");
    }
    if (h > maxHumy){
      lcd.setCursor(10, 1);
      lcd.print("+");
    }
    else if (h < minHumy){
      lcd.setCursor(10, 1);
      lcd.print("-");
    }
    else {
       lcd.setCursor(10,0);
       lcd.print(" ");
    }

or

   if (t == Ts)                    //added temperature and humidity set point (Ts and Hs)
   {
    if (t > maxTemp){
     lcd.setCursor(10, 0);
     lcd.print("+");
    }
    else if (t < minTemp){
      lcd.setCursor(10,0);
      lcd.print("-");
    }
    else {
       lcd.setCursor(10,0);
       lcd.print(" ");
    }
   }
   else if (h == Hs)                     //added temperature and humidity set point (Ts and Hs)
   {
    if (h > maxHumy){
      lcd.setCursor(10, 1);
      lcd.print("+");
    }
    else if (h < minHumy){
      lcd.setCursor(10, 1);
      lcd.print("-");
    }
    else {
       lcd.setCursor(10,0);
       lcd.print(" ");
    }
   }

Doesn’t look like it, sorry. Seems you are back to printing NOTHING (by erasing the display) if the temperature is between Min and Max. Otherwise it will display “+” if above max or “-“ if below min.

Perhaps that’s what you want now, but to me it seems like you will be back to your original complaint of nothing being displayed in the “between min and max” case?

Also you have messed up the set cursor position in the humidity with what looks like a copy and paste error. But I assume that is a typo? You could save yourself that particular headache, and make your code more readable at the same time, by hoisting the common cursor positioning code outside of the if....

    lcd.setCursor(10, 1);
    if (h > maxHumy){
      lcd.print("+");
    }
    else if (h < minHumy){
      lcd.print("-");
    }
    else {
      lcd.print(" ");
    }

Why have you now have introduced variables Ts and Hs? Where are these set? What are they set to?

Your first example only updates the sign symbol for Temperature and Humidity if BOTH t and h are at their “set points”.
The second example updates the temperature sign symbol if t is at its “set point”.
Then updates the humidity sign symbol, but only if temperature was NOT at its “set point” (it’s in the else if clause) but if h IS at its set point (what the “if” of the “else if” statement is saying).

That seems a particularly esoteric requirement, and so is almost certainly not correct. If anything you meant to code humidity as a separate “if” and not as an “else if” of the first condition.

As you are testing for specific things (t == Ts, h == Hs) then these bits of code will execute only in those very specific circumstances. That means the vast majority of the time this code will be displaying nothing. So if you are using lcd.clear the LCD will be blank, otherwise it will be displaying what was displayed in those positions last time that condition was met.

As I said, learn to step through your code in your head. Use a pen and paper to write down the values of variables, and what is on the display, if it helps. Think...
“What happens if h, t, Hs and Ts are these particular values?”
“How will my code behave?”
“Which “if” and which “else if” will execute each time through loop?”
“What text will be left on the LCD after that happens?”

That’s really all there is to any programming problem.

Probably because I'm a mechanic guy and my logic works differently than yours do. Well actually I have different logic there too, most of the colleges says that, but in the end, my results impress them most of the time.

Like, you have experience and practicality at your hands, as you did that several hundred times, and you also know those little tips and tricks on how to make shortcuts without remedying anything else, I didn't know I could place "setCursor" before "if" and then print. Actually JCA34F did that in my sketch, but with so many sleepless days and nights in the last couple of weeks, made me forget, and I was concentrated on something differently at that moment, like wow I also didn't know you can use "if" without "{}". . .

That is just opposite what I do and I have to adjust for this.
I think I will have to take a break for today and sit back again tomorrow or even a day after that and when my head gets clear I will read all of this again and start from scratch.
Don't get me wrong, but I appreciate what are you doing here and I'm thankful as I don't have anyone else to speak with about this stuff.
And I will start with the paper first, then keyboard :wink:

I also didn't know you can use "if" without "{}". .

Only under some circumstances. It would be best practice is to always use {} around the code block even if it only one statement.

sone0121:
Probably because I'm a mechanic guy and my logic works differently than yours do. Well actually I have different logic there too, most of the colleges says that, but in the end, my results impress them most of the time.

Irrespective of how your brain logic works (which may well be different to mine), the computers logic works the same. So I am just saying you need to think about that somehow.

If you have some other way of thinking about how code works, and it produces the results you want, then fine. But it was you who asked "just want to check if I'm on the right trail?"!

The only reason I moved the setCursor was because I found a bug. And a general coding rule (or one that I follow anyway) is only write code once. That means less bugs, or at the very least bigger bugs which are easier to spot (and so less bugs because they DO get spotted)!

I would second UKHeliBob advice about always using { } with "if". It is very good advice. It is actually coding practice in many professional situations too...

Thank you all guys. You made me think more out of the box :slight_smile: and yes I'm sticking to your advices
The challenge is actually what drives me to go even more until it starts working as intended :slight_smile:

Atm I have a bigger concern over my head. Don't wanna start new topics, so I'm gonna ask here. I will get back to LCD after I solve this first.

I'm trying to control both temperature and high humidity on the same pin. Every time I try I lose the minimum set point.
This is newest idea I got, let me know what you think guys

const int vent = 12;        // ventilation relay pin

//values to turn off and on ventilation based on temperature and RH
float maxTemp = 29.00;
float minTemp = 27.00;

float maxHumy = 60.00;
float minHumy = 55.00;

  //control for ventilation

if (digitalRead(vent)){
  if (t > maxTemp){
    digitalWrite(vent, LOW);
  }
  if (t < minTemp){
    digitalWrite(vent, HIGH);
      }
      if (h > maxHumy){
        digitalWrite(vent, LOW);
      }
        if (h < minHumy){
          digitalWrite(vent, HIGH);
      }

That code effectively ignores the temperature because the last thing it checks is the humidity

What do you want the vent to do if the temperature is high and the humidity is low ?

With 2 parameters either high or low there are 4 possible states

Smart question, thank you :slight_smile:

  //control for ventilation
  if (digitalRead(vent)) {
    if (t > maxTemp || h > maxHumy) {
      digitalWrite(vent, LOW);
    }
    if (t > maxTemp && (h < minHumy && maxHumy)) {
      digitalWrite(vent, LOW);
    }
    if (h > maxHumy && t < (minTemp && maxTemp)) {
      digitalWrite(vent, LOW);
    }
  }
  else if (t < minTemp || h < minHumy) {
    if (t < minTemp && h < (minHumy && maxHumy)) {
      digitalWrite(vent, HIGH);
    }
    if (h < minHumy && t < (minTemp && maxTemp)) {
      digitalWrite(vent, HIGH);
    }
  }

But I feel I'm still missing something
Should I include

t > minTemp && t < maxTemp
// and h also
h > minHumy && h < maxHumy
    if (t > maxTemp && (h < minHumy && maxHumy))

This is wrong for a start. It does not test h against maxHumy, rather it tests whether maxHumy is true, which it will always will be

Start by writing down the 4 possible combinations and what you want the vent to do and posting it here

hmm trying to figure out how to set temperature primary and humidity secondary. EDIT: which was wrong!?

so when
temp high, humy high = vent on
temp high, humy low = vent on
temp low, humy high = vent on
temp low, humy low = vent off

so 3 cases on, 1 off

you made me think but not compile :smiley:

so maybe something like

  //control for ventilation
  if (digitalRead(vent)) {
    if (t > maxTemp || h > maxHumy) {
      digitalWrite(vent, LOW);
    }
    if (t > maxTemp && h < minHumy) {
      digitalWrite(vent, LOW);
    }
    if (t < minTemp && h > maxHumy) {
      digitalWrite(vent, LOW);
    }
  }
  else if (t < minTemp || h < minHumy) {
           digitalWrite(vent, HIGH);

So, if temp low and humidity low, turn the vent off, else turn it on.

You may want to apply some hysteresis to avoid constant flipping near the set point or use millis to ensure that the vent can only be changed every five minutes.