Display Text in another line when "\n" received

Hello,

I use a plugin for one of my PC games that takes data from the game and then sends it to Arduino via serial. Arduino reads the data and outputs to the 16x4 LCD. Arduino is programmed to write text to a second line of the LCD when it receives '\n' from the plugin:

      if (serial_byte == '\n')
        lcd.setCursor(0, 1);
      else
        lcd.print(char(serial_byte));

That worked great, but recently I received a 20x4 lcd and I have no idea how to make the Arduino display text on four lines... Any suggestions?

you need something like this I guess

int linenr = 0;

void loop()
{
  if (Serial.available() > 0)
  {
    serial_byte = Serial.read();
    if (serial_byte == '\n' || serial_byte == '\r' )
    {
      linenr++;
      if (linenr > 3) linenr = 0;
      lcd.setCursor(0, linenr);
    }
    else
    {
      lcd.print(char(serial_byte));
    }
  }
  ...
}

robtillaart:
you need something like this I guess

int linenr = 0;

void loop()
{
  if (Serial.available() > 0)
  {
    serial_byte = Serial.read();
    if (serial_byte == ‘\n’ || serial_byte == ‘\r’ )
    {
      linenr++;
      if (linenr > 3) linenr = 0;
      lcd.setCursor(0, linenr);
    }
    else
    {
      lcd.print(char(serial_byte));
    }
  }
  …
}

Thanks for answer, but that doesn’t work for me :frowning: All the lines are just scrolling through the LCD. And why had you written “serial_byte == ‘\n’ || serial_byte == ‘\r’” ? I think only ‘\n’ is enough. I think you can help me if show the entire block of code for the lcd:

  // Text length
  int text_len = Serial.read();
  
  // Followed by text
  if (0 < text_len && text_len < 127)
  {
    lcd.clear();
    for (int i = 0; i < text_len; ++i)
    {
      while (Serial.available() == 0) // Wait for data if slow
      {
        delay(2);
      }
      serial_byte = Serial.read();
      if (serial_byte < 0 && serial_byte > 127)
        return;
      
      if (serial_byte == '\n')
        lcd.setCursor(0, 1);
      else
        lcd.print(char(serial_byte));
//      delay(2);
    }
  }

Thanks in advance!

Thanks for answer, but that doesn’t work for me :frowning: All the lines are just scrolling through the LCD.
Can you specify unambiguously what behaviour you want?

And why had you written “serial_byte == ‘\n’ || serial_byte == ‘\r’” ? I think only ‘\n’ is enough.
For robustness sake, carriage return and newline are often combined.

I think you can help me if show the entire block of code for the lcd:
Still what do you want to happen with the 2 extra lines on the LCD?

I want this:
When Arduino receives '\n' from the plugin, to write the text after \n into the new line on the LCD. When it receives another \n, to write in the third line and so on till the fourth line. Your code looked good, but the lcd showed strange things. The texts were scrolling through lines and I could not see anything. I want my LCD to constantly display text on four lines at the same time.

And the code you have sent. Do I have to replace entire block of code that I sent in the answer with your code to display text on four lines?

Does the code you receive always fit a line, or can it be larger ?
2004 displays usually are 2 lines of 40 characters, and are treated as odd and even lines.
So sending a bunch of characters to a 2004 display instread of a 1602, might end up with the characters showing up in line 1, then roll on to line 3 instead of line 2.

Is that what's happening ?

Did you tell the sketch you are using another type of display now ?

MAS3:
Does the code you receive always fit a line, or can it be larger ?
2004 displays usually are 2 lines of 40 characters, and are treated as odd and even lines.
So sending a bunch of characters to a 2004 display instread of a 1602, might end up with the characters showing up in line 1, then roll on to line 3 instead of line 2.

Is that what's happening ?

Did you tell the sketch you are using another type of display now ?

I have introduced the lcd in the setup as 20, 4. What is happening is that the lcd with the code robtillart gave to me is flickering and showing weird things. I just can't describe that. Yes, the code I receive always fits a line. But I don't know how to make the lcd switch the line when it receives \n from the code.

Flickering of the screen usually means it is updated too fast, or constantly cleared and rewritten.
"weird things on the display" might also be explained by that.
So comment out the lcd.clear line in that and see what that does.

Do you want the display to scroll, meaning the contents of line 0 disappears, and that of line 1 gets copied to 0 and so on ?
If so, you need to store the contents of said line somewhere and you can only discard of it after you have received a fourth newline command.
I think that means you need to keep 5 lines stored, and also that you have to manage lines.
Remember that writing to a LCd is relatively slow (so it takes some time), so scrolling is a relatively slow process.
Clearing a line means filling it with spaces which also consumes some time, but not clearing it will mean you might see updated content and old content in the same line.
If you have no appetite for that, you should consider clearing line 0 and rewriting its contents with new data.
This latter thing (except for the clearing part) is what robtillaart's code is supposed to do.
It's real easy to get rid of the /r part in that code if you want to (who knows who many times /r is sent).

MAS3:
Flickering of the screen usually means it is updated too fast, or constantly cleared and rewritten.
“weird things on the display” might also be explained by that.
So comment out the lcd.clear line in that and see what that does.

Do you want the display to scroll, meaning the contents of line 0 disappears, and that of line 1 gets copied to 0 and so on ?
If so, you need to store the contents of said line somewhere and you can only discard of it after you have received a fourth newline command.
I think that means you need to keep 5 lines stored, and also that you have to manage lines.
Remember that writing to a LCd is relatively slow (so it takes some time), so scrolling is a relatively slow process.
Clearing a line means filling it with spaces which also consumes some time, but not clearing it will mean you might see updated content and old content in the same line.
If you have no appetite for that, you should consider clearing line 0 and rewriting its contents with new data.
This latter thing (except for the clearing part) is what robtillaart’s code is supposed to do.
It’s real easy to get rid of the /r part in that code if you want to (who knows who many times /r is sent).

I don’t want anything to scroll. I want my LCD to display four lines of text that it receives from the plugin.

The plugin is written like this:

ss << "Some text for line 1";

ss  << "\n";

ss << "Some text for line 2";

ss << "\n";

ss << "Some text for line 3";

ss << "\n";

ss << "Some text for line 4";

Arduino receives the entire text at the same time. And I want it to just display that text on the next line when it receives that “\n”. And I don’t know how to do that.

Please don't quote entire replies in the next reply.
It's an unnecessary waste of space and it doesn't help in understanding the thread in any way.

Ok, so you want to update the text on the screen all at once.
I thought you had to wait for a line to arrive and then put it on your screen.

In that case, robtillaart did understand it correctly and his solution is supposed to do exactly what you want:
It clears the screen and then writes the 4 lines it receives.

Do you know how fast the updates arrive from that plugin ?
Perhaps they do arrive in a too high frequency so that the above mentioned flickering is explained in my last reply.

Did you try what happens if you do comment out the lcd.clear, as suggested in my last reply ?
If that is an improvement, you can work out a solution where you fill the remaining characters on the actual line with spaces before you go to the next line.
That's not too hard to do, but you need to understand the logic behind it.

I figured that out myself. I changed the plugin code to this:

ss << "Some text for line 1";

ss  << "\1";

ss << "Some text for line 2";

ss << "\2";

ss << "Some text for line 3";

ss << "\3";

ss << "Some text for line 4";

An then changed the Arduino code:

  if (0 < text_len && text_len < 127)
  {
    lcd.clear();
    for (int i = 0; i < text_len; ++i)
    {
      while (Serial.available() == 0) // Wait for data if slow
      {
        delay(2);
      }
      serial_byte = Serial.read();
      if (serial_byte < 0 && serial_byte > 127) return;

      switch (serial_byte) {
        case '\1':
        lcd.setCursor(0,1);
        break;
        case '\2':
        lcd.setCursor(0,2);
        break;
        case '\3':
        lcd.setCursor(0,3);
        break;
        default:
        lcd.print(char(serial_byte));
        break;
      }
    }
  }

That works flawlessly, but I have one problem. I think that could be a plugin issue… Everything is displayed as it has to, but the fourth line on the display looks like "Some text for " I can only display 3,5 lines on the lcd. I have no idea what is happening with the fourth line ending. Any help with this one? Maybe the plugin can’t send that long string…

What is the value of text_len?

// Text length
int text_len = Serial.read();

if textlen is to small your loop might stop and call an lcd.clear().

I think you do not need that if you add a command in the plugin to send a clear screen.
Then everything is under control of the plugin.

      while (Serial.available() == 0); // Wait for data

      serial_byte = Serial.read();
      if (serial_byte < 0 && serial_byte > 127) return;

      switch (serial_byte) {
        case '\4':
        lcd.clear();
        lcd.setCursor(0, 0);  // possibly done by clear?
        break;
       case '\1':
        lcd.setCursor(0, 1);
        break;
        case '\2':
        lcd.setCursor(0, 2);
        break;
        case '\3':
        lcd.setCursor(0, 3);
        break;
        default:
        lcd.print(char(serial_byte));
        break;
      }
    }

robtillaart:

      while (Serial.available() == 0); // Wait for data

serial_byte = Serial.read();
      if (serial_byte < 0 && serial_byte > 127) return;

switch (serial_byte) {
        case ‘\4’:
        lcd.clear();
        lcd.setCursor(0, 0);  // possibly done by clear?
        break;
      case ‘\1’:
        lcd.setCursor(0, 1);
        break;
        case ‘\2’:
        lcd.setCursor(0, 2);
        break;
        case ‘\3’:
        lcd.setCursor(0, 3);
        break;
        default:
        lcd.print(char(serial_byte));
        break;
      }
    }

I don’t really know what is the text_len value. I don’t know why that value is needed. And I don’t know what text_len does. But the code you provided now looks great. So, I have to put in the string “\4” before all of the text that has to be sent to LCD in the plugin and then I don’t need to use the text_len?

EDIT:
I think the text_len is the string length that lcd has to display. The plugin sends length of the string for the LCD.

EDIT 2:
No, that doesn’t work. Without the functions with text_len all LCD characters fill with a random letter. The entire LCD filled with T letters. If I leave the text_len and modify other portions of code with your code the half of the fourth line still shows random characters and these random characters also fils 1/4 of the third line. That’s weird…
I added the “\4” to the beginning of the string for LCD in the plugin. I can display three lines from bottom to top or from top to bottom, but when I want to display four lines, the LCD starts showing weird things on fourth and third lines.
EDIT 3:
I don’t know what is really happening, but I think that the string that I want to show is too long. Maybe the plugin can’t send the string that is that long, maybe the Arduino cannot display that string… I don’t know how to fix this!

I MADE A MISTAKE IN MY FIRST POST IN THIS THREAD! I previuosly used 16x2 LCD display. TWO LINES only.

I understood that, and i bet robtillaart with all his experience also understood.
But also that each line was 16 characters, and now 20.

text_len is your counter that counts what character is to be displayed next.
If you are using another display and have adopted the plugin to sending more data to make optimal use of that new display, you also need to tell your sketch to expect more data to be stored in that array, if you are using an array.
And you need to set the value of text_len to the maximum possible, or to the actual number of bytes that are sent.
The maximum number of bytes will be larger than 80 because of your control commands.
Also check to see /1, /2, /3, and /4 aren't already reserved for some other controls which might mess with your sketch.

@Gustiakas
Can you post (attach) the complete Arduino Sketch you were using for the 16x2 LCD?

robtillaart:
Can you post (attach) the complete Arduino Sketch you were using for the 16x2 LCD?

Yes, of course I can. Here is the code for 16x2 LCD. And I have not created this plugin. I’ve downloaded it.

eurotrucks_dash_4bit.ino (4.93 KB)

MAS3:
If you are using another display and have adopted the plugin to sending more data to make optimal use of that new display, you also need to tell your sketch to expect more data to be stored in that array, if you are using an array.

And you need to set the value of text_len to the maximum possible, or to the actual number of bytes that are sent.
The maximum number of bytes will be larger than 80 because of your control commands.

Also check to see /1, /2, /3, and /4 aren’t already reserved for some other controls which might mess with your sketch.

I don’t know much about C++, so I can’t addopt it for larger display. I don’t know what to edit in it.

Do I need to set the value of text_len in the plugin or in the Arduino code?

No, \1, \2, \3 and \4 are not reserved for any other function. I have previuously tried with \n, \a, \b and the result was the same - broken fourth line.

So, I think you could help if I send the entire plugin source. I only edit the main plugin file "plugin.cpp.

So here are two plugin sources:
plugin_1602 - original plugin for 16x2 display (downloaded from the internet)
plugin_2001 - plugin, I have modified myself to display on 20x4 LCD

plugin_1602.zip (9.32 KB)

plugin_2004.zip (9.96 KB)

Gustiakas:
Yes, of course I can. Here is the code for 16x2 LCD. And I have not created this plugin. I've downloaded it.

OK understand the Arduino 16x2 code in detail now.

I notice there is not a very robust handshake to get in sync.
Did you encounter problems to get started some times?
e.g. "PROTOCOL VERSION ERROR" message?
or that it took some time before messages appeared?

robtillaart:
Did you encounter problems to get started some times?
e.g. “PROTOCOL VERSION ERROR” message?
or that it took some time before messages appeared?

No, I did not encounter any problems with starting, and I haven’t got any error messages or delays when displaying text. Everything displays when it has to be displayed.

I also attached the plugin’s source in the answer to MAS3, so you can take a look at that. I don’t think I had any errors with sync. The display is always very responsive.