Lcd troubleshooting

Hi everyone!

I can’t figure out why my lcd doesn’t work at all. I have tried to run only lcd part of the code but it didn’t help either.

#include <LiquidCrystal.h>

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

String readString;

void setup() {
        Serial.begin(9600);
        lcd.begin(16, 2);
  	lcd.print("Go");
   }

void loop() {
  
 while (Serial.available()) {
     delay(1); 
	 char c = Serial.read();
     readString += c;
     
    }
       
  if (readString.length() >0) {
     Serial.println(readString);
     
   if (readString == "y") {
	digitalWrite(8, HIGH);
    	lcd.setCursor(0, 1);
        lcd.print("Yellow On");
    }
     
   if (readString == "yoff") {
	digitalWrite(8, LOW);
    	lcd.setCursor(0, 1);
    	lcd.print("Yellow Off");
    }
     
   if (readString == "r") {
	digitalWrite(9, HIGH);
    	lcd.setCursor(0, 1);
    	lcd.print("Red On");
    }
     
   if (readString == "roff") {
	digitalWrite(9, LOW);
    	lcd.setCursor(0, 1);
    	lcd.print("Red Off");
     
    }
     
   if (readString == "w") {
	digitalWrite(10, HIGH);
    	lcd.setCursor(0, 1);
        lcd.print("White On");
    }
     
   if (readString == "woff") {
	digitalWrite(10, LOW);
    	lcd.setCursor(0, 1);
    	lcd.print("White Off");
     
   }
     
     
       readString="";
  }
}

Led resistors are set on 220 Ohm.

Code works, but could be improved, for me using my Uno and 16x2 LCD. Turn off line endings in serial monitor and try it.

line ending.jpg

Karma for a well done first post. Not many new members bother to read the forum guidelines and post code in code tags and include a readable diagram. You can post the image so that we do not have to download it. Here is how.

line ending.jpg

There are a couple of things that I would change.

Using the String class with Arduino can lead to hard to find bugs as Strings can corrupt memory. Read the serial input basics tutorial to see how to receive serial data into a c-string (null terminated character array).

You will notice that old data is left on the display so that if "yellow on" is displayed and you send 'r' the display will show "red on on". If you pad your LCD output strings with spaces so that they are the same length the new data will overwrite the old. So send "red on " the extra spaces will overwrite the left over on, for instance.

If using c-strings, equality does not work (if (readstring == “y”)). Use srtcmp() instead.

The following code works on my Uno. The code illustrates the points that I posted in this and the previous post.
Uses the code from serial input basics to receive the data into a c-string.
Uses strcmp() to do comparisons in the if statements.
Uses padding spaces to overwrite old data.

#include <LiquidCrystal.h>

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

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;

void setup()
{
   Serial.begin(9600);
   lcd.begin(16, 2);
   lcd.print("Go");
}


void loop()
{
   recvWithEndMarker();
   //showNewData();
   if (newData == true)
   {
      Serial.println(receivedChars);

      if (strcmp(receivedChars, "y") == 0)
      {
         digitalWrite(8, HIGH);
         lcd.setCursor(0, 1);
         lcd.print("Yellow On");
      }

      if (strcmp(receivedChars, "yoff") == 0)
      {
         digitalWrite(8, LOW);
         lcd.setCursor(0, 1);
         lcd.print("Yellow Off");
      }

      if (strcmp(receivedChars, "r") == 0) 
      {
         digitalWrite(9, HIGH);
         lcd.setCursor(0, 1);
         lcd.print("Red On     ");
      }

      if (strcmp(receivedChars, "roff") == 0)
      {
         digitalWrite(9, LOW);
         lcd.setCursor(0, 1);
         lcd.print("Red Off     ");

      }

      if (strcmp(receivedChars, "w") == 0)      
      {
         digitalWrite(10, HIGH);
         lcd.setCursor(0, 1);
         lcd.print("White On    ");
      }

      if (strcmp(receivedChars, "woff") == 0)
      {
         digitalWrite(10, LOW);
         lcd.setCursor(0, 1);
         lcd.print("White Off    ");

      }
      newData = false;
   }
}

void recvWithEndMarker()
{
   static byte ndx = 0;
   char endMarker = '\n';
   char rc;

   while (Serial.available() > 0 && newData == false)
   {
      rc = Serial.read();

      if (rc != endMarker)
      {
         receivedChars[ndx] = rc;
         ndx++;
         if (ndx >= numChars)
         {
            ndx = numChars - 1;
         }
      }
      else
      {
         receivedChars[ndx] = '\0'; // terminate the string
         ndx = 0;
         newData = true;
      }
   }
}

void showNewData()
{
   if (newData == true)
   {
      Serial.print("This just in ... ");
      Serial.println(receivedChars);
      newData = false;
   }
}

Sorry, almost forgot to say that you will need to enable newline in the line endings in serial monitor for the above to work.

Thank you for your reply!

The code you made is fantastic! Your code with c-strings is running much faster than mine (good to know for me).

I will be extremely thankful if you would help me with one more thing.
I need to manually control the brightness of the white led.
Basically: User types a value from 0 to 255 and the white led changes its brightness based on the value.

I have spent 3 days trying to make it work but no result. How would you do it? A code example would be very useful for me!

Here is how I would do what you ask. I use the strtok() function to split a string that is input through serial monitor. Enter “b, brightness value” (b,127). The strtok() function splits the input at the comma, creating 2 strings in an array. The second string (index 1) is the number that I convert from a string to an int with the atoi() function. Note that I gave the LED pins names cause I don’t like using pin numbers in the body of the code.

#include <LiquidCrystal.h>

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

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;

const byte yellowLed = 8;
const byte redLed = 9;
const byte whiteLed = 10;

void setup()
{
   Serial.begin(9600);
   lcd.begin(16, 2);
   lcd.print("Go");
}


void loop()
{
   recvWithEndMarker();
   //showNewData();
   if (newData == true)
   {
      Serial.println(receivedChars);

      if (strcmp(receivedChars, "y") == 0)
      {
         digitalWrite(yellowLed, HIGH);
         lcd.setCursor(0, 1);
         lcd.print("Yellow On");
      }

      if (strcmp(receivedChars, "yoff") == 0)
      {
         digitalWrite(yellowLed, LOW);
         lcd.setCursor(0, 1);
         lcd.print("Yellow Off");
      }

      if (strcmp(receivedChars, "r") == 0)
      {
         digitalWrite(redLed, HIGH);
         lcd.setCursor(0, 1);
         lcd.print("Red On     ");
      }

      if (strcmp(receivedChars, "roff") == 0)
      {
         digitalWrite(redLed, LOW);
         lcd.setCursor(0, 1);
         lcd.print("Red Off     ");

      }

      if (strcmp(receivedChars, "w") == 0)
      {
         digitalWrite(whiteLed, HIGH);
         lcd.setCursor(0, 1);
         lcd.print("White On    ");
      }

      if (strcmp(receivedChars, "woff") == 0)
      {
         digitalWrite(whiteLed, LOW);
         lcd.setCursor(0, 1);
         lcd.print("White Off    ");
      }

      // this is how I would do it.  There is probably a "better" way, but I use strtok for this.
      // the strtok() function is used to split a string at the delimiters (in this case a comma).
      // enter "b,brightness value" in serial monitor (ex. b,128)

      if (receivedChars[0] == 'b') // you can use == if comparing a single element of a string to a character
      {
         char *strings[2]; // pointers to 2 character arrays
         char *ptr = NULL; // create a pointer 
         byte index = 0; 
         ptr = strtok(receivedChars, ",");  
         while (ptr != NULL)
         {
            strings[index] = ptr; 
            index ++;
            ptr = strtok(NULL, ",");
         }
         int brightness = atoi(strings[1]);
         Serial.println(brightness);
         analogWrite(whiteLed, brightness);
      }
      newData = false;
   }
}

void recvWithEndMarker()
{
   static byte ndx = 0;
   char endMarker = '\n';
   char rc;

   while (Serial.available() > 0 && newData == false)
   {
      rc = Serial.read();

      if (rc != endMarker)
      {
         receivedChars[ndx] = rc;
         ndx++;
         if (ndx >= numChars)
         {
            ndx = numChars - 1;
         }
      }
      else
      {
         receivedChars[ndx] = '\0'; // terminate the string
         ndx = 0;
         newData = true;
      }
   }
}

void showNewData()
{
   if (newData == true)
   {
      Serial.print("This just in ... ");
      Serial.println(receivedChars);
      newData = false;
   }
}

Thank you so much!

By the way I have found the reason why my LCD wasn't working. The problem was in potentiometer, it was set on max value, I turned it to 0 and the LCD started working like a charm.

I learned a lot of important new things from you. Thank you again!

Have a wonderful day!

deepfocus40k:
Thank you so much!

By the way I have found the reason why my LCD wasn't working. The problem was in potentiometer, it was set on max value, I turned it to 0 and the LCD started working like a charm.

I learned a lot of important new things from you. Thank you again!

Have a wonderful day!

WATCH THIS SPACE . . . for a message from Paul_B.

Don

Oh ... right ... OK!

Ah yes, I have been exceptionally busy at work in the absence of my wife. :astonished:

Wasn't watching the message carefully enough! :roll_eyes:

Didn't check the "what does 'doesn't work' actually mean?" part.

Disconnect the end of the potentiometer that connects to 5 V. This is a silly mistake slavishly copied from one amateur design to another over the years on these displays. It would not have cured setting a 10k potentiometer to the wrong end (but would if the potentiometer had been 1k) but it will make setting the contrast exactly twice as easy! :grinning: