silly LCD scrolling issue

I'm very new to Arduino, and it's been several years since I did any coding in C++ so I'm a little rusty.

I have an HD44780 16x2 LCD that I've been playing with. I'm attempting to get it to repeatedly scroll a message longer than the 16 characters available on the LCD.

I have it scrolling, but not quite like I want. The sketch is currently just scrolling an all caps alphabet, and I'm trying to code it such that it would reach the end and immediately start back at the beginning and at some point would look like:

"...XYZABC..."

Instead, what I'm getting is:
"...XYZ "
and eventually all the way down to:
"Z "

Once the final Z scrolls off, then it will start back at the beginning, however, it starts with A all the way to the left like:
"ABC..."

I've rewritten the code several different ways, and continually get the same result although the code seems to get tighter each time. here is the current version:

#include <LiquidCrystal.h>
#include <String.h>

// LiquidCrystal display with:
// rs on pin 12
// rw on pin 11
// enable on pin 10
// d4, d5, d6, d7 on pins 5, 4, 3, 2
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
int delayTime = 300;
char string[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz";
char string2[] = "ABCDEFGHIJKLMNOP QRSTUVWXYZ ";
char string3[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; //sizeof = 27

int pos = 0;
char display[16];
int i = 0;
int grab = 0;

void setup()
{
// Print a message to the LCD.
//lcd.print(sizeof(string3));

}

void loop()
{
generateDisplay();
lcd.home();
lcd.clear();
lcd.print(display);
delay(delayTime);

}

void generateDisplay()
{
grab = pos;
for(i=0; i<16; i++)
{
grab=(grab >= sizeof(string3))?0:grab;
display = string3[grab];

  • grab++;*
  • }*
  • pos++;*
  • if(pos > sizeof(string3))*
  • {*
  • pos = 0;*
  • }*
    }
    [/quote]
    What am I missing?
    Thanks
    Mitch

*minor footnote

I started with a different piece of sample code that expected it to be wired slightly different than how I already had it wired. So the comments and the code don't match, but the code is correct and comments are outdated.

Found it. was as simple as changing it to check that grab was less than sizeof my string MINUS ONE.

Even though there are only 26 characters in the array, the sizeof is 27. I knew that, never occurred to me that there was some form of value there.

It now does exactly what I wanted it to do.

Can you post the corrected code? Scrolling text on my LCD is something I've wanted to play with, but haven't gotten around to yet.

happy to.

I'm sure there are probably better ways of doing this... But the best way for me to learn some of this stuff is to just brute force my way through and reinvent some small wheels for a while. That said, I don't think it's a half bad chunk of code... especially not for someone who got his Arduino last week and his LCD yesterday! :slight_smile:

#include <LiquidCrystal.h>

// LiquidCrystal display with:
// rs on pin 12
// rw on pin 11
// enable on pin 10
// d4, d5, d6, d7 on pins 5, 4, 3, 2
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
int delayTime = 500;
char string1[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz";
char string2[] = "ABCDEFGHIJKLMNOP QRSTUVWXYZ ";
char string3[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; //sizeof = 27
char string[] = "I love PINBALL!! ";

int pos = 0;
char display[16];
int i = 0;
int grab = 0;

void setup()
{

}

void loop()
{
generateDisplay();
lcd.home();
lcd.clear();
lcd.print(display);
delay(delayTime);
}

void generateDisplay()
{
grab = pos;
for(i=0; i<16; i++)
{
grab=(grab >= sizeof(string)-1)?0:grab;
display = string[grab];

  • grab++;*
  • }*
  • pos++;*
  • if(pos > sizeof(string))*
  • {*
  • pos = 0;*
  • }*
    }
    [/quote]

The extra byte is because all strings have a "trailing zero byte" to indicate the end of the string.

--Phil.

The other option is to use the LCD4Bit library. It allows for the LCD_LEFT command (0x04?) which pushes the entire text left one space as many times as you want and with as much delay as you want. However, you do have to remember at that point that you cannot have a string of longer than 40 characters per line since I believe that technically the 41st character of the first line is the first of the second line.

I think you are close. I'm not sure it's 40, I think it may be 42. I'll have to count again.

I found that out through some trial and error. I wondered why it picked such an odd place to "wrap".

I figured there was probably a shift somewhere that I wasn't finding. But I've continued to refine my code, and I've nearly got it now where it's able to handle multiple strings on multiple lines and with multiple widths. But then my big box of LED's came in the mail and I unwired it to play with the new LED's. I'll probably wire it back up again and get the code back out to play with it some more tonite. I'll post the final sketch when I get it working.

MitchelWB

Ok, so I've nearly got my code ready to post for a little more robust version. But I've encountered a snag.

I've created a function that I'm passing strings in to. The function is then handling the display of my message.

I'm using a for loop to step through the string much like in the code I've already posted. Except that when I use sizeof() on a passed in string, I'm only getting a value of 1. The whole string is there, but the sizeof only reports a value of 1. Which means my loop never goes anywhere. If however I hard code the for loop to loop 10 times, then I will get 10 characters (assuming my string is at least 10 characters).

I'd guess it's because the variable is technically being declared as part of the function call, but is just being declared as an array with no size. It copies the passed string in to the function scope variable, but apparently not the size? Or is it just creating a pointer to it? I'm just not sure what's happening that my sizeof() function isn't returning the actual length of the string in the variable.

Any ideas?

MitchelWB