Text scrolling

I’m trying to get text to scroll on my 20x4 Arduino LCD screen but when i run the following code, it prints “Hello World” starting in the top left corning, then it scrolls down to the third line from the right side.

Firstly, why is it jumping to the third text line instead of the second line? (The line right below the first line)

2)How can i make it just scroll across the first line?

3)How can i make it start off screen on the right side of the first line then scroll onto the screen?

Thanks,

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

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 20 chars and 4 line display

void setup()
{
  lcd.init();                      // initialize the lcd   
  lcd.backlight();
  lcd.begin(20,4);
  lcd.print("Hello World");
  delay(1000);
  
}

void loop()
{
  // setcursor(column, row)
  
  // scroll 13 positions (string length) to the left 
  // to move it offscreen left:
  for (int positionCounter = 0; positionCounter < 13; positionCounter++)
  {
    // scroll one position left:
    lcd.scrollDisplayLeft(); 
    // wait a bit:
    delay(300);
  } 
   
}

Maybe there is an easier way to do it, but I would do it by hand, rather than using in-built LCD functions.

So, as a first step to understanding the concept, it would go something like (untested, pseudocode)

const byte LCD_WIDTH = 20;
const String msg = "Hello World!";

void loop()
{
    // allow for space before message. Loop of what is the first character to display on the LCD column 0.
    for (int i=0; i < LCD_WIDTH + sizeof(msg); i++)
    {
        LCD.setCursor(0,0);  // start at the beginning of the first line
        if (i < LCD_WIDTH) {
            // Scrolling onto the screen, right to left. Send the spaces at the front to the LCD
            for (int j = LCD_WIDTH; j > i; j--) {
                LCD.print(" ");
            }
            LCD.print(msg.substring(0, i));
        } else if (i > LCD_WIDTH) {
            // Scrolling off the screen, right to left.
            LCD.print(msg.substring(i - LCD_WIDTH, sizeof(msg)));
            // send the spaces at the end to the LCD
            for (int j = i - LCD_WIDTH; j < LCD_WIDTH; j++) {
                LCD.print(" ");
            }
        } else {
            LCD.print(msg);
        }

        delay(500);
    }    

}

LCD 20x4 has memory usually organized as 40x2. 1st line continues at 3th line and 2nd line continues at 4th.

See if this works for you. You may have to adjust it for your display, as I’m using an I2C LCD. Still, it’s the scroll function that’s of interest.

#include <Wire.h>  // Comes with Arduino IDE
// Get the LCD I2C Library here: 
// https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads
#include <LiquidCrystal_I2C.h>

#define COLS      16
#define ROWS       2
#define PAUSE    400

// For the Yourduino I2C LCD display:
// set the LCD address to 0x27 for a 16chars 2 line display
// Set the pins on the I2C chip used for LCD connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
char msg1[] = "From: Jill";
char msg2[] = "We will meet for lunch at noon at the Twin Lakes Restaurant";

void setup() 
{
  Serial.begin(9600);      // For debugging, if needed...
  lcd.begin(COLS, ROWS);   // init lcd for 16 chars 2 lines
}

void loop()
{
  int len;
  len = strlen(msg1);
  if (len > COLS) {        // Truncate From details if too long
    msg1[COLS] = '\0';
  }
  lcd.setCursor(0,0);      //Start at character 4 on line 0
  lcd.print(msg1);
  len = strlen(msg2);
  if (len <= COLS) {       // Second part short enough to fit?
    lcd.setCursor(1, 0);
    lcd.print(msg2);
  } else {
    ScrollDisplay(msg2, 1, sizeof(msg2)); // Need to scroll the message
  }
  delay(4000);
}

/*****
  The purpose of this function is to scroll a message across
  a line of the display. This is only called if the message
  is longer than the display is wide.
  
  Parameter list:
    char msg[]        the message to scroll
    int row           the row for scrolling
    int howLong       the length of the message
    
  Return value:
    void
*****/
void ScrollDisplay(char msg[], int row, int howLong)
{
  int i;
  int j;
  char window[COLS + 1];  // Enough room for message + null
  
  strncpy(window, msg, COLS);
  window[COLS + 1] = '\0';
  lcd.setCursor(0, row);        // Show first part...
  lcd.print(window);
  delay(PAUSE);

  j = COLS;
  do {
    if (j == (howLong - COLS))            // Seen everything?
      break;                              // Yep.
    memcpy(window, &msg[j], COLS - 1);    // Slide the message down 1 char
    window[COLS-1] = msg[j + COLS];       // Add new character at the end
    lcd.setCursor(0, row);
    lcd.print(window);
    delay(PAUSE);
    j++;
  }while (true);  
}

You can fiddle with PAUSE to see if that makes it less “jumpy” on your display.