Scrolling Text with RPLCD

The RPLCD Library

Last year when I started playing around with HD44780 based character LCDs on the
Raspberry Pi, I did not find any software library for it that I liked. There
were some C++ libraries around and also some Python scripts, but they were a bit
messy and not as clean and consistent as I’m used to from the Python community.
So I wrote my own library: RPLCD.

In contrast to other libraries, RPLCD tries to be “Pythonic”, which means that I
don’t want to simply copy the C implementations, but use Python features where
appropriate. The result of this is that I’m using a clean modular approach and
make use of language features like properties and context managers. Here’s a
small example on how to write a text to a 20×4 LCD:

>>> from RPLCD import CharLCD
>>> lcd = CharLCD()
>>> lcd.write_string(u'Raspberry Pi HD44780')
>>> lcd.cursor_pos = (2, 0)
>>> lcd.write_string(u'http://github.com/nrdbrgn/RPLCD')

The result:

A photo of the HD44780 LCD module displaying some text.

If you want to know more, please refer to the README file.

Scrolling Text

Writing a string to the display with RPLCD is easy. But what about more dynamic
things, like scrolling text? That’s not hard to implement by using a “frame
buffer” data structure.

The idea is that you create a data structure which contains all the characters
that should be written to the display later on. This data structure can then be
manipulated with standard Python tools. A good choice here would be a
2-dimensional list, representing rows and columns. In the case of a 2×16 LCD:

>>> framebuffer = [
...     'Hello!',
...     '',
... ]

Then we need a function to actually write the framebuffer to the device. It
should properly truncate the strings to the max column length.

>>> def write_to_lcd(lcd, framebuffer, num_cols):
...     """Write the framebuffer out to the specified LCD."""
...     lcd.home()
...     for row in framebuffer:
...         lcd.write_string(row.ljust(num_cols)[:num_cols])
...         lcd.write_string('rn')

Write the framebuffer to the LCD:

>>> from RPLCD import CharLCD
>>> lcd = CharLCD()
>>> write_to_lcd(lcd, framebuffer, 16)

Now we have a framebuffer that simply writes “Hello!” to the first row of the
LCD. But we want a scrolling text across the second row… To achieve this, we
need to manipulate the framebuffer, write it to the display, sleep for a short
while and repeat. A simple version might look like this:

>>> import time
>>> long_string = 'This string is too long to fit'
>>> for i in range(len(long_string) - 16 + 1):
...     framebuffer[1] = long_string[i:i+16]
...     write_to_lcd(lcd, framebuffer, 16)
...     time.sleep(0.2)

This simply scrolls the text into the visible area and stops. To get infinite
scrolling, simply add 16 blank characters at the beginning and end of the string
and repeat. Here’s the extended version of the above code, wrapped in a function:

>>> def loop_string(string, lcd, framebuffer, row, num_cols, delay=0.2):
...     padding = ' ' * num_cols
...     s = padding + string + padding
...     for i in range(len(s) - num_cols + 1):
...         framebuffer[row] = s[i:i+num_cols]
...         write_to_lcd(lcd, framebuffer, num_cols)
...         time.sleep(delay)
...
>>> while True:
...     loop_string(long_string, lcd, framebuffer, 1, 16)

Now you got infinite scrolling text on the second row, while the first row
stays static.