Go Down

Topic: LCD displays text sent by serial monitor after pressing a button (Read 8032 times) previous topic - next topic

UKHeliBob

Quote
if I type more than 16 characters, how the display can move to the second row automatically?!?
I don't know if you can do it automatically but by counting the number of characters received and displayed you can use lcd.setCursor() to move to the second line at the right point.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

edondolo

I digged a lot about lcd.setCursor on internet and I also tried hundred of option in order to make the screen working on both 2 lines, but nothing happened!

What I got is something like:

Code: [Select]
int charactersPrinted = 0;
while (Serial.available() > 0) {
  lcd.write(Serial.read());
  charactersPrinted++;
  if (charactersPrinted == 16) {
    // move to the second line
  }
}


but I cannot understand how I could display text on the second line after the 16th character! What I want to have is that, after the 16th character, the 17th appears on the second row! What I might do to move on the new line?


UKHeliBob

In your trials of hundreds of options did you come a cross the setCursor() method of the LCD library ?

Try this
Code: [Select]
byte lcdCurrentColumn = 0;
byte lcdCurrentLine = 0;
while (Serial.available() > 0)
{
  lcd.setCursor(lcdCurrentColumn, lcdCurrentLine);
  lcd.write(Serial.read());
  lcdCurrentColumn++;
  if (lcdCurrentColumn == 16)
  {
    lcdCurrentLine++;
    lcdCurrentColumn = 0;
  }
}

I changed the name of some variables to make it more obvious what is going on.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

edondolo

Oh woooow yes it's running now! As you did is quite clear! :o

There is only one more problem and is that the lcd.clear() doesn't work! After that I send a message on the lcd and it come on second row... it's just goes forward on that row without restart on the first row!

Is it a problem of lcd.clear in the wrong place? Or I need to any value to restart the cursor somewhere?  :'(


Right now this is my code:

Code: [Select]

#include <LiquidCrystal.h>

#define LCD_LIGHT_PIN A4
const int buttonPin = 8; 
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 
int buttonState = 0;
byte lcdCurrentColumn = 0;
byte lcdCurrentLine = 0;


void setup() { 
  lcd.begin(16, 2);
  lcd.setCursor(0,0);
  lcd.setCursor(1,0);
  Serial.begin(9600);
  lcd.noDisplay();

  pinMode(buttonPin, INPUT);

  pinMode(LCD_LIGHT_PIN, OUTPUT);

  digitalWrite(LCD_LIGHT_PIN, LOW);


}

void loop() { 
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH)
  {

    // when characters arrive over the serial port...
    if (Serial.available()) {
      // wait a bit for the entire message to arrive
      delay(100);
      // clear the screen
      lcd.clear();

      // read all the available characters
      while (Serial.available() > 0) {


        lcd.setCursor(lcdCurrentColumn, lcdCurrentLine);
        lcd.write(Serial.read());
        lcdCurrentColumn++;
        if (lcdCurrentColumn == 16)
        {
          lcdCurrentLine++;
          lcdCurrentColumn = 0;

        }
      }

      digitalWrite(LCD_LIGHT_PIN, HIGH);

      lcd.display();
      delay(5000);

      lcd.noDisplay();


      digitalWrite(LCD_LIGHT_PIN, LOW);


    }
  }
}




I tried several attempt with the setCursor example in the library as well, but nothing happened!

UKHeliBob

You  need to reset lcdCurrentColumn and lcdCurrentLine to zero before starting to display a second or subsequent message.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

edondolo

I'm not really sure if I know how do it! I mean I tried to reset the setCursor with lcd.home/clean at end of the loop and the display stops running, I tried setting up the cursor on (0,0) and (1,0) but nothing happened at the end of the loop, I tried to write an if statement after the while(serial.available) in order to say: when you get the 32th characters restart from 1st, but I'm quite sure that it wasn't written well (I don't know exactly how manage it)!!! I even tried to write an else statement after the if... But nothing again! :smiley-roll-sweat:  Could you help me as well to reset the setCursor when the second row is complete pleaseeeee? ::)

UKHeliBob

As I said in reply #19, you need to reset lcdCurrentColumn and lcdCurrentLine to zero before starting to display a second or subsequent message.  

Another way of saying that would be you  need to reset lcdCurrentColumn and lcdCurrentLine to zero after displaying current message.

So, what are you doing in your program after displaying the current message and where are you doing it ?  At that point reset lcdCurrentColumn and lcdCurrentLine to zero as well.

As to resetting the cursor to 0, 0 when the second row is complete, you need to check when lcdCurrentLine is incremented if it becomes 2 and if so set it back to zero.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

edondolo

Actually what I tried to do it is add a if statement after that one that you help me to make works.

Thats what i got

Code: [Select]
//Turning ON/OFF the LCD - Senior 2.0 ;D

#include <LiquidCrystal.h>

#define LCD_LIGHT_PIN A4
const int buttonPin = 8; 
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 
int buttonState = 0;
byte lcdCurrentColumn = 0;
byte lcdCurrentLine = 0;


void setup() { 
  lcd.begin(16, 2);

  Serial.begin(9600);
  lcd.noDisplay();

  pinMode(buttonPin, INPUT);

  pinMode(LCD_LIGHT_PIN, OUTPUT);

  digitalWrite(LCD_LIGHT_PIN, LOW);


}

void loop() { 
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH)
  {

    // when characters arrive over the serial port...
    if (Serial.available()) {
      // wait a bit for the entire message to arrive
      delay(100);
      // clear the screen
      lcd.clear();

      // read all the available characters
      while (Serial.available() > 0) {


        lcd.setCursor(lcdCurrentColumn, lcdCurrentLine);
        lcd.write(Serial.read());
        lcdCurrentColumn++;
        if (lcdCurrentColumn == 16)
        {
          lcdCurrentLine++;
          lcdCurrentColumn = 0;
{
  if (lcdCurrentColumn == 32)
  {
    lcdCurrentLine++;
    lcdCurrentColumn= 0;
  }
}
        }
      }

      digitalWrite(LCD_LIGHT_PIN, HIGH);

      lcd.display();
      delay(5000);

      lcd.noDisplay();


      digitalWrite(LCD_LIGHT_PIN, LOW);


    }
  }
}





 


I thought that trying to tell to the lcd that same that you done, but setting up as value 32... Could be a good solution! But it's not! That's the way that I used to reset lcdCurrentColumn and lcdCurrentLine to zero!

As you can see:

Code: [Select]

{
  if (lcdCurrentColumn == 32) //when the lcd get the character 32
  {
    lcdCurrentLine++;
    lcdCurrentColumn= 0; //come back to the first column
  }
}


Is it completely wrong what I tried to do? How I could solve it?

UKHeliBob

Quote
I thought that trying to tell to the lcd that same that you done, but setting up as value 32
Why ?  The LCD has 2 rows numbered 0 and 1 and 16 columns numbered 0 to 15.

Try this
Code: [Select]

#include <LiquidCrystal.h>

#define LCD_LIGHT_PIN A4
const byte buttonPin = 8;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
byte  buttonState = 0;
byte lcdCurrentColumn = 0;
byte lcdCurrentLine = 0;

void setup()
{
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.setCursor(1, 0);
  Serial.begin(9600);
  lcd.noDisplay();
  pinMode(buttonPin, INPUT);
  pinMode(LCD_LIGHT_PIN, OUTPUT);
  digitalWrite(LCD_LIGHT_PIN, LOW);
}

void loop()
{
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH)
  {
    // when characters arrive over the serial port...
    if (Serial.available()) {
      // wait a bit for the entire message to arrive
      delay(100);
      // clear the screen
      lcd.clear();

      // read all the available characters
      while (Serial.available() > 0)
      {
        lcd.setCursor(lcdCurrentColumn, lcdCurrentLine);
        lcd.write(Serial.read());
        lcdCurrentColumn++;
        if (lcdCurrentColumn == 16)
        {
          lcdCurrentLine++;
          if (lcdCurrentLine == 2)    //if we have gone beyond line 1
          {
            lcdCurrentLine = 0;       //go back to line 0
          }
          lcdCurrentColumn = 0;
        }
      }
      digitalWrite(LCD_LIGHT_PIN, HIGH);
      lcd.display();
      delay(5000);
      lcd.noDisplay();
      digitalWrite(LCD_LIGHT_PIN, LOW);
      lcdCurrentLine = 0;              //put the cursor position back to 0, 0
      lcdCurrentColumn = 0;            //ready to display the next message
    }
  }
}
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

edondolo

Yes it's working now! :)  And thanks to add the comments close to each line, it helps me to understand why you did that! I think that now I got a bit more! When I have to use "if statement" I'm always a bit stuck cause I don't now exactly what I have to write inside!
I have just one more question, why do you used "byte" instead "int"?


Thanks for your patience and time UKHeliBob, you helped me to make my prototype working! I really appreciate it. :D

UKHeliBob

Quote
why do you used "byte" instead "int"?
To save memory.  It does not matter in your program but it is a good habit to get into to use the smallest data type that will do the job.  An int takes two bytes of memory whilst a byte takes one. Again it does not matter here, but the processor can manipulate byte variables faster than larger data types and that too can sometimes be important.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

edondolo

I got it! Thank you very much again, the lcd works super well now!  :smiley-cool:  :D

Go Up