Go Down

Topic: Text not printing on LCD whit closed Serial Monitor (Read 326 times) previous topic - next topic

primef

Hello all,

I just connected my LCD Keypad Shield on the Arduino, by putting the whole shield on the Arduino.
I then tested the LCD and it works if I print a string using
Code: [Select]
lcd.print("Hello All")

After that I printed a text that I'm sending from a Raspberry Pi 3 using the Serial connection between Arduino and Raspberry. For this purpose I used
Code: [Select]
if (Serial.available()){
    String text = Serial.readStringUntil('/n');
    lcd.print(text);


However, the text shows up on the LCD only if I have the serial monitor of the Arduino IDE open.
If I close the serial monitor, nothing will show up on the LCD. If I then reopen the serial monitor, the text will print on the LCD.

Is this a normal behaviour? If yes, is there a workaround to avoid it?

Many thanks

MAS3

Hi and welcome.

Guess what this line does:


Code: [Select]
if (Serial.available()){


Right !

It tells to execute the part between the {curly brackets} only if a Serial.available is true.
So the code does exactly what you told it to do, and yes, that's normal behaviour.

If you want to print some text regardless of the serial connection, you need to send whatever you want to print, outside of those {curly braces}.

But put some more thoughts to that.
Does it make sense to print the same text that was read some minutes ago, over and over again ?
 
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

primef

Thanks for your really fast reply.
That of Serial.Available was also my first tought, therefore I used this code
Code: [Select]
  //if (Serial.available()){
    lcd.clear();
    String text = Serial.readStringUntil('/n');
    lcd.print(text);
  //}


and unfortunately the problem persists.

To your second point, I'm absolutely with you. But I had to do something like that because I'm waiting the constantly for text input on the serial from the raspberry. Therefore I need to loop it to poll for something on the line.

MAS3

Hi.

That is exactly what you did in your 1st post.
Putting the print outside the {} would look like this:

Code: [Select]
 if (Serial.available()){
    String text = Serial.readStringUntil('/n');
  }
lcd.print(text);



Try that yet ?

I'm sure you can do something smarter than sending old and not necessarily correct data over and over again, either with your Arduino or with your Pi (or even both).

You could also test to see an updated text was generated, and send the result of that test along with the text.

Updated could also mean the same but still valid data came in.
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

bperrybap

#4
Sep 13, 2017, 01:26 am Last Edit: Sep 13, 2017, 01:29 am by bperrybap
'/n' is not a single character. It is a multi byte character consisting of a slash 0x2f and an n 0x6e or the value 0x2f6e
If you pass that value to a function that expects char type then the upper 8 bits are truncated and the char value will be 0x6e or a character n  which is not a new line.
If you intended it to be a newline that is '\n'

If you had warnings turned on in the IDE (which I highly recommend ALWAYS enabling) you would see a nice red warning message in the IDE window warning you about where you were using this "character".

Also, in order to use that with the serial monitor you must make sure that a newline is what is sent when you press the <ENTER> key. The IDE serial monitor has a setting to set what gets sent when that key is pressed.

----
BTW, IMO,
Microsoft really made a mess of things when it comes to backslahes vs slashes and line terminations - although Apple also screwed up line terminations as well - especially since Unix had figured all this stuff out more than 10 years before either of them came along.

--- bill

primef

That is exactly what you did in your 1st post.
Putting the print outside the {} would look like this:

Code: [Select]
if (Serial.available()){
    String text = Serial.readStringUntil('/n');
  }
lcd.print(text);



Try that yet ?


What I posted in the second post, is as far as I know, does exactly that, because I commented the lines out with //.

'/n' is not a single character. It is a multi byte character consisting of a slash 0x2f and an n 0x6e or the value 0x2f6e
If you pass that value to a function that expects char type then the upper 8 bits are truncated and the char value will be 0x6e or a character n  which is not a new line.
If you intended it to be a newline that is '\n'
Does the problem with the two characters solve by using \n or are they also counted as two characters?

bperrybap

#6
Sep 13, 2017, 04:22 pm Last Edit: Sep 13, 2017, 04:35 pm by bperrybap
backslash has special meaning in C source code. slash is just another character.
so '/n' is a 16 bit value of 0x2f6e and '\n' is an 8 bit value of 0x0a which is linefeed/newline.

'/n' is not normally used. In fact depending on the compiler, compiler version and options used it can be a hard error instead of a warning.

Again, I HIGHLY recommend that you enable warnings in your IDE so you can see issues like this.

--- bill


primef

So I resolved part of the problem. My steps were:
- changed /n to \n
- used another type of approach to read data from serial and print it to lcd (see code below)

Code: [Select]
void serialEvent(){
  String incoming_text = Serial.readStringUntil('\n');
  lcd.clear();
  lcd.print(incoming_text);
}


I used a function given by the Serial Library, which is called when data is available on the Serial line.

But one problem persists. When I send text to the arduino from the raspberry, the first text input is ignored. So for exemple if I send "Hello", the first time I send it, it is like discarded and not shown on the LCD. When I send it the second time all works as it should.

If I open the Serial monitor, instead and to the same actions as above, the first Input is shown to the LCD too.

Seems strange to me, but maybe there is something I'm overlooking. Any ideas?

Again, I HIGHLY recommend that you enable warnings in your IDE so you can see issues like this.

Ok, will do that, thanks.

MAS3

Hi.

I did see the // in your code, but assumed it was some copy mistake.
That's why they were missing in my example.

What i showed is not exactly the same as what you did.
Because you commented out the condition (that serial is available), your code will wait until it sees the \n.
I don't know whether there is some time out There is a time out, you can set its value.
But for the duration of that time out or until the \n arrives, execution of code is halted.
So that is blocking code.
Once the \n passes, the data is sent to the display.

My suggestion (based on what you had before) was sending data to the LCD, regardless of an update to the buffer you created and holding that data.
That's also why i made the 2nd remark.
But because the condition is still in place, it is less blocking.

But you made some changes to your code, and it improved but still isn't what you want it to be.
Did you do your tests sending the same string ?
Because that would make it harder to know what exactly is printed to your LCD.
In that case it might turn out interesting to send "Hello 1", followed by "Hello 2", and so on.
But you might have done some similar test already, i don't know.
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

primef

Hi.
I had a problem with the posting of my thread. I wrote it before you sent your last reply @MAS3, but I don't know if it was posted. For this reason, could you kindly tell me if you are referring to my last reply (4pm) or to the one before it?

Thanks

bperrybap

Another issue you may soon run into is if the number of characters in the string being printed is more than the number of characters on an LCD line.
But we don't know much about your code or your final intentions as you have not shown us your code or told us what you intend to do.

Most lcd keypad shields use a 2x16 display so if you send more than 16 characters to the LCD there will be an issue since since the extra characters will go into LCD memory but will not wrap to the next line on the LCD display.
This is because the hd44780 LCD module is very dumb and does not support any sort of line wrapping. In fact the LCD module chips don't even know the LCD geometry of the physical display.

If you want line wrapping, you could use my hd44780 library with the hd44780_pinIO class which supports end of line wrapping.
You can install it with the IDE library manager.
You can read more about it here:
https://github.com/duinoWitchery/hd44780

--- bill

primef

But you made some changes to your code, and it improved but still isn't what you want it to be.
Did you do your tests sending the same string ?
Because that would make it harder to know what exactly is printed to your LCD.
In that case it might turn out interesting to send "Hello 1", followed by "Hello 2", and so on.
But you might have done some similar test already, i don't know.

Due to this part of text, I think you really referred to my last post (4pm), sorry.
As you already stated, I did a similar test as the one you said.
I declared a variable with value 10 and everytime new data was sent from the raspberry to the arduino (so on the serial line), the variable was first decreased by one and then the value of the variable was printed on the LCD.
The result of the test was: the first time I sent the text from the raspberry, nothing showed up on the LCD, the second time I sent a text the number 9 showed up on the LCD, the third time the number 8 and so on.
To me it sounds like the first text isn't even correctly received, because in that case, for the second text I sent, the number 8 should have been printed out on the LCD.

Another issue you may soon run into is if the number of characters in the string being printed is more than the number of characters on an LCD line.
But we don't know much about your code or your final intentions as you have not shown us your code or told us what you intend to do.

Most lcd keypad shields use a 2x16 display so if you send more than 16 characters to the LCD there will be an issue since since the extra characters will go into LCD memory but will not wrap to the next line on the LCD display.
This is because the hd44780 LCD module is very dumb and does not support any sort of line wrapping. In fact the LCD module chips don't even know the LCD geometry of the physical display.

If you want line wrapping, you could use my hd44780 library with the hd44780_pinIO class which supports end of line wrapping.
You can install it with the IDE library manager.
You can read more about it here:
https://github.com/duinoWitchery/hd44780

--- bill
Many thanks for your proactive help!
Honestly I already encountered that problem and my tought was to create a special pattern in the text I send (e.g. "/$/") and use the functions that the String class offers to divide my text by that pattern.
For example I send "Hello /$/ All!", and take the text until I encounter the /$/ divider, and put it on the first line with lcd.cursor. The part after the divider pattern will then be on the second line, with lcd.cursor.
I really don't know if this solution even works or if it is appropriate, because I didn't implement it yet.
However I will at first give a try to your library on GitHub.

Unfortunately I already shutdown all my "IoT Infrastructure"  :)  for today, so I will post the full code of my Arduino and the python code of the raspberry, tomorrow (I actually will soon do a GitHub repository for my whole project, just in case someone is interested in a diy surveillance system  :)  ).

bperrybap

However I will at first give a try to your library on GitHub.
Install it using the library manager vs manually or even using a zip install.
The instructions for how to use the library manager on the github page.

--- bill

MAS3

Hi.

I was indeed addressing both of your posts since my last reply.
You asked while referring to the timestamps of your posts, but these forum timestamps are tied to a user's time zone.
We seem to be in different time zones so that doesn't help too much in identifying which post you are mentioning.

So you did do a similar test.
It's always helpful to tell about what you already did try and what you learned from that.
Because someone willing to help can't know what you left out and might suggest things you already tried.
But good for you that you already tried that to be sure what's going on is what you suspected to be happening.

bperrybap's library is also my new standard library for these types of displays, i really like it.
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

primef

Install it using the library manager vs manually or even using a zip install.
The instructions for how to use the library manager on the github page.

--- bill
Hi,

really well done job with that library. I'm using it now for my project and it is really easy to enable the linewrap. On top of that the "old" functions of LiquidCrystal are still available.

So you did do a similar test.
It's always helpful to tell about what you already did try and what you learned from that.
Because someone willing to help can't know what you left out and might suggest things you already tried.
But good for you that you already tried that to be sure what's going on is what you suspected to be happening.

Ok, sorry for that. Next time will be more explicit on my tests. As solution for the moment, I implemented a workaround. I send from the raspberry as first request an empty one, so that it "enables" the LCD.

About my code postings, I didn't post my code because it increased in complexity in a fast way. For this reason I will post my GitHub repository as soon, as it is in a decent status (2-3 days), and refer to it, to show the error.

But for the moment many thanks.

Go Up