LCD: programming and Raspberry Pi use

Introduction

The information about the use of LCDs (liquid-crystal displays) with the Raspberry Pi is rather sparse, especially when comparing the information about the use of LCDs with Arduino. I think there are several reasons for this:

  1. LCDs typically use 5 V supply and logic, while 3.3 V logic is used by Raspberry Pi.
  2. LCDs require the transfer of large amounts of data, and Python as the primary programming language of the Raspberry Pi is quite slow.
  3. LCDs normally use parallel communication, which is not pre-programmed Raspberry Pi.

These problems can be avoided with the following strategies:

  1. Sometimes the LCD can be changed from 5 V logic to 3.3 V logic. Sometimes it is even possible to write 3.3 V logic to 5 V LCD controller chips.
  2. The pigpio module can be used on the Raspberry Pi operation system for fast GPIO communication.
  3. Parallel communication is not difficult to program if one knows the basics.

On this page I intend to give a basic electronic and programming introduction and instructions on how to use these strategies on different LCDs.

LCD voltage

Chip nameProducerCommunicationVddMin. logic HighCompatible chipsComments
Graphic LCD
KS0108Samsungpar (6800)4.5 V – 5.5 V2.0 V or 0.7 Vdd
RA6963RAiOpar (8080)3.0 V – 5.5 VVdd - 2.2 V
ST7565RSitronixser (SPI), par (6800 & 8080)1.8 V – 3.3 V0.8 Vdd
ST7920Sitronixser (SPI), par (6800)2.7 V – 5.5 V0.7 Vddoscillation resistor 5 V—33 kΩ, 2.7 V—18 kΩ
T6963CToshibapar (8080)4.5 V – 5.5 VVdd - 2.2 VRA6963outdated
Character LCD
HD44780Hitachiser (?), par (6800)2.7 V – 5.5 V0.7 VddSPLC780C, ST7066, KS0066oscillation resistor 5 V—91 kΩ, 3.0 V—75 kΩ

As the table above shows, most LCD controller chips support 5 V logic, but there are a number of chips that support both 3.3 V and 5 V logic.

But even if the LCD controller chip is supplied with 5 V and operates in 5 V logic, it can sometimes accept 3.3 V as logic High. For example, if the RA6963 chip is supplied with Vdd = 5 V, it will accept anything above 5 V - 2.2 V = 2.8 V as a logic High. In these cases, however, the device can only be used in write mode - using the LCD in read mode may destroy Raspberry Pi!

The biggest problem, however, is not the LCD controller chip supply voltage, but the unrelated supply voltage required for operating liquid crystals. If the supply voltage is too high, the pixel is always dark, if the supply voltage is too low, the pixel is always bright. The optimal supply voltage depends on the LCD device and also on the temperature.

The temperature dependence is taken into account by an external potentiometer for the so-called contrast management. However, many LCD devices do not support contrast management and can only be used at room temperature. The more annoying problem is that the optimal supply voltage for liquid crystals is usually above 3.3 V (and usually below 5 V), which makes LCD devices supplied at 5 V much simpler.

LCD devices that are supplied with 3.3 V use so-called charge pumps that generate negative potential. The total difference between supply potential and negative potential is then larger than 3.3 V and is sufficient for operating liquid crystals.

Sometimes LCD devices are sold for the 5 V supply, but there is a free space on the PCB (printed circuit board) for the charge pump, and the device can be adapted for the 3.3 V supply. In such cases it is best to consult the seller regarding the adaptation, but with some basic knowledge of electronics such situations can be identified and the device adapted without consultation.

[voltage inverter] [free space on PCB]

The figure above left shows how a charge pump (MAX660, ICL7660) can be used as a voltage inverter. The total voltage between Vdd and -Vdd doubles the starting voltage and is in most cases sufficient for liquid crystal supply. The picture above right shows a typical free space on the PCB for the charge pump, where U7 stands for the charge pump, while C8 and C9 stand for two capacitors.

Backlight

Liquid crystals do not generate the light, but block it. Therefore, every LCD device must have a light source behind the liquid crystals, which consists of one or more light emitting diodes (LED). Although LED and chip share the same PCB, their circuits are galvanically isolated. This makes it possible to supply the backlight LEDs with 5 V, even if the LCD device is used with Raspberry Pi.

The topic that needs to be addressed is maximum LED current. If the current through the LED is too high, it can destroy it. To limit this current, a resistor is connected in series with a LED. It is common that the LCD device already has an appropriate resistor for the maximum permissible current at a designed supply voltage. If not, such a resistor must be connected in series by the user. Note that since LEDs are required to illuminate large displays, their typical maximum current is between a few tens of mA and 100 mA.

In principle one could calculate the value of the appropriate resistor RL by knowing the supply voltage Vdd, the LED voltage drop VL and the designed LED current IL by RL = (Vdd - VL)/IL. The problem is that the LED voltage drop is not constant, but depends on the LED current, as one can see for example see on this page. The exact relationship depends on several factors, especially the LED color, and is generally not provided by the manufacturer of LCD device. In case you have to determine the resistance value yourself, I suggest an experimental method where LEDs, potentiometer and ammeter are connected in series.

[controlling backlight with transistor]

Sometimes a user wants to control the backlight by turning it on and off and changing its brightness. Since the individual Raspberry Pi GPIO current is limited to 16 mA, this usually means that backlight LEDs cannot be supplied directly by GPIO pin. Fortunately, a very simple circuit with a common inexpensive NPN transistor can be used, as shown in the figure above. If the GPIO pin is set to High, the transistor is open and can be considered a short circuit. The resistor RG is used to limit the GPIO current. If the current gain of the transistor hFE is known, the resistor can be calculated using the expression RG = 3.3 V × hFE / IL. Typically for 2N3904 and IL = 100 mA, hFE ≥ 30, so RG = 1 kΩ.

This setup can be used for both a 5 V and a 3.3 V supply. So if the LCD device design supply is 5 V, the backlight can be supplied by the 5 V rail of Raspberry Pi without any changes to the PCB.

The same setup can also be used for brightness control using a pulse width modulated (PWM) GPIO pin. The pulse width modulation turns the GPIO pin High and Low very fast, so fast that our eyes do not detect the flickering. As the share of High state drops, the perceived brightness decreases.

Programming basics

All LCD controller chips have RAM (random acces memory) which can be accessed and modified by communicating with the chip. A specific memory address corresponds to a bit on the graphic LCD or a character on the character LCD.

In a graphic LCD, when the byte at the home memory address is set to 0x50 (0b01010000), the second and fourth bits in the first line of the display become dark.

[character glyph]

In a character LCD, when the byte at the home memory address is set to 0x50, the first character in the first line of the display is usually the letter 'P', since the ASCII code for 'P' is 0x50. Character LCDs also have CGROM and CGRAM (character generation RAM and ROM) where glyphs are defined for characters. Eight bytes are required to define glyphs for 8 × 8 character: The letter 'P' in the figure above can be defined by bytes 0x1E, 0x11, 0x11, 0x1E, 0x10, 0x10, 0x10, 0x00 (0b00011110, 0b00010001, 0b00010001, 0b00011110, 0b00010000, 0b00010000, 0b00010000, 0b00000000). This is important to understand because most character LCDs have additional memory set in which user-defined glyphs, usually non-ASCII characters, can be defined.

In some cases the LCD controller chip supports both graphics and text. In this case, the chip has three memory sets: one for displayed bits, one for displayed characters, and one for character generation.

Serial communication

Mostly two different serial communication protocols are used, which were introduced with the microprocessors Intel 8080 and Motorola 6800. These communication protocols are usually simply referred to as 8080 and 6800.

Both protocols use in principle 10 channels, 3 control channels and 8 bit channels. The 8 bit channels transmit the byte, while the control channels determine whether the byte is a command or a datum, determine whether the byte is to be read or written, and trigger the byte transmission.

[serial communication]

The figure above shows the simplified process of both communication types.

For type 8080, both channels WR and RD must be High before communication. At the start, channel C/D must be set to determine whether the byte is a command or a datum.

For type 6800, the channel E must be Low before communication. At the start, channel RS must be set to determine whether the byte is a command or a datum and the channel R/W must be set to determine whether the byte is to be read or written.

If the communication is programmed in Python, sending a byte takes about 1ms (Raspberry Pi 3). With large amounts of data, the entire communication can take up to several seconds. However, if pigpio module scripts are used, the transmission time can be reduced to about 20 µs (Raspberry Pi 3). For large LCDs, especially graphic ones, the use of scripts is essential to achieve a sufficient refresh rate.

RA6963 chip

This LCD controller chip has several extraordinary capabilities:

[predefined character table]

Hardware

The RA6963 chip operates at both 3.3 V and 5 V. However, a very high supply voltage is required for the liquid crystals.

[240 × 128 graphic LCD PCB]

The picture above shows the PCB of the 5 V supply voltage 13 cm 240 × 128 graphic LCD device. For this device, the required supply voltage for the liquid crystals is 17.3 V at room temperature. This is achieved by using two voltage inverters connected in series, U9 and U10, which generate a negative potential of -3Vdd = -15 V. Note that there is free space for the third voltage inverter connected in series, U11, which allows a total negative potential of -5 Vdd. The third inverter is short-circuited by a zero resistance at position C19.

The seller claimed that the device could be adapted to the 3.3 V supply voltage by replacing the 0805 resistor R4 from 21.5 kΩ to 6.8 kΩ, which reduces required supply voltage for the liquid crystals. After the replacement, the contrast at room temperature is hardly sufficient, so I intend to investigate other options. Two 47 Ω 1206 resistors R12 and R13 in parallel limit the current through the LED backlight to 55 mA at 5 V supply. One of two resistors should be replaced from 47 Ω to 6.8 Ω if the backlight is to be supplied with a voltage of 3.3 V.

[240 × 128 graphic LCD setup]

The figure above shows the setup for using the LCD display, which is suitable for both 5 V and 3.3 V supply. Even if the RA6963 chip is supplied with Vdd = 5 V, it accepts anything above 2.8 V as a logic High (see LCD voltage), that is it can be used in the write-only mode with Raspberry Pi. The write-only mode in the setup is achieved by connecting RD to Vdd. Please note that if the LCD display is supplied with 5 V, the read mode destroys the Raspberry Pi! The chip enable CE, the font select FS and the frame ground FG are connected to ground. The line VOUT is the output of voltage inverters, V0 is the liquid crystals supply and a potentiometer is used to optimize the latter.

Software

The RA6963 chip has an additional reset line RES or RST. To reset the chip, this line is set to Low for a short time. The chip must be reset after power-up.

According to the manual, a status check must be performed before reading or writing data to ensure that the chip is ready to execute commands and read or write data. If the chip is supplied with 5 V, this check cannot be performed by Raspberry Pi, as reading 5 V logic data may destroy it. On the other hand, the speed of the chip is very high and the chip is ready after only a few microseconds (much more than Raspberry Pi needs to prepare the communication). Therefore, status checks can be avoided completely.

Many commands for the RA6963 chip require one or two bytes as parameters. According to the chip protocol, these parameters are sent before the command. Since two byte parameters usually represent a low and a high part of the memory address, the corresponding Python function can be written as follows:

def writecommand(self, com, num=0, dat=0): while num>=0: if num==0: value=com self._gpio.write(self._cd, 1) else: value=dat self._gpio.write(self._cd, 0) self._gpio.write(self._d0,value & 0x01) self._gpio.write(self._d1,(value & 0x02) >> 1) self._gpio.write(self._d2,(value & 0x04) >> 2) self._gpio.write(self._d3,(value & 0x08) >> 3) self._gpio.write(self._d4,(value & 0x10) >> 4) self._gpio.write(self._d5,(value & 0x20) >> 5) self._gpio.write(self._d6,(value & 0x40) >> 6) self._gpio.write(self._d7,(value & 0x80) >> 7) self._gpio.write(self._wr,False) self._gpio.write(self._wr,True) dat = dat >> 8 num=num-1

By default, this function assumes a command com without parameters. If a parameter is required, dat indicates whether the parameter has one byte (int8) or two bytes (int16), while dat is an actual parameter. The _cd corresponds to the C/D channel, the _wr to the WR channel, while _d0 correspond to _d7 to the data channels.

It would be very inefficient to write to or read from chip memory with one command for every byte. For this reason, the RA6963 chip defines the data auto read and write. As in the corresponding Python function below, the procedure starts with issuing the auto write command, followed by sending the data list and ends with issuing the auto reset command:

LCD_SETDATAAUTOWRITE = 0xB0 LCD_AUTORESET = 0xB2 def writedata(self, data): self.writecommand(LCD_SETDATAAUTOWRITE) self._gpio.write(self._cd, 0) for value in data: self._gpio.write(self._d0,value & 0x01) self._gpio.write(self._d1,(value & 0x02) >> 1) self._gpio.write(self._d2,(value & 0x04) >> 2) self._gpio.write(self._d3,(value & 0x08) >> 3) self._gpio.write(self._d4,(value & 0x10) >> 4) self._gpio.write(self._d5,(value & 0x20) >> 5) self._gpio.write(self._d6,(value & 0x40) >> 6) self._gpio.write(self._d7,(value & 0x80) >> 7) self._gpio.write(self._wr,False) self._gpio.write(self._wr,True) self.writecommand(LCD_AUTORESET)

Here, data is a list of bytes to be written to memory.

When the LCD display is in graphic mode, a total of 240 × 128 bits or a total of 3840 bytes should be sent for one full screen picture. If the communication is programmed in Python, this takes about 4.5 s, which is obviously too much (Raspberry Pi 3).

However, if pigpio module scripts are used, the transmission time can be reduced significantly. Writing scripts is somewhat complex because it follows the syntax of Assembly language. Without explaining the details, I wrote a Python library that contains a script for writing commands and a script for writing data. The library includes all chip capabilities except for reading data and cursor-related commands.

For easier understanding a test Python file is also included. Note that scripts take at most 10 int32 data. To speed up the process and call the data script as seldom as possible, the data must be packed into lists of 10 int32 data each before sending to the script.

The transmission time for the full 240 × 128 bits screen is approximately 68 ms, of which 35 ms is for script operation, 16 ms for triggering scripts, and 17 ms for the rest (Raspberry Pi 3). A simple demonstration of the library running the included test Python file is shown in the video below.

HD44780 chip

This LCD controller chip has two extraordinary capabilities:

It is by far the most common character LCD controller and there are many Python libraries that support it.

Hardware

The HD44780 chip operates at both 3.3 V and 5 V. However, a supply voltage of 4 V – 5 V is required for the liquid crystals.

[40 × 4 character LCD PCB]

The picture above shows the PCB of the 5 V supply voltage 15 cm 40 × 4 character LCD device. It contains two HD44780 compatible chips, one of which operates the upper half of the screen and one the lower half. Three 100 Ω resistors R13, R14, R15 in parallel limit the current through the LED backlight to 100 mA at 5 V supply. The device has the pin 12 as the liquid crystal supply V0, but this line goes through jumper J1, which is not activated. Therefore, the supply voltage for liquid crystals cannot be adjusted by default, and the device may only have good contrast at room temperature.

On closer inspection, the liquid crystal supply is connected to the left side of jumper J1, the right side of R8 and the left side of R9. By default, the supply is shortened by zero resistance at R8 to ground. However, if one wants supply the LCD device with 3.3 V instead of 5 V, the supply potential of liquid crystals must be reduced to -1.7 V. This is achieved by removing resistor R8, installing a charge pump (MAX660, ILC7660) at U7, two 10 µF capacitors at C8 and C9 and 3 kΩ resistor at R9. As before, the supply voltage for the liquid crystals cannot be adjusted, so the contrast is convinient only for room temperature. Finally, according to the manual, R6 should be replaced by 75 kΩ.

[40 × 4 character LCD setup]

The figure above shows the setup for using the LCD display with 4 wire serial communication and backlight control. When the HD44780 compatible chip is supplied with Vdd = 5 V, it accepts anything above 0.7 Vdd = 3.5 V as a logic High (see LCD voltage). Theoretically this means that it could not even be used with Raspberry Pi, but in practice 3.3 V is sufficient to use the chip in the write-only mode. The write-only mode in the setup is achieved by connecting R/W to ground. Please note that if the LCD display is supplied with 5 V, the read mode destroys the Raspberry Pi! The V0 is for the liquid crystal supply and a potentiometer is used to optimize it.

Software

All commands for the HD44780 chip consist of only one byte, part of which can also be a parameter. It is therefore reasonable to write a single function that writes command or data bytes. The corresponding Python function can be written as follows:

def writebyte(self, value, char_mode=False): if char_mode: self._gpio.write(self._rs, 1) else: self._gpio.write(self._rs, 0) self._gpio.write(self._d7,(value & 0x80) >> 7) self._gpio.write(self._d6,(value & 0x40) >> 6) self._gpio.write(self._d5,(value & 0x20) >> 5) self._gpio.write(self._d4,(value & 0x10) >> 4) self._gpio.write(self._en,True) self._gpio.write(self._en,False) self._gpio.write(self._d7,(value & 0x08) >> 3) self._gpio.write(self._d6,(value & 0x04) >> 2) self._gpio.write(self._d5,(value & 0x02) >> 1) self._gpio.write(self._d4,value & 0x01) self._gpio.write(self._en,True) self._gpio.write(self._en,False)

By default, this function assumes a command. The _en corresponds to the E channel, the _rs to the RS channel, while _d0 correspond to _d7 to the data channels.

A total of 40 × 4 characters or a total of 320 half-bytes should be sent for one full screen text. If the communication is programmed in Python, this takes about 0.27 s, which is already unpleasant for the eye (Raspberry Pi 3). It is even slower when using Raspberry Pi Zero.

However, if pigpio module scripts are used, the transmission time can be reduced significantly. Writing scripts is somewhat complex because it follows the syntax of Assembly language. Without explaining the details, I wrote a Python library that contains a script for writing commands and a script for writing data. The library includes all chip capabilities.

It is important to note that the chip is rather slow in processing data. The manual states that the execution time for each byte is 37 µs. However, I have found experimentally that 55 µs is required when the chip is supplied with 3.3 V. In my library the value for the execution time can be specified by the user.

For easier understanding a test Python file is also included. Note that scripts take at most 10 int32 data. To speed up the process and call the data script as seldom as possible, the data must be packed into lists of 10 int32 data each before sending to the script.

The transmission time for the full 40 × 4 character screen is approximately 15 ms. A simple demonstration of the library running the included test Python file is shown in the video below.

Many other useful resources for setting up and programming this chip are also available on the Internet, of which I especially recommend the following two. Programming the HD44780 LCD Display with Raspberry Pi gives instructions for programming the parallel communication, while LCD16x2 HD44780 Tutorial has a good overview of the chip's commands.

ST7565R chip

This LCD controller chip has several extraordinary capabilities:

Hardware

The ST7565R chip operates at 3.3 V.

[128 × 64 graphic LCD PCB]

The picture above shows the PCB of the 3.3 V supply voltage 8.5 cm 128 × 64 graphic LCD device. The 10 Ω resistor R11 limits the current through the LED backlight to 20 mA at 3.3 V supply. Positions R6 and R7 select between 8080 and 6800 parallel communication, while R8 and R9 select between serial and parallel communication. The selection between serial and parallel communication can also be made by the pin PS if none of the positions R8 and R9 is short-circuited. By default on this PCB serial communication is selected by using zero resistance at R9, and in case of parallel communication, 6800 communication is selected by using zero resistance at R6. I have removed resistor R9 and select between serial and parallel communication using pin PS. Do not use pin PS if the selection between serial and parallel communication is already done on the PCB, because this may destroy Raspberry Pi!

Please report what else would you like to see here, suggestions, new tricks etc. to the author using feedback form.

Created by Marko Pinteric: feedback form.

Updated . Web page has been read by visitors since October 2020.

Valid XHTML 1.0! Valid CSS!