Control a HD44780 LCD display via I2C with the Raspberry Pi

LCD character displays are a simple and a cost-effective way to display a text. Thanks to the HD44780 controller, the control of the modules has become very simple. However, one must occupy many GPIOs for it. An alternative is the I2C data bus, which means that only two GPIOs are used.

In this tutorial a 20×04 HD44780 character display is controlled using a I2C display adapter. A logic converter is used to adjusting the voltage level for the module without damaging GPIOs.



In order to access an HD47780 display via I²C, I have used the following accessories:


Raspberry Pi hd44780 i2c display

The pins of the I2C LCD adapter fit perfectly on the display and can be soldered. Some displays are already delivered with a soldered I²C adapter.



The Raspberry Pi GPIOs can not get more than 3.3V voltage, but there are some modules (like this display), which send and want to receive 5V signals. For this, a Logic Level Converter can be used, which has 2 sides. On one side those connections that are running on 3.3V are connected and on the other those with 5V. You can recognize this at different characteristics (LV – HV), as you see in the following picture:


The pins are then connected as follows:

Raspberry Pi 3.3V Level Converter 5V Level Converter I2C LCD Adapter
3.3V (Pin 1) LV
5V (Pin 2) HV VCC
GPIO2 / SDA (Pin 3) TX1 (below)
GPIO3 / SCL (Pin 5) TX1 (above)
 — TX0 (below) SDA
 — TX0 (above) SCL


Here is a schematic drawing:


Raspberry Pi HD44780 I2C Display Controller

Any ground pin can be taken. For the sake of clarity, I chose pin 20 instead of pin 6 on the schematic diagram.

This configuration is also usable with other modules which require signals with a higher voltage than 3.3V (in this case 5V) (real time clock, etc.).



Before we can start, two I²C tools are needed, which we install:

sudo apt-get install python-smbus i2c-tools

Then we will release I2C (if you have already released it from previous tutorials, you can skip it):

sudo raspi-config

Under “Interfacing Options”> “I2C” we activate it. Now add the corresponding entries to the modules file:

sudo nano /etc/modules

These two lines are added to the end:

Afterwards it has to be restarted, so that all changes take effect.

sudo reboot


If you have already connected the display, you can now test whether it has been detected (if you have one of the first Raspberry Pi’s [Rev.1], you have to pass 0 instead of 1):

sudo i2cdetect -y 1

The output should look like this:


pi@raspberrypi ~ $ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- 27 -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

If you see a number other than 27, you must change this in the file (ADDRESS = 0x27).

Let’s start with the code:

mkdir hd44780 && cd hd44780

With the help of the two included scripts, the display can now be addressed. To do this, we open the Python console and enter the following code:

sudo python

The first parameter of the lcd_display_string is for the text and the second for the row. You do not have to change all lines at once, but you can not easily replace individual characters. For this, the entire text (with the character changed at the desired position) would have to be retransmitted.

The contrast of my I2C adapter was at the beginning very low. If nothing should be shown, test the wheel on the back and look obliquely on the display.




Code Reference:

6 Responses

  1. This is very unique and interesting information. Logical level converters have played and important role in advanced science and novel technology. Thanks for sharing this with us. Kindly post more informative content like this.

  2. Perfect tutorial.

    Is there a simple way to displaying sensor data on the web?

    Best regards and thank you very much for such a good useful and interesting tutorial.

  3. I don’t understand how this works!

    I2C is a bi-directional interface, but your level shifters are uni-directional.

    Have I missed something???

    • (Ok, my bad n sorry about the spam. The level shifter is bi-directional. Whatever next…)


Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Subscribe to Raspberry Pi Tutorials and don't miss any new Tutorial!