Go Down

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

edondolo

Hello to everyone,

I'm a master student in Interaction design and I'm a beginner in Arduino field, but I really want to improve my knowledge in it as much as possible... And I need of you!

I'm developing a simple project with an LCD screen (16x2) connected to a push button, where I can send a message to the display typing on the serial monitor and the message is displayed for 10 sec after that the button has been pressed. After these 10 seconds, the display turns itself off automatically and I can send a new message to display on it and so on!

This is the code that I'm using to display text on the LCD through the Arduino sketch (it works):


#include <LiquidCrystal.h>

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

void setup() { 
  // Setup the number of columns and rows:
  lcd.begin(16, 2);
  lcd.noDisplay();

  // Set the button pin as an input:
  pinMode(buttonPin, INPUT);

   // Set the LCD display backlight pin as an output:
  pinMode(LCD_LIGHT_PIN, OUTPUT);

  // Turn off the LCD backlight:
  digitalWrite(LCD_LIGHT_PIN, LOW);
}

void loop() { 
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH)
  {
    // Print some text to the LCD:
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Hello");
lcd.setCursor(0, 0);
    lcd.print("world");
    // Turn the backlight on:
    digitalWrite(LCD_LIGHT_PIN, HIGH);

    // Display the text on the LCD.
    lcd.display();

    // Wait for 10 seconds and then turn off the display and backlight.
    delay(10000);
    lcd.noDisplay();
    digitalWrite(LCD_LIGHT_PIN, LOW);
  }
}


This is the modified code that I'm trying to use to send message through the serial monitor but it doesn't works:

#include <LiquidCrystal.h>

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

void setup(){
    // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  lcd.noDisplay();
 
  pinMode(buttonPin, INPUT);

    pinMode(LCD_LIGHT_PIN, OUTPUT);

   digitalWrite(LCD_LIGHT_PIN, LOW);
 
  // initialize the serial communications:
  Serial.begin(9600);
}

void loop()
{
  // 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) {
      // display each character to the LCD
      lcd.write(Serial.read());
    }
  }



  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH)
  {
       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) {
      // display each character to the LCD
      lcd.write(Serial.read());

       digitalWrite(LCD_LIGHT_PIN, HIGH);

       lcd.display();

       delay(10000);
    lcd.noDisplay();
    digitalWrite(LCD_LIGHT_PIN, LOW);
   
 
    }
  }
}
}
}


Now, my question is: how can I write properly the modified code? I need to use the serial monitor to send the message on the screen and not to type what I want to read on the arduino sketch.

Hoping to have been clear,
thanks in advance

Edoardo

jessemonroy650

Edoardo
please repost your code with the markup. LIKE THIS:
Code: [Select]

[code]
    // YOUR CODE HERE
[/code ] //<<== REMOVE BLANK SPACE

edondolo

Done! :)

Here it is the code that I'm trying to make works... but it didn't! Anyone might help me?!?

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;

void setup(){
    // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  lcd.noDisplay();
 
  pinMode(buttonPin, INPUT);

    pinMode(LCD_LIGHT_PIN, OUTPUT);

   digitalWrite(LCD_LIGHT_PIN, LOW);
 
  // initialize the serial communications:
  Serial.begin(9600);
}

void loop()
{
  // 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) {
      // display each character to the LCD
      lcd.write(Serial.read());
    }
  }



  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH)
  {
       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) {
      // display each character to the LCD
      lcd.write(Serial.read());

       digitalWrite(LCD_LIGHT_PIN, HIGH);

       lcd.display();

       delay(10000);
    lcd.noDisplay();
    digitalWrite(LCD_LIGHT_PIN, LOW);
   
 
    }
  }
}
}
}


UKHeliBob

Quote
Here it is the code that I'm trying to make works... but it didn't!
What does it do or not do that is wrong ?
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'm trying to satisfy it is send a message on the lcd through the serial monitor. But when I type into the serial monitor text box and I press "send"... nothing appears on my lcd!  :smiley-neutral:

In the code below I got a if statement about buttonState and and if about Serial.available, is it correct to have this two if statement one after the another or that's not possible? Do I need something in between?
Code: [Select]



  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH)
  {
       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) {
      // display each character to the LCD
      lcd.write(Serial.read());

       digitalWrite(LCD_LIGHT_PIN, HIGH);

       lcd.display();

       delay(10000);
    lcd.noDisplay();
    digitalWrite(LCD_LIGHT_PIN, LOW);
   
 
    }
  }
}
}


UKHeliBob

Quote
is it correct to have this two if statement one after the another or that's not possible?
That is perfectly possible and you could even combine them together like this
Code: [Select]
if (buttonState == HIGH && Serial.available()) {

In the code you posted you seem to be trying to read the serial data twice.  Once at the start of loop() when the LCD display is turned off, then later when the button is pressed but by then there will be no serial data to read.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

edondolo

What I want to achieve it something like:

-send a message through the serial monitor on the lcd
-the lcd gets the message but it is still turned off
-when the push button is pressed the lcd turns on and shows up the message for x seconds
-later on this x seconds the lcd is turned off automatically again

You told me that there is no serial data to read, what does it means? I want that the data that is going to be read is what has been sent to the serial monitor

UKHeliBob

Quote
You told me that there is no serial data to read, what does it means?
It means that when you try to read the serial data for the second time (after pressing the button) the serial data has already been read.

Try reading the serial input and printing it on the LCD with nothing else in the program.  You have a section of code that does this already.
Code: [Select]
 // 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) {
      // display each character to the LCD
      lcd.write(Serial.read());
    }
  }

Do this with the LCD enabled.  Does it work ?
If so then do it with the LCD disabled.  Then, when the button is pressed enable the LCD.  There is no serial data to read at this point because it has already been read and displayed.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

edondolo

Thank you very very very much for your time and for the code improvements! Really appreciate it! This evening I gonna try what you suggest me and I'll tell you if it works or not  :)


Edoardo

UKHeliBob

As I suggested, get the basics working then you can move on.  Let us know your results.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

edondolo

Finally I found time to try to work on it! Now I can send messages through the serial monitor onto the lcd, and when I press the button I can see the message appear. But the problem is that the characters are displayed one after the other, and not all the text in once. I mean: if I type a simple "Hello" and I send it onto the lcd, when I press the button, the screen displays first the "h" after a bit "e" after a bit the "l" and so on! And furthermore I cannot use the second row of the lcd (it is a 16,2 screen), I can just send messages on the first line.

My questions are:
How can I display the whole text onto the lcd in once?
How can I use the second row of the screen?


This is the sketch that I got:

Code: [Select]


//Turning ON/OFF the LCD

#include <LiquidCrystal.h>

#define LCD_LIGHT_PIN A4
const int buttonPin = 8; 
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 
int buttonState = 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(1000);
    // clear the screen
    lcd.clear();
    // read all the available characters
    while (Serial.available() > 0) {
      // display each character to the LCD
      lcd.write(Serial.read());
   

       digitalWrite(LCD_LIGHT_PIN, HIGH);

       lcd.display();

       delay(1000);
    lcd.noDisplay();
    digitalWrite(LCD_LIGHT_PIN, LOW);
   
 
  }
}}}




Thanks in advance again for your time  ;)

UKHeliBob

Quote
the screen displays first the "h" after a bit "e" after a bit the "l" and so on!
Is each character arriving with a 1 second interval by any chance ?  The sort of thing that might be caused by
Code: [Select]
delay(1000);
for instance.

Try Auto Formatting (Ctrl/T) to get rid of the }}} and you might be able to see 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

Yes it is, each character arrives with 1 sec interval! But the problem is: whether I change the delay in a shorter one (i.e. delay 100), also the light of the lcd depends from that delay and I cannot see anything on the screen cause the light goes on and off to fast.
How can I set up a longer delay for "life" light of the screen and one for get the text in once?

thanks for the suggestion of Auto Formatting!

UKHeliBob

The problem is that the delay(1000) is inside the while (Serial.available()) loop.  Why not put all the available characters on the LCD before enabling the display then delaying if you want to ?

I had hoped that formatting the code so that you could see what was in each code block.
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 did as you advice me and it's perfectly working! Now the lcd get the whole text in once. Super thank you very much! :)  :)  :)  :)  :)  :)  :)  :)  :)

Now, other issue! How can I get text on the second row automatically? I mean, if I type more than 16 characters, how the display can move to the second row automatically?!?

Go Up