Displaying strings on a 16x2 i2c display

Hello, i would like to ask a few questions about whether i could find somewhere some examples of how could i print serial monitor inputs longer than the 16 characters limit of a 16x2 display.

I've tried so far the basic example that comes with the arduino IDE but i can't seem to wrap my head around how to do what i want exactly, and i'm fairly new to all this, meaning that i've just started with programming.

I tried doing some things that seemed logical to me, but they yielded unexpected results or completely failed.

What i'm trying to do is as follows:

Read the input that i type and submit in the serial monitor, store it somehow, and display it on the 16x2 display, however, if the input is larger than 16 characters, i would like to have it scroll across the screen to display it whole, or divide it in the 2 lines that it has.

I have no idea where to begin even, and from what i've tried untill now, nothing works. An example of how to do this would help me great to understand everything.

Thank you!

(I won't post code because i don't really know how to format it properly).

Welcome to the forum

Please post your best effort and describe the problems that you have with it

I recommend using the hd44780 library.
It provides a long line wrapping capability that can be enabled with a single API call.
i.e. you just call lineWrap() to enable it.

It even comes with an example to demonstrate the capability. LineWrap
The hd44780 library is available in the IDE library manager so you can install it quickly and easily with no manual download.

It also comes with a sketch that shows how to read strings from the serial port and display them on the LCD:
Serial2LCD

Since it supports multiple interfaces, it has an i/o class for each type of h/w.
You will need to use the proper i/o class for your h/w.
Here are two common i/o classes:
For an lcd controlled directly by arduino pins you would use
hd44780_pinIO
For an lcd controlled by a PCF8574 based backpack you would use
hd44780_I2Cexp

Here is a link to the Wiki

--- bill

1 Like

Thank you for your answers!

So, i will describe this more properly.
The screen has 16 characters per row, and i want to be able to sent to it text longer than 16 characters, and when i do this, the text will scroll.

This is one of the instances of code i managed to do by myself. ( It doesn't work because i don't really know what i'm doing btw)

[code]

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2); 

void setup()
{
  lcd.init(); 
  lcd.backlight();
  Serial.begin(9600);
  lcd.blink();
}

void loop()
{
  if (Serial.available()) {
    delay(100);
    lcd.clear();
    while (Serial.available() > 0) {
      lcd.write(Serial.read());
    }
  }
  if (Serial.read() > 16) {
  for (lcd.scrollDisplayLeft()=0, lcd.scrollDisplayLeft() < 128, lcd.scrollDisplayLeft()++)
  }
  
}
[/code]

In the hd44780 library there are the scrollDisplayLeft() and scrollDisplayRight() functions. Call the function before a print to shift the whole display one character to the left or right. Count characters and if more than 16, scroll and print the next character.

Please take a look on the code i pasted in the post before yours, am i doing it correctly? That's what i'm trying to do for a while, but i'm really noob.

That is not how to use the function. Call the function before each print . That will shift the whole display one character to the left or right. Then print to the new blank spot. Count characters and if more than 16, scroll and print the next character.

Here is a demo that shows what I posted before.

#include <Wire.h>
#include <hd44780.h>                       // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header

hd44780_I2Cexp lcd; // declare lcd object: auto locate & auto config expander chip

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

boolean newData = false;
byte ndx = 0;

// LCD geometry
const int LCD_COLS = 16;
const int LCD_ROWS = 2;

void setup()
{
   lcd.begin(LCD_COLS, LCD_ROWS);
   lcd.clear();
   lcd.print("Hello World");
   Serial.begin(115200);
   Serial.println("Type in a upto 40 characters and send");
   Serial.println("make sure newline is enabled in serial monitor line endings");
}

void loop()
{
   //static unsigned int index = 0;
   recvWithEndMarker();
   if (newData)
   {
      showNewData();
      lcdDisplay();      
      ndx = 0;
      newData = false;
   }
}

void lcdDisplay()
{
   lcd.clear();
   for (int n = 0; n < ndx; n++)
   {
      if (n > 15)  // 16 character LCD
      {
         lcd.scrollDisplayLeft();
         lcd.print(receivedChars[n]);
      }
      else
      {
         lcd.print(receivedChars[n]);
      }
      delay(200);
   }
}


void recvWithEndMarker()
{

   char endMarker = '\n';
   char rc;

   while (Serial.available() > 0 && newData == false)
   {
      rc = Serial.read();
      //Serial.println(rc);
      if (rc == '\r') // ignore carruage return
      {
         return;
      }
      if (rc != endMarker)
      {
         receivedChars[ndx] = rc;
         ndx++;
         if (ndx >= numChars)
         {
            ndx = numChars - 1;
         }
      }
      else
      {
         receivedChars[ndx] = '\0'; // terminate the string

         newData = true;
      }
   }
}

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



1 Like

Well from your first description I thought that these details are all managed by the library.

handover 200 characters to the library and the library starts scolling the 200 characters through the display automatically without any additional line of code.

Anyway would be a convenient function to have something like this.

Be the change you want to see in the world
best regards Stefan

This page covers the memory organization of the hd44780 controller and shows why scrolling is necessary to display more than one line worth of characters. It has to do with how the display memory is organized.

I thought the library would have some function that does the scrolling "in the background"

Sorry, I misunderstood. The hd44780 library has no function like that that I know of. There is line wrap, but that goes to the next line, not continue on the current line.

Thank you for your kind answers and for the examples. Tomorrow i'll study it and come back whether i succeeded or not.

So, with your solutions i did manage to make it work, however there are many things that i don't really understand why they work and how exactly, but i suppose that's just a matter of study.

Thank you again for the help!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.