John's Musings

Yeah, Me Neither

LCD HD44780 Raspberry Pi 8 Bit Wiring

Had some issues with 4 bit wiring of my HD44780, 20x4 LCD which I use in a project in a tube amplifier. Every time the AC power is thrown it causes corruption in the LCD characters. Supposedly 8 bit operation is less susceptible to this behavior so here we go. ..........

Virtually every tutorial on the web is for 4 bit operation, and why not? Less wires, less pin assignments to add to your's just easier.

Here's how we wire it from the LCD (pins 1 through 16)

Pin 1 - Ground

Pin 2 - Hot (5v) pin 2 or 4 on Raspberry Pi

Pin 3 - Center leg of potentiometer for contrast (usually 10K ohm and they usually come with the LCD)

Pin 4 - RS pin 26


Pin 6 - EN pin 24

Pin 7 - D0 pin 11

Pin 8 - D1 pin 12

Pin 9 - D2 pin 13

Pin 10 - D3 pin 15

Pin 11 - D4 pin 16

Pin 12 - D5 pin 18

Pin 13 - D6 pin 22

Pin 14 - D7 pin 7

Pin 15 - Hot (5v)

Pin 16 - Ground

NOTE: Pin 1 of LCD is the pin closest to the Raspberry Pi.

Pin 1 of the Raspberry Pi is the bottom left hand side pin. The pin above it has two red wires on it and is pin #2.

The remaining two pins on the Potentiometer go to hot and ground. Note that pin 2 I made a split jumper because there are only two 5v connections on the Pi. Three are required here. The black, negative wires can be placed on any Ground on the GPIO on the Raspberry Pi.

Also if you want to eliminate the potentiometer take the wire that goes from LCD pin to Ground (pin 3) and place a resistor in series with it. About 2K ohms will get you a nice clean display with perfect contrast. I have some small 4.7k ohm resistors and I twisted 2 in parallel together (2.35k ohms) and heat shrinked it up real pretty. Perfect display contrast and that totally elimates running another hot and ground wire down to a 3 leg potentiometer.

In order to fetch this information to display you need a python script from Github by jscrane. The file named is the one you want. I usually click on that GitHub file which reveals the code in its entirety. Copy the whole code to your clipboard and do the following:

mkdir lcdlms
cd lcdlms
sudo nano

Then paste your code in. Once it is in find the line near the top that says this:

my $DEF_LMS = "rpi";

Change "rpi" to the IP address of your server

my $DEF_LMS = "";

Hit CTL +X then Y and Enter to save the file.

Now make it executable.

sudo chmod u+x

Now there are a lot of ways to start the program and a lot of Linux purists may poo-poo my simplistic method instead of using a fancy script which monitors it for life and resurrects it if it dies. I just start it from crontab at boot. The only gotcha here is the sleep command. I have a Raspberry Pi 3 and LogitechMediaServer starts in a matter of seconds. Consequently I have a Pi A+ which it takes about 2 minutes for LMS to fully start. Adjust your sleep command accordingly.

sudo crontab -e

add this to the bottom and adjust accordingly for the location of your file, your IP address and the name of your squeezelite player at the end.

@reboot sleep 25; /home/pi/lcdlms/./ -v lms -d localhost:13666 -l LCDpi

Should start at boot. Yer doing it!

Now for LCDProc.

Install lcdproc with these commands:

sudo apt-get install libany-uri-escape-perl libswitch-perl
sudo apt-get update
sudo apt-get install lcdproc lcdproc-extra-drivers
mkdir lcdproc
cd lcdpro
sudo apt-get install build-essential
sudo apt-get remove lcdproc
sudo apt-get install lcdproc lcdproc-extra-drivers

You can now modify LCDd.conf

sudo nano /etc/LCDd.conf

In /etc/LCDd.conf the following must be added to the driver section of the HD44780 section. (Note that the numbers are different and are the GPIO assignments of the Raspberry Pi NOT the PIN numbers).

For cut and paste below:

#GPIO Pin map page for 8 bit operation











A special driver is needed for newer Pi's and can be downloaded with the following command in a Pi Terminal. Make sure you point to this driver location in the


section. I placed mine in /home/pi/lcdproc

mkdir lcdproc
cd lcdproc

After upgrading my Raspberry Pi LCD project in May 2017 the program LCDd would not start. The driver posted just above was not recognized. I found a driver in this thread that worked.

The driver file can be downloaded from my site here. Clicking the link will immediately download the file. I had NOTHING to do with the development of this driver. Nothing. Nada. Zip.

Here's my /etc/LCDd.conf file in it's entirety. I've deleted the unneeded drivers for brevity. Your server section and driver section should contain the same information.

# LCDd.conf -- configuration file for the LCDproc server daemon LCDd
# This file contains the configuration for the LCDd server.
# The format is ini-file-like. It is divided into sections that start at
# markers that look like [section]. Comments are all line-based comments,
# and are lines that start with '#' or ';'.
# The server has a 'central' section named [server]. For the menu there is
# a section called [menu]. Further each driver has a section which
# defines how the driver acts.
# The drivers are activated by specifying them in a driver= line in the
# server section, like:
#   Driver=curses
# This tells LCDd to use the curses driver.
# The first driver that is loaded and is capable of output defines the
# size of the display. The default driver to use is curses.
# If the driver is specified using the -d <driver> command line option,
# the Driver= options in the config file are ignored.
# The drivers read their own options from the respective sections.

## Server section with all kinds of settings for the LCDd server ##

# Where can we find the driver modules ?
# IMPORTANT: Make sure to change this setting to reflect your
#            specific setup! Otherwise LCDd won't be able to find
#            the driver modules and will thus not be able to
#            function properly.
# NOTE: Always place a slash as last character !

# Tells the server to load the given drivers. Multiple lines can be given.
# The name of the driver is case sensitive and determines the section
# where to look for further configuration options of the specific driver
# as well as the name of the dynamic driver module to load at runtime.
# The latter one can be changed by giving a File= directive in the
# driver specific section.
# The following drivers are supported:
#   bayrad, CFontz, CFontzPacket, curses, CwLnx, ea65, EyeboxOne, g15, glcd,
#   glcdlib, glk, hd44780, icp_a106, imon, imonlcd,, IOWarrior, irman, joy,
#   lb216, lcdm001, lcterm, lirc, lis, MD8800,, mdm166a, ms6931, mtc_s16209x,
#   MtxOrb, mx5000, NoritakeVFD, picolcd,, pyramid, rawserial, sdeclcd,
#   sed1330, sed1520, serialPOS, serialVFD, shuttleVFD, sli,, stv5730, svga,
#   t6963, text, tyan, ula200, vlsys_m428, xosd

# Tells the driver to bind to the given interface. [default:]

# Listen on this specified port. [default: 13666]

# Sets the reporting level; defaults to warnings and errors only.
# [default: 2; legal: 0-5]

# Should we report to syslog instead of stderr? [default: no; legal: yes, no]

# User to run as.  LCDd will drop its root privileges and run as this user
# instead. [default: nobody]

# The server will stay in the foreground if set to yes.
# [default: no, legal: yes, no]

# Hello message: each entry represents a display line; default: builtin
Hello=" John's Awesome"
Hello="  Raspberry Pi"

# GoodBye message: each entry represents a display line; default: builtin
GoodBye=" Turn us back"
GoodBye="  on soon"

# Sets the default time in seconds to displays a screen. [default: 4]

# If set to no, LCDd will start with screen rotation disabled. This has the
# same effect as if the ToggleRotateKey had been pressed. Rotation will start
# if the ToggleRotateKey is pressed. Note that this setting does not turn off
# priority sorting of screens. [default: on; legal: on, off]

# If yes, the the serverscreen will be rotated as a usual info screen. If no,
# it will be a background screen, only visible when no other screens are
# active. The special value 'blank' is similar to no, but only a blank screen
# is displayed. [default: on; legal: on, off, blank]

# Set master backlight setting. If set to 'open' a client may control the
# backlight for its own screens (only). [default: open; legal: off, open, on]

# Set master heartbeat setting. If set to 'open' a client may control the
# heartbeat for its own screens (only). [default: open; legal: off, open, on]

# set title scrolling speed [default: 10; legal: 0-10]

# The "...Key=" lines define what the server does with keypresses that
# don't go to any client. The ToggleRotateKey stops rotation of screens, while
# the PrevScreenKey and NextScreenKey go back / forward one screen (even if
# rotation is disabled.
# Assign the key string returned by the driver to the ...Key setting. These
# are the defaults:

## The menu section. The menu is an internal LCDproc client. ##
# You can configure what keys the menu should use. Note that the MenuKey
# will be reserved exclusively, the others work in shared mode.

# Up to six keys are supported. The MenuKey (to enter and exit the menu), the
# EnterKey (to select values) and at least one movement keys are required.
# These are the default key assignments:

## Hitachi HD44780 driver ##

# Select what type of connection. See documentation for availabe types.

# I/O address of the LPT port. Usual values are: 0x278, 0x378 and 0x3BC.
# For I2C connections this sets the slave address (usually 0x20).

# Device of the serial, I2C, or SPI interface [default: /dev/lcd]

# Bitrate of the serial port (0 for interface default)

# If you have a keypad connected.
# You may also need to configure the keypad layout further on in this file.

# Set the initial contrast (bwctusb, lcd2usb, and usb4all)
# [default: 800; legal: 0 - 1000]

#GPIO Pin mappage for 4 bit operation

#GPIO Pin mappage for 8 bit operation

# Set brightness of the backlight (lcd2usb and usb4all):
# Brightness is the brightness while the backlight is set to 'on'.
# [default: 800; legal: 0 - 1000]

# OffBrightness is the brightness while the backlight is set to 'off'.
# [default: 300; legal: 0 - 1000]

# If you have a switchable backlight.

# If you have the additional output port ("bargraph") and you want to
# be able to control it with the lcdproc OUTPUT command

# Specifies if the last line is pixel addressable (yes) or it controls an
# underline effect (no). [default: yes; legal: yes, no]

# Specifies the size of the LCD.
# In case of multiple combined displays, this should be the total size.

# For multiple combined displays: how many lines does each display have.
# Vspan=2,2 means both displays have 2 lines.

# If you have an HD66712, a KS0073 or another controller with 'extended mode',
# set this flag to get into 4-line mode. On displays with just two lines, do
# not set this flag.
# As an additional restriction, controllers with and without extended mode
# AND 4 lines cannot be mixed for those connection types that support more
# than one display!

# In extended mode, on some controllers like the ST7036 (in 3 line mode)
# the next line in DDRAM won't start 0x20 higher. [default: 0x20]

# Character map to to map ISO-8859-1 to the LCD's character set
# [default: hd44780_default; legal: hd44780_default, hd44780_euro, ea_ks0073,
# sed1278f_0b, hd44780_koi8_r, hd44780_cp1251, hd44780_8859_5, upd16314 ]
# (hd44780_koi8_r, hd44780_cp1251, hd44780_8859_5 and upd16314 are possible if
# compiled with additional charmaps)

# If your display is slow and cannot keep up with the flow of data from
# LCDd, garbage can appear on the LCDd. Set this delay factor to 2 or 4
# to increase the delays. Default: 1.

# Some displays (e.g. vdr-wakeup) need a message from the driver to that it
# is still alive. When set to a value bigger then null the character in the
# upper left corner is updated every <KeepAliveDisplay> seconds. Default: 0.

# If you experience occasional garbage on your display you can use this
# option as workaround. If set to a value bigger than null it forces a
# full screen refresh <RefreshDiplay> seconds. Default: 0.

# You can reduce the inserted delays by setting this to false.
# On fast PCs it is possible your LCD does not respond correctly.
# Default: true.

# If you have a keypad you can assign keystrings to the keys.
# See documentation for used terms and how to wire it.
# For example to give directly connected key 4 the string "Enter", use:
#   KeyDirect_4=Enter
# For matrix keys use the X and Y coordinates of the key:
#   KeyMatrix_1_3=Enter