If I do an lcd.print at col 15, does the cursor then advance to col 16 (which doesn't exist), only to be moved back to col 15 with the lcd.scrollDisplayLeft() ? If that is the case, why would explicitly resetting the cursor to col 15 every time cause a problem (never mind that it does not seem to be necessary)?

I'm not sure what you are trying to accomplish but I think it may be similar to the fourth animated example on this page: --> http://www.geocities.com/dinceraydin/lcd/commands.htm.

I think you can implement this with what is called 'autoscroll()' in Arduinoese although I haven't tried it.

You haven't told us what size display you are using, but column 16 does indeed exist as far as the LCD controller is concerned. If you have a 16x2 display then columns above 16 are hidden, but they do exist. Any characters that you 'print' to those hidden locations will be revealed when you shift (the correct term for scroll) the display.

Sorry, I am culturally deprived. Would that be like the operation of the display in the link I mentioned above?

Quote

While we're at it, I am also experiencing a phenomenon where the 27th character I print to the lcd ends up on the second line.

If you really want to find out what is going on then follow the LCD Addressing link at http://web.alfredstate.edu/weimandn. Make sure you read the information about the LCD Controller Memory, the information about the 40 x 2 LCD, and the information about the 20 x 2 LCD before you try to figure out the 16x2.

Yes what I am trying to accomplish is like example #4 except without the visible cursor, and each character gets printed at col 15 before it gets scrolled (in the example they are printing the character at col 7 or .

Quote

If you really want to find out what is going on then follow the LCD Addressing link at http://web.alfredstate.edu/weimandn.

That was very helpful in understanding the guts of things, although I had assumed (perhaps incorrectly) that the LiquidCrystal library would take care of the sausage making, so to speak.

I was particularly excited to see that the first line of memory ends on 27, since that is the point at which my display seems to print the next character on the 2nd line, until I realized that it was 0x27, not decimal 27.

In any case, it gives me some place to start and some things to think about.

Using your explanation, I would expect that setting the cursor to (15,0) and then starting to write my string, I would write 25 characters (1 visible and 24 'invisible') and the 26th would appear at position (0,1). However, my understanding is that using autoscroll or scrolldisplayleft moves the cursor position each time (i.e. after the print/write, the cursor goes to 16,0 but then gets decremented back to 15,0) so the 'wrap' should never happen.

In my case, it does wrap on the 27th character (haven't figured out where I lost 1 yet!), but starts at position (7,1). It would seem that the scrolling is not, in fact, changing the cursor position. I tried to do that explicitly (set the cursor to 15,0 each time I write) but that got me some other weirdness.

In searching for other solutions, I came across a number of posts that seem to indicate the 'scroll' functions often yield unexpected results. Also, there was mention that setcursor is really pointing to a memory location, and that sometimes that doesn't correspond to the physical display location you think it does.

Have you seen any of these phenomena before? Do you use the lcd library that ships with the Arduino IDE, or are there 'better' ones out there?

I haven't done much with display shifting but let me try to explain what is happening.

After clearing the screen (which happens during the LCD initialization) the counter that keeps track of memory addresses is set to 0x00. Then, the first ASCII character code that you send to the display is stored at that address and subsequent character codes are sent to sequential addresses after that one. The sequence normally increases but you can change that if you want. You can also change the address so things start other than at address 0x00.

Each of the memory addresses is associated with a specific screen location so, when you store the ASCII code for a character in a memory address the character itself appears at the location specified for that memory address.

When you set the cursor to (15,0) the library uses what it knows (or should know) about your display to convert this into a memory address. For (15,0) on a 16x2 display the memory address is 0x0F.

If the display is shifted left once then the memory address associated with a particular screen location is one number higher than it was before. You could also say that the screen location associated with a particular memory address is one location to the left of where it was before.

This means that the character that you put in memory location 0x0F now moves left since that address is now associated with (14,0). The address counter has automatically incremented to 0x10 and location (15,0) is now associated with that new address so the next character will appear right where you expect it.

As long as you don't try to reset the cursor things should work as expected (until you fill up the screen). I don't know what will happen if you do try to reset the cursor because I have not explored the library to see if the author has accounted for the fact that the relationship between memory addresses and screen locations has changed. I rather expect that she didn't since you report 'some other weirdness'.

I do not use the LCD library that ships with the Arduino IDE (or any other library either). I like to know what is going on. Libraries have their place, they permit microcomputer neophytes to do things that they couldn't otherwise do and they permit professional coders to crank out code rapidly and efficiently. I am neither a neophyte nor a professional coder and I prefer to work without using libraries.

rwiens,This peaked my interest as I initially also expected the same behavior you expected.So when in doubt, just go look at the code.Then all becomes obvious.

The scrollDisplayLeft() sends the hd44780 command:LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFTor0x10 | 0x8 | 0x0or 0x18which is hd44780 commandCursor/Display shift with S/C = 1, R/L = 0which is moves the existing display to the left bychanging the base address of where the display fetches characters.scrollDisplayLeft() does not alter the cursor position.

The next part is where the things are not so obvious.setCursor() sends the hd44780 command:(LCD_SETDDRAMADDR | (col + row_offsets[row])or0x80 | (col + row_offsets[row])This will set the cursor position to an absolute address.It is not dependent on the display position.

So what you are seeing is that column 15 appears to move, when in factwhat is really happening is that column 15 is staying the same and the displaywindow is changing.

In order to do what you want, all you need to do set the initial cursor positionand then not set the cursor position between updates.Something like:

In order to do what you want, all you need to do set the initial cursor position and then not set the cursor position between updates.

I guess that is essentially the same as "As long as you don't try to reset the cursor things should work as expected (until you fill up the screen).Quiz: What do you expect to happen when you do fill up one line of the screen?

Quote

... and then you can scroll it to the left between each update.

I would expect that the use of lcd.autoscroll() would remove the need to do this, but then again things do not always work out the way you expect.

Bill, I did in fact look at the library and saw the same stuff you did but wasn't entirely sure how to interpret it. Your explanation is helpful, although I would need to spend some more time with the 44780 documentation to really understand it (I am not a c++ guy, either).

Don do you have any example sketches for LCD control that don't use the LiquidCrystal library? I would like to see what the 'raw' commands look like. I also have the tendancy to want to understand things at the lowest level, but have to trade that off with how much time it takes to get that understanding. I am not a neophyte coder, per se, but am pretty new to Arduino and anything c++ish

I'm still not clear on why my 27th character ends up in the middle of the 2nd line, but it sounds like that is irrelevant since one way or the other I will need to figure out when I have written 40 characters to the first line and then start shifting all of the RAM one position to the left (my strings are typically 25-50 characters long and I am essentially trying to display them one after another so I have basically an 'endless' string). As a matter of fact, I might just start writing the first character to the 40th position and then start shifting. My only question is whether I will be able to loop through 40 positions (x2 lines) fast enough.

That was very helpful in understanding the guts of things, although I had assumed (perhaps incorrectly) that the LiquidCrystal library would take care of the sausage making, so to speak.

Before I forget (again) I think that I may have something for you along these lines. A while back one of our forum contributors was dealing with 40x4 displays which are essentially two 40x2 displays in the same package. While he was developing his liquidcrystal440 library he also did some work on the timing (since he had some incredibly out-of-spec displays) and also on the line wrapping. The library is not restricted to 40x4 displays, it works with the smaller ones as well. That original library has evolved into LiquidCrystal1.0 and to get a copy start here:--> http://code.google.com/p/liquidcrystal440/ and follow the Downloads link to get to the latest version.

Quote

Don do you have any example sketches for LCD control that don't use the LiquidCrystal library?

I do almost all of my work in assembly language but I know have some LCD stuff written for the pre 1.0 versions of the Arduino IDE around here somewhere since that's what I sent John when he was working on his liquidcrystal440 library. I'll look for it.

Quote

My only question is whether I will be able to loop through 40 positions (x2 lines) fast enough.

I hope you understand that the 2 lines will inherently shift at the same time. You can get around this with programming so it's is not a deal killer.

You might want to experiment by writing a 'normal' string of about ten characters to the display and then send at least 100 shift left commands, with a pause between each so you can watch what is going on. You may be surprised at the result.

My only question is whether I will be able to loop through 40 positions (x2 lines) fast enough.

"fast enough" is a relative term.How fast do you need to update the display? How often? How many cycles are used by other stuff?

The supplied LiquidCrystal library can update a full 16x2 display around 87 times per second or in around 11.5msIf you switch to fm's LiquidCrystal library replacement,it can update a full 16x2 display around 300 times per second or in around 3.3ms

The key to keeping the display updates fast and avoiding flicker is to avoid using lcd.clear() and lcd.home()Those commands are quite slow.With fm's library you can update the entire 16x2 display faster than time it takes lcd.clear() to execute.

You may want to consider managing a shadow display buffer in RAM.Fill it in the way you want the display to look. Then, slam out the buffer to the display.You can manage the shadow buffer anyway you like.Either creating a full shadow buffer of all the display ram that you index into to create the scrolling effector just have the local buffer represent what will be displayed on the lcd.I would think that even the supplied LiquidCrystal display should be more than fast enough todo what you need.

How fast do you need to update the display? How often? How many cycles are used by other stuff?

I haven't figured out the exact speed (and it will actually change depending on the content) of the scroll but I would say at the fastest I need to shift at about 60ms (i.e. a character goes all the way from col 15 to col 0 in 1s). The question is whether I could read and re-write all 80 characters in that time. Sounds like the fm LiquidCrystal library replacement will at least update the display quickly enough (where do I find it?).

Quote

I hope you understand that the 2 lines will inherently shift at the same time.

This is exactly what I am trying to accomplish.

Quote

You might want to experiment by writing a 'normal' string of about ten characters to the display and then send at least 100 shift left commands, with a pause between each so you can watch what is going on. You may be surprised at the result.

I did some experimentation along these lines and did get unexpected results. One thing I thought about was trying to read the memory pointer from the display controller to see what was happening.

Quote

You may want to consider managing a shadow display buffer in RAM.

I assume you are talking about the Arduino RAM? The more I think about it, the more that seems like the easiest solution, although now I am curious about understanding what is actually happening in the display controller.

How fast do you need to update the display? How often? How many cycles are used by other stuff?

I haven't figured out the exact speed (and it will actually change depending on the content) of the scroll but I would say at the fastest I need to shift at about 60ms (i.e. a character goes all the way from col 15 to col 0 in 1s). The question is whether I could read and re-write all 80 characters in that time. Sounds like the fm LiquidCrystal library replacement will at least update the display quickly enough (where do I find it?).

60ms is a LONG time to a micro-controller.Keep in mind, the times I quoted are to update the entire 16x2 display.Doing this:lcd.setCursor(0,0);lcd.write(char); // repeated 16 timeslcd.setCursor(0,1);lcd.write(char); // repeated 16 times.

You don't need to re-write 80 characters.All you need to do is write the 32 characters visible on the display.

In looking at your timing and doing some math:You are wanting to scroll characters from col 15 to col 0 that is 16 "moves" in 1 second that means each move needs to happen in1/16 of second or 62.5ms.The standard LiduidCrystal libraray can update all 32 characters on the displayin 11.5ms and fm's library can udpate all 32 in 3.5ms.

When using the standard library that means you use11.5ms out of your 62.5ms budget. Which means thatupdating the display uses about 18% of the CPU available in your timing intervalwhich means you still have 72% of the CPU left over to do all your other stufflike reading information from the SD card etc.While fm's library would reduce that budget to just under 6%my gut feeling is that based on what you have said you want to dothe standard LiquidCrystal library should be capable of doing what you wanteven when updating the full 16x2 display each time you need to do a move/animation.

Quote

You might want to experiment by writing a 'normal' string of about ten characters to the display and then send at least 100 shift left commands, with a pause between each so you can watch what is going on. You may be surprised at the result.

I did some experimentation along these lines and did get unexpected results.One thing I thought about was trying to read the memory pointer from the display controller to see what was happening.

The memory pointer increases (assuming left to right) each time a character is written.The memory pointer is set to an absolute address when setCursor() is called.

Quote

You may want to consider managing a shadow display buffer in RAM.

I assume you are talking about the Arduino RAM? Yes, just fill in your buffer and then write it to the display.You can update the entire display, which is every single character position on a 16x2 displayin 11.51ms (87 times per second) using the standard library or in 3.35ms (~300 times per second)If you shadow the full LCD ram, you can make things shift by simply changing the indexof where you start grabbing characters from memory.Also if you use a local RAM buffer you will be able to shift the two lines independently.