Arduino controlled LCD using a shift register and the SPI library
Now that I got my recycled 40×2 character LCD working with Arduino, the next step is to get it to show something useful. I decided to add it to my Bluetooth Controlled robot and display data from its two ultrasonic distance sensors (initially). Gradually more interesting info like battery voltage and wheel encoder data can also be shown, as I get those components working. The problem is that now I need to find another 6 digital pins to control the LCD itself. Fortunately, there is an alternative: add a 74HC595 shift register and take advantage of the Arduino SPI library. Here is how:
In this case, I want to send data one way only – from the Arduino to the LCD. Using a shift register gives me 8 additional digital output pins (in the case of the 74HC595) at the cost of 3 Arduino digital pins (for one way communication from the Arduino to the shift register via SPI).
Step 1: Wiring the Arduino, the 74HC595 shift register and the LCD
- The Arduino Uno communicates with the shift register using SPI . The Arduino is the “Master” and the shift register is the “Slave”. For this purpose we need the Data (MOSI), Clock (SLCK) and Latch (Slave Select) pins connected. The MISO (Master In Slave Out) line is not needed because we are not going to read any data from the LCD.
- The character LCD is now connected to the shift register pins, not directly to the Arduino. A byte is sent from the Arduino each clock cycle, which then tells the shift register how to set each of its 8 digital pins (high or low).
Connections between the Arduino and the shift register:
The data bits (MOSI): Connect pin 14 “DS” on the 74HC595 to Arduino pin 11.
The SPI clock (SCK): Connect pin 11 “SHCP” on the 74HC595 to Arduino pin 13.
The Latch: Connect pin 12 “STCP” on the 74HC595 to Arduino pin 9.
Here is a diagram of the connections (updated on June 8th, 2015):
Some LCDs do not have a backlight (pins 15 and 16 on the LCD). In the diagram above pin 15 (tha anode of the backlight) is connected to the 5v rail through a 220 Ohm current limiting resistor. On most LCD modules, a current limiting resistor is already built in on the LCD module, so you may not need to add one. Naturally, if your LCD does not have a backlight (has 14 pins only) you do not need to worry about that at all.
The trimpot connected to pin 3 of the LCD (labeled V0 on my module) controls the brightness of the display. One thing to note is that the display may be the brightest when its pin 3 is connected to ground. If you do not have a trimpot, I would suggest to do just that.
Step 2: Adding SPI support to the Arduino LiquidCrystal library
By default the LiquidCrystal library that comes pre-installed with the Arduino IDE (I am using version 1.0.5) assumes a direct connection between the Arduino and the LCD. Fortunately, there is a modified version of the LiquidCrystal library that adds support for SPI, created by Juan Hernandez, in the Arduino Playground.
I followed the steps below to get things working.
- Back up your original LiquidCrystal library, just in case. I simply cut the whole LiquidCrystal folder and moved it to a backup foldern, outside of the Arduino library directory.
- Download a copy of the updated version supporting SPI from here.
- Close the Arduino IDE, if you have it open
- Replace the original LiquidCrystal library with the modified version from step 2.
- Open the Arduino IDE
- Using the File menu, navigate to File->Examples -> LiquidCrystal. If you see an example called “HelloWorld_SPI”, you have installed the updated library
Step 3: Using the modified LiquidCrystal library with a shift register
The first thing to get the HelloWorld_SPI example sketch up and working with your set-up. If you are starting from scratch, or adding the LCD code to an existing Arduino sketch, make sure to add the following two lines in the top:
#include <SPI.h> #include <LiquidCrystal.h>