GLCD / ks0108 smooth horizonal text scrolling?


I’m tinkering with a ks0108 and the beta GLCD libraries and would like to be able to scroll text across the screen in a ticker-like fashion, but at 1-pixel resolution so that the scroll effect is very smooth.

Smooth vertical scrolling is easy: just use a negative Y index into a text area like so:

int offset=0;
while(offset > -8) {
  textBox.CursorToXY(0, offset);
  textBox.Printf("Scrolling up");

The above technique doesn’t work for the X axis; specifying a negative X index simply places the text on the left edge of the screen.

Any idea how to do smooth horizontal scrolling with GLCD?


In your favour is the fact that drawing on pixel boundaries in the X direction is fairly efficient (because each extra X is another byte in the LCD memory, whereas a pixel vertically is part of a byte).

However the hardware doesn't directly support it, unlike scrolling in the Y direction (which is just a hardware register).

If you just want a line of scrolling text (rather than the whole screen) I got an example to work fast enough using the library I wrote for the I/O expander. Basically I just erased up to where the text is going to start, drew the text, and erased past it. This can be done pretty fast, and gives the impression of smoothly scrolling text.

In fact, if you do it too fast it becomes a bit unreadable, at least with the LCD I have, because the LCD pixels have a fairly slow recovery time.

Ah, I see why now, from Wikipedia:

As the number of pixels (and, correspondingly, columns and rows) increases, this type of display becomes less feasible. Very slow response times and poor contrast are typical of passive-matrix addressed LCDs.

I'm guessing mine is a passive-matrix display, and to be honest, even with a deliberate 100 ms delay between each attempt to scroll horizontally, it was making my eyes water.

Haggis, What you are doing is pure luck that it kind of works. In fact I had to review the code several times to see what it was doing. It is taking advantage of several "bugs" and is likely to break in future releases. The arguments to CursorToXY() are unsigned 8 bit values. So passing a -1 is the same as passing in a 255. (which would be off the display and definitely outside the text area) But then there is some math going on that overflows because values are all 8 bits and is stored back into an 8 bit variable. In the future, the code may be altered to support displays with greater than 255 pixel width/height (so arguments and variables become 16 bits) or it might start to sanity the check the incomming arguments. If either of those happens the code you have will not longer behave like it does now.

The real solution for pixel "scrolling" is to add in new glcd functions that move pixels on the display. I have thought about doing this several times but have never done it. Essentially it would be an area move operation, where a rectangular area could be moved around on the screen and also potentially rolled around the top/bottom or right/left.

One thing you can do which is not quite the same is to declare a text area that is vertical. i.e multiple lines tall but only 1 character wide. Then the current built in scroll routines can scroll the message up or down depending on the scroll direction. You would want to send the message 1 character at time with a delay between characters and it would scroll character by character instead of pixel by pixel. Not exactly what you are looking for, but it would work.

You can kind of sorta do what you want using the CursoTo() function by passing only the column because you can pass in negative value to move the cursor position backwards.

As an alternative, you could redraw the entire line each time. Then write a small routine that builds up a buffer of a full line of text. The code would need to roll around inside the buffer when the copy occurs. So for example, assuming 20 characters fit on a line. Then you create a 20 character buffer. Then have a routine that inserts your message into that 20 character buffer starting at different locations (say moving to to the left or right one position each time). Then if the text area is a single line all you have to do us print the 20 character buffer to the text area (no CursorTo() calls needed as the old text would automatically be scrolled out) and the text will appear to move. Albeit 1 character a time but it would be scrolling around the line.

--- bill