Getting Switch Cases to print in Serial Monitor and LCD & Updating the LCD

Hello,

I am having issues getting my switch case values to print on the LCD and on the Serial Monitor when the LCD portion of the code is present. (If all the "lcd.print" are not there, the switch cases print on the serial monitor)

Additionally, I was wondering if there was a way to continuously print on the lcd while the void loop still runs in the background.

As of right now it the code works as follows:

  • the void loop runs and prints on the serial monitor
  • the lcd goes through the 3 screens with 3sec delay (time to read the screen)
  • then it waits 5 seconds (LCD has a cleared screen) and runs again
    I don't want to match the lcd delay to the void loop delay because eventually I want the void loop to run every 5–10 mins and I still want the lcd to print out a status report at the current pace.

Thanks!

My code is as follows:

// Include Libraries
#include <dht.h> //humidity and temperature sensor
#include <virtuabotixRTC.h> //real clock
#include <LiquidCrystal.h> // lcd

//Initialize and Define Pins
virtuabotixRTC myRTC(7, 6, 5);

dht DHT;
#define DHT11_PIN 22

const int sensorMin = 120;
const int sensorMax = 800;
int lightsensorPin = A0;


int soilsensorPin = A1;  
int soilsensorValue = 0;  
int soilpercent = 0;


int fanPin = 24;
int relay1 = 31; //humidifier
int relay2 = 33; //grow lamp
int relay3 = 35; //heating pad

int redPin = 9;
int greenPin = 10;
int bluePin = 11;

LiquidCrystal lcd(51, 49, 47, 45, 43, 41);


void setup() {
  
  Serial.begin(9600);

  lcd.begin(16,2); // initializes lcd


  pinMode(fanPin,OUTPUT);
  
  pinMode(relay1,OUTPUT);
  pinMode(relay2,OUTPUT);
  pinMode(relay3,OUTPUT);
  
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT); 


//Start with all relays off
  digitalWrite(relay1,LOW);
  digitalWrite(relay2,LOW);
  digitalWrite(relay3,LOW);


}

void loop() {
// Read Values 
int chk = DHT.read11(DHT11_PIN);

myRTC.updateTime();


int analogLight;
int rangeLight;
analogLight = analogRead(lightsensorPin);
rangeLight = map(analogLight,sensorMin,sensorMax,0,3); 


soilsensorValue = analogRead(soilsensorPin);
soilpercent = convertTosoilpercent(soilsensorValue);
printValuesToSerial();




// If Humidity is high OR Temp is high (>80F): turn fans on
if (DHT.humidity >= 80 || DHT.temperature > 30){
  digitalWrite(fanPin,HIGH);
} else {
  digitalWrite(fanPin,LOW);
}

// If Temp is low (<68F): turn on heating pad
if (DHT.temperature < 20) {
  digitalWrite(relay3,HIGH);
} else {
  digitalWrite(relay3,LOW);
}


// If Time of Day is between 8am and 3pm AND the light sensor detects dim or below: turn relay 2 (the lamp) on
  while (myRTC.hours > 8 && myRTC.hours < 15){
    if (rangeLight < 2){
        //(myRTC.hours > 8 && myRTC.hours < 15 && rangeLight < 2)
    digitalWrite(relay2,HIGH);
    } else { 
    digitalWrite(relay2,LOW);
}
  }

//If the humidity is low: turn on humidifier
if (DHT.humidity < 40) {
  digitalWrite(relay1,HIGH); 
} else {
  digitalWrite(relay1,LOW);
}

//Reflect Soil Moisture with LED: if high = green, if med = blue, if low = red
if (soilsensorValue > 465){
    digitalWrite(greenPin,HIGH);  // green
} else {
    digitalWrite(greenPin,LOW); }
if (soilsensorValue > 257 && soilsensorValue < 464){
  digitalWrite(bluePin,HIGH);  // blue
} else 
 {
    digitalWrite(bluePin,LOW); }
if (soilsensorValue < 256){
    digitalWrite(redPin,HIGH);  // red
} else {digitalWrite(redPin,LOW); }

 switch (rangeLight) 
    {
        
        case 0:
            Serial.println("dark");
            break;
       
        case 1:
            Serial.println("dim");
            break;
        
        case 2: 
            Serial.println("medium");
            break;
       
        case 3:
            Serial.println("bright");
            break;
    }
    
// The following is commented out because otherwise the code doesn't run
//switch (rangeLight) 
//    {
//        case 0:
//            lcd.print("dark");
//            break;
//
//        case 1:
//            lcd.print("dim");
//            break;
//       
//        case 2: 
//            lcd.print("medium");
//            break;
//     
//        case 3:
//            lcd.print("bright");
//            break;

delay(5000);
}

int convertTosoilpercent(int value)
{
  int soilpercentValue = 0;
  soilpercentValue = map(value, 0, 582, 0, 100);
  return soilpercentValue;
}

 void printValuesToSerial()
{
 Serial.print("\nCurrent Date / Time: ");
 Serial.print(myRTC.dayofmonth); //You can switch between day and month if you're using American system
 Serial.print("/");
 Serial.print(myRTC.month);
 Serial.print("/");
 Serial.print(myRTC.year);
 Serial.print(" ");
 Serial.print(myRTC.hours);
 Serial.print(":");
 Serial.print(myRTC.minutes);
 Serial.print(":");
 Serial.println(myRTC.seconds);
 Serial.print("Soil Analog Value: ");
 Serial.print(soilsensorValue);
 Serial.print("\nSoil Humidity: ");
 Serial.print(soilpercent);
 Serial.print("%");
 Serial.print("\nTemperature F = ");
 Serial.println((DHT.temperature*1.8)+32);
 Serial.print("Temperature C = ");
 Serial.println(DHT.temperature);
 Serial.print("Humidity = ");
 Serial.println(DHT.humidity);

 

 lcd.print("Date: ");
 lcd.print(myRTC.dayofmonth); //You can switch between day and month if you're using American system
 lcd.print("/");
 lcd.print(myRTC.month);
 lcd.print("/");
 lcd.print(myRTC.year);

 lcd.setCursor(0,1);
 lcd.print("Time: "); 
 lcd.print(myRTC.hours);
 lcd.print(":");
 lcd.print(myRTC.minutes);
 lcd.print(":");
 lcd.print(myRTC.seconds);
 
 delay(3000);
 lcd.clear();

 lcd.print("Soil Hum: ");
 lcd.print(soilpercent);
 lcd.print("%");

 lcd.setCursor(0,1);
 lcd.print("Air Hum: ");
 lcd.print(DHT.humidity);

 delay(3000);
 lcd.clear();

 lcd.print("Temp F = ");
 lcd.print((DHT.temperature*1.8)+32);

 lcd.setCursor(0,1);
 lcd.print("Temp C = ");
 lcd.print(DHT.temperature);

 delay(3000);
 lcd.clear();
}

Where’s the cursor when you write to the kid?

avr_fred:
Where’s the cursor when you write to the kid?

?

I don't understand

You have to set your cursor for printing on the lcd screen (if you still don't get it: it's all clearly explained in the manual of the LCD library, which you should have read already to know how to handle an LCD screen in the first place).

Furthermore, "void loop" (the loop function) is never running in the background. There are no background processes in the Arduino world, except maybe interrupt handling but that's hardware level.

avr_fred:
Where’s the cursor when you write to the kid?

I think he meant "lcd", not "kid".

I didn't even notice that typo. Apparently my built-in auto-correct works too well :slight_smile:

wvmarle:
You have to set your cursor for printing on the lcd screen (if you still don't get it: it's all clearly explained in the manual of the LCD library, which you should have read already to know how to handle an LCD screen in the first place).

Furthermore, "void loop" (the loop function) is never running in the background. There are no background processes in the Arduino world, except maybe interrupt handling but that's hardware level.

Okay the "kid" was a typo. I was thrown for a loop there

I'll look into it, thanks!

Bonus question, obviously feel free to ignore:
To to the best of your knowledge, if I switch my delay() to millis() would the lcd continue looping through the information and update accordingly?

blckft:
To to the best of your knowledge, if I switch my delay() to millis() would the lcd continue looping through the information and update accordingly?

You can't just replace delay() with millis(), it needs more work than that. See Blink Without Delay for an example on how to regularly update the display while not blocking.

I rarely use lcd.clear() preferring to overwrite values instead. That way you don't get a flickering display. Do keep in mind that writing to an LCD is relatively slow so best to only write every now and then (100 ms intervals, 10 times a second, is what a human will perceive as "instantly" but is a long time for an Arduino in which it can do other things), and/or when data has changed.

wvmarle:
You can't just replace delay() with millis(), it needs more work than that. See Blink Without Delay for an example on how to regularly update the display while not blocking.

I rarely use lcd.clear() preferring to overwrite values instead. That way you don't get a flickering display. Do keep in mind that writing to an LCD is relatively slow so best to only write every now and then (100 ms intervals, 10 times a second, is what a human will perceive as "instantly" but is a long time for an Arduino in which it can do other things), and/or when data has changed.

Another thing to remember is what happens when you overwrite a longer string (or number with more digits) with a shorter string (or number with fewer digits). If you try to overwrite 59 (two digits) with 0 (one digit), you will instead see 09: the 9 at the end is "left over" from the 59 you had previously written.

It might be time to learn about sprintf().

Actually, sprintf() seems to be the exact thing you need.
More info here: sprintf | Liudr's Blog

Actually, this whole thread is about a solution to a problem that need not exist. Date and time together can fit into one line of a 16x2 display. You will need to shorten the year to two digits, and you might need a bit of trickery for months 10 through 12, but it can be done. The soil moisture level, the humidity, and the air temperature can all fit together on the second line, especially if you save room by showing the temperature in either Fahrenheit or Celsius rather than both.