Go Down

Topic: Cursor position after lcd.print() and lcd.scrollDisplayLeft() (Read 2 times) previous topic - next topic

rwiens

Don,

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?

floresta

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.


Don

bperrybap

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_MOVELEFT
or
0x10 | 0x8 | 0x0
or 0x18
which is hd44780 command
Cursor/Display shift with S/C = 1, R/L = 0
which is moves the existing display to the left by
changing 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])
or
0x80 |  (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 fact
what is really happening is that column 15 is staying the same and the display
window is changing.

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.
Something like:
Code: [Select]
lcd.setCursor(15,0);   
for (chrdCnt=1; chrdCnt<chrdLen; chrdCnt++) {

        lcd.print(chords[chrdCnt]);
        delay(1000);
        lcd.scrollDisplayLeft();
     }


This will allow the cursor position (ram address) to continue to bump
as the character is written and then you can scroll it to the left between
each update.

I tried it and it does work.

--- bill


floresta

#8
Feb 12, 2013, 02:06 am Last Edit: Feb 12, 2013, 02:08 am by floresta Reason: 1
Quote
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.

Don

rwiens

#9
Feb 12, 2013, 04:05 am Last Edit: Feb 12, 2013, 04:14 am by rwiens Reason: 1
Thanks guys.

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.

Richard

Go Up