Two wire Interface for LCD-with shift register

P1050315e lcdshiftUsing an LCD for a microcontroller such as the Arduino takes up quite a number of pins and actually doesn’t leave that much pins for other tasks. There are various solutions, like using an HC595 shiftregister (requiring three wires), a PCF 8574 or MCP23008 to create an I2C option or using a shift register such as the 74LS164. The added circuit does just that. It works on an Attiny85 as well.

A Library (by Malpartida) supporting this circuit can be found here:

A 100nf decoupling capacitor is necessary and should be placed near the  IC. Shiftregisters as the 74LS164 cause sudden changes to the current drawn from it’s power, and hence introduce noise. To counter this, a “decoupling capacitor” should be used as close to the shiftregister power pins as possible (Vcc and GND). Otherwise, the shiftregister may get faulty data and then the LCD won’t work as intended. This is also dependent on other factors, like wire lengths etc.

The resistor and the diode form an AND gate. They could be replaced by a proper AND gate, but that would increase the component count. The circuit can be easily built on a piece of 16×16 stripboard, even a 11×12 piece if you connect the LCD with wires rather than a connector.

74sr-lcdAs the top circuit doesn’t really show the logical functions of the 74LS164 but merely the lay out of the chip, I added the circuit below to show its logical function:

#include <LiquidCrystal_SR.h>
LiquidCrystal_SR lcd(8,7,TWO_WIRE);
//                   | |
//                   | \-- Clock Pin
//                   \---- Data/Enable Pin

void setup(){
lcd.begin(16,2);               // initialize the lcd
lcd.home ();                   // go home
void loop(){
lcd.home ();
lcd.setCursor (0, 1 );
lcd.print("2 wire");
Proof of concept

It is possible to let the backlight be taken care of by the software as well. Connect the circuit below to pin 4 of the SN164 and to the backlight pins of the LCD:


The stripboard should be adapted like this:

With backlight regulation

The full circuit like this:

As I still had an old Seiko M1632 display with no back-light and a DIL 2×7 connector rather than a SIL 1×16 connector, I also quickly made a design on perfboard for that:

for Seiko M1632
for Seiko M1632

It is a 9×14 piece. If you are cramped for space you can do it on an 8×11 piece, smaller even if one uses a small standing  variable resistor. For the practical circuit I chose a slightly bigger 9×20 piece (no use trimming an already small piece), and no.. you don’t want to see the bottom side🙂 :


As pin 4 of the 164 is used for the LCD backlight, but the Seiko doesn’t have a backlight, I decided  later to add an LED, connected through a 1 k resistor to pin 4 and be able to switch the LED on and off with the backlight command.

contrastWith regard to the potmeter for the contrast… if using a potmeter is not desirable for any reason, it is possible to set the Vlc to a voltage that is most optimal for most situations. The circuit shows how. Over the diode a voltage of about 0.65 Volt can be expected which is ideal for most situations:


8 bit Two wires

Above circuits are all for LCD in 4 bit mode as that is the most often used mode. However, Mike MacLaren pointed me to a circuit that uses a shiftregister (either a 164 or a 595) that uses two wires and does full 8 bit addressing of the LCD

Two Wire 8bit LCD with 164 Shiftregister
Two Wire 8bit LCD with 164 Shiftregister

The above circuit uses an HC164 shiftregister, but Mike’s site also has a circuit for a 595 and a driver program for a PIC as well as an Arduino microprocessor. This circuit does not cater for software backlight control, but it has full 8 bit control, should you need that

8 thoughts on “Two wire Interface for LCD-with shift register

  1. Program with errors, corrected, but still not working:
    This report would have more information with
    “Show verbose output during compilation”
    enabled in File > Preferences.
    Arduino: 1.0.6 (Windows 7), Board: “Arduino Uno”
    C:\Users\D\Documents\Arduino\libraries\LiquidCrystal\I2CIO.cpp: In member function ‘int I2CIO::begin(uint8_t)’:
    C:\Users\D\Documents\Arduino\libraries\LiquidCrystal\I2CIO.cpp:61: error: ‘Wire’ was not declared in this scope
    C:\Users\D\Documents\Arduino\libraries\LiquidCrystal\I2CIO.cpp: In member function ‘uint8_t I2CIO::read()’:
    C:\Users\D\Documents\Arduino\libraries\LiquidCrystal\I2CIO.cpp:117: error: ‘Wire’ was not declared in this scope
    C:\Users\D\Documents\Arduino\libraries\LiquidCrystal\I2CIO.cpp: In member function ‘int I2CIO::write(uint8_t)’:
    C:\Users\D\Documents\Arduino\libraries\LiquidCrystal\I2CIO.cpp:140: error: ‘Wire’ was not declared in this scope

    1. looks like you do not have the library installed, or u are calling the wrong one. seems u are calling the i2c library while u shld be calling the SR library.

      1. Jerry, do i understand correct you get no other error message than ‘cannot compile’? That is odd.
        which IDE are you using?
        Do you have the proper library installed?
        Was your PC perhaps filled to max memory capacity?
        Please go to preferences and tick ‘verbose error messages’ and try again

  2. The given link is for “I2C”. I cannot find the “LiquidCrystal_SR” library. So, the code doesn’t work for me. I really need to make it work for a project. Can anyone help me please?

    1. Azfarul, I am not sure which link you tried, but if you mean the one for the Malpertida library, what makes you think that is for I2C?
      the link brings you to a download page with several versions, pick the latest one ( download and install it.
      If you open it, you will see it has the LiquidCrystal_SR library.
      Install the entire library, not just the LiquidCrystal_SR files

  3. Hello!

    I’m having some problems with this. I’m using an Attiny45 with a random chinese HD44780-based LCD (used it before with normal wiring, it’s not faulty). I successfully uploaded the program és wired everything, but no text is shown on the screen. Only this:

    What I changed in your code is that I use “LiquidCrystal_SR lcd(0,1,TWO_WIRE);”, so pin 5 and 6. I also left out the transistor part, the LCD is directly connected to the supply, contrast is also on 5V.

    Do you have any ideas, why is this?


    1. yes that is easy to explain. in my program i used pin 7 and 8 as present on the arduino, but the attiny doesnt have a pin 7 and 8. So yr change does the right thing: chosing two pins that the attiny45 does have.

      Your digital pins 0 and 1 are the same as the physical pins 5 and 6

      It is wise to also use a limiting resistor for the backlight. Not all LCD’s like full 5 Volt on their backlight

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s