Lcd.print function not working in Loop but works in Setup

Hello, first post so go easy on me. I've checked similar topics but no solution so far.

Initially, I had the problem that the LCD wouldn't print the analogue data. This was the code I had:

// include LCD library
#include <LiquidCrystal.h>

// define constants for wet and dry sensor
const int dry = 595; // value for dry sensor
const int wet = 239; // value for wet sensor
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);


void setup()
{
  Serial.begin(9600); // set serial monitor so values can be monitored via IDE

// set up LCD pins as follows (also see: https://www.arduino.cc/en/Tutorial/LibraryExamples/HelloWorld for setup of LCD):
  // LCD RS pin to digital pin 12
  // LCD Enable pin to digital pin 11
  // LCD D4 pin to digital pin 5
  // LCD D5 pin to digital pin 4
  // LCD D6 pin to digital pin 3
  // LCD D7 pin to digital pin 2
  // LCD R/W pin to GND
  // LCD VSS pin to GND
  // LCD VCC pin to 5V
  // LCD LED+ to 5V through a 220 ohm resistor
  // LCD LED- to GND

  const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; // define pins corresponding with the above setup
  LiquidCrystal lcd(rs, en, d4, d5, d6, d7); // define which pins on the LCD are being used
  lcd.begin(16, 2); // set up the LCD's number of columns and rows
  lcd.print("Soil Moisture: "); // Print a message to the LCD.

  
}

void loop()
{
  int sensorVal = analogRead(A0); // output analogue value as integer
  int percentageHumididy = map(sensorVal, wet, dry, 100, 0); // set analogue value as percentage between 0% and 100%
  Serial.print(percentageHumididy); // print output
  Serial.println("%"); // add "%" sign after output to display as percentage
  

  // SO FAR, THIS PRINTS VALUES IN THE SERIAL MONITOR. NOW WE HAVE TO PRINT TO THE LCD. Above, LCD library should be included in program.
  
  lcd.setCursor(0, 1); // set the LCD cursor to column 0, line 1

  lcd.print(percentageHumididy); // print the sensor value on LCD:
  lcd.println("%"); // add "%" sign after output to display as percentage

  delay(100); // restart loop after 1 second
}

I moved the lines referring to LCD from setup to loop and that fixed it, so now the code I have is:

// include LCD library
#include <LiquidCrystal.h>

// define constants for wet and dry sensor
const int dry = 595; // value for dry sensor
const int wet = 239; // value for wet sensor
LiquidCrystal lcd (12, 11, 10, 5, 4, 3, 2);


void setup()
{
  Serial.begin(9600); // set serial monitor so values can be monitored via IDE

  // set up LCD pins as follows (also see: https://www.arduino.cc/en/Tutorial/LibraryExamples/HelloWorld for setup of LCD):
  // LCD RS pin to digital pin 12
  // LCD Enable pin to digital pin 11
  // LCD D4 pin to digital pin 5
  // LCD D5 pin to digital pin 4
  // LCD D6 pin to digital pin 3
  // LCD D7 pin to digital pin 2
  // LCD R/W pin to GND
  // LCD VSS pin to GND
  // LCD VCC pin to 5V
  // LCD LED+ to 5V through a 220 ohm resistor
  // LCD LED- to GND

}

void loop()
{
  const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; // define pins corresponding with the above setup
  LiquidCrystal lcd(rs, en, d4, d5, d6, d7); // define which pins on the LCD are being used
  lcd.begin(16, 2); // set up the LCD's number of columns and rows
  lcd.print("Soil Moisture: "); // Print a message to the LCD.
  lcd.setCursor(0, 1); // set the LCD cursor to column 0, line 1

  int sensorVal = analogRead(A0); // output analogue value as integer
  int percentageHumididy = map(sensorVal, wet, dry, 100, 0); // set analogue value as percentage between 0% and 100%
  Serial.print(percentageHumididy); // print output
  Serial.println('%'); // add "%" sign after output to display as percentage

  // SO FAR, THIS PRINTS VALUES IN THE SERIAL MONITOR. NOW WE HAVE TO PRINT TO THE LCD. Above, LCD library should be included in program.

  lcd.print(percentageHumididy); // print the sensor value on LCD:
  lcd.println('%'); // add "%" sign after output to display as percentage

  delay(100); // restart loop after 1 second
}

And this works but it's sloppy. I don't understand why it works in loop but not setup. Surely it would be neater to have the constants defined in setup?

Welcome

When you do this in setup() :

LiquidCrystal lcd(rs ...
lcd.begin( ...

You create and use a local variable. This variable is automatically deleted at the end of setup()

The global variable lcd is not used here, so when you use it in loop(), you didn't call the begin method for this instance of the LiquidCrystal class

Correct way to use it:

LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);

void setup()
{
  Serial.begin(9600); // set serial monitor so values can be monitored via IDE
  lcd.begin(16, 2); // set up the LCD's number of columns and rows
  lcd.print("Soil Moisture: "); // Print a message to the LCD.
}

void loop()
{
  lcd.setCursor(0, 1);
  ...

Try this..........

// include LCD library
#include <LiquidCrystal.h>

// define constants for wet and dry sensor
const int dry = 595; // value for dry sensor
const int wet = 239; // value for wet sensor

// set up LCD pins as follows (also see: https://www.arduino.cc/en/Tutorial/LibraryExamples/HelloWorld for setup of LCD):
// LCD RS pin to digital pin 12
// LCD Enable pin to digital pin 11
// LCD D4 pin to digital pin 5
// LCD D5 pin to digital pin 4
// LCD D6 pin to digital pin 3
// LCD D7 pin to digital pin 2
// LCD R/W pin to GND
// LCD VSS pin to GND
// LCD VCC pin to 5V
// LCD LED+ to 5V through a 220 ohm resistor
// LCD LED- to GND

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; // define pins corresponding with the above setup
LiquidCrystal lcd(rs, en, d4, d5, d6, d7); // define which pins on the LCD are being used
//LiquidCrystal lcd (12, 11, 10, 5, 4, 3, 2);

void setup()
{
  Serial.begin(9600); // set serial monitor so values can be monitored via IDE
  lcd.begin(16, 2); // set up the LCD's number of columns and rows
  lcd.print("Soil Moisture: "); // Print a message to the LCD.
}

void loop()
{
  lcd.setCursor(0, 1); // set the LCD cursor to column 0, line 1
  int sensorVal = analogRead(A0); // output analogue value as integer
  int percentageHumididy = map(sensorVal, wet, dry, 100, 0); // set analogue value as percentage between 0% and 100%
  Serial.print(percentageHumididy); // print output
  Serial.println('%'); // add "%" sign after output to display as percentage

  // SO FAR, THIS PRINTS VALUES IN THE SERIAL MONITOR. NOW WE HAVE TO PRINT TO THE LCD. Above, LCD library should be included in program.

  lcd.print(percentageHumididy); // print the sensor value on LCD:
  lcd.println('%'); // add "%" sign after output to display as percentage

  delay(100); // restart loop after 1 second
}

Hi
My code works, apologies I wasn't clearer. I just don't understand why it worked in setupbut not loop.

I have now managed to clear up the code so it is the following, thanks to my pal, Edward, who is well versed in this stuff. I believe it is the same (or very close to) as to what you have stated?

// include LCD library
#include <LiquidCrystal.h>

// define constants for wet and dry sensor
const int dry = 595; // value for dry sensor
const int wet = 239; // value for wet sensor
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; // define pins corresponding with the above setup
LiquidCrystal lcd(rs, en, d4, d5, d6, d7); // define which pins on the LCD are being used
  

void setup()
{
  Serial.begin(9600); // set serial monitor so values can be monitored via IDE
  lcd.begin(16, 2); // set up the LCD's number of columns and rows
  lcd.print("Soil Moisture: "); // Print a message to the LCD.
  
  // set up LCD pins as follows (also see: https://www.arduino.cc/en/Tutorial/LibraryExamples/HelloWorld for setup of LCD):
  // LCD RS pin to digital pin 12
  // LCD Enable pin to digital pin 11
  // LCD D4 pin to digital pin 5
  // LCD D5 pin to digital pin 4
  // LCD D6 pin to digital pin 3
  // LCD D7 pin to digital pin 2
  // LCD R/W pin to GND
  // LCD VSS pin to GND
  // LCD VCC pin to 5V
  // LCD LED+ to 5V through a 220 ohm resistor
  // LCD LED- to GND

}

void loop()
{
  lcd.setCursor(0, 1); // set the LCD cursor to column 0, line 1

  int sensorVal = analogRead(A0); // output analogue value as integer
  int percentageHumididy = map(sensorVal, wet, dry, 100, 0); // set analogue value as percentage between 0% and 100%
  Serial.print(percentageHumididy); // print output
  Serial.println('%'); // add "%" sign after output to display as percentage

  // SO FAR, THIS PRINTS VALUES IN THE SERIAL MONITOR. NOW WE HAVE TO PRINT TO THE LCD. Above, LCD library should be included in program.

  lcd.print(percentageHumididy); // print the sensor value on LCD:
  lcd.print('%'); // add "%" sign after output to display as percentage

  delay(100); // restart loop after 1 second
}

@guix - I appreciate your response. I think some of that still went over my head; I understand what you are saying but I don't understand the principle behind it or why it is that way. But thanks for giving a bit more clarity than what I had previously

This seems to contradict the thread topic

Apologies, I meant it worked in setup but not loop