Controlling Alphanumeric LCDs With Three Wires


The HD44780 LCD controller is the defacto way of adding a small text display to your next project. If you need a way to display a few variables, a few lines of text, or adding a small user interface to a project, odds are you’ll be using one of these parallel LCDs. These displays require at least six control lines, and if you’re using a small microcontroller or are down to your last pins, you might want to think about controlling an LCD with a shift register.

[Matteo] used the ubiquitous ‘595 shift register configured as a serial to parallel converter to drive his LCD. Driving the LCD this way requires only three pins on the Arduino, [Matteo]’s microcontroller of choice.

For the software, [Matteo] modified the stock Arduino LiquidCrystal library and put it up on his Git. Most of the functions are left untouched, but for this build the LCD can only be used in its four bit mode. That’s not a problem for 99% of the time, but if you need custom characters on your LCD you can always connect another shift register.

If you just can’t spare three pins for a display, you could squeeze this down to just two, or add a second microcontroller for a one-wire-like interface.

38 thoughts on “Controlling Alphanumeric LCDs With Three Wires

  1. I just use a drop of epoxy to dead-bug mount an ATtiny84 on the back of the LCD. That way you can use 1-wire or I2C or whatever you want. I get the tinys in 100 lot at Mouser for $0.80 ea. I get the LCDs off Ebay for about 3.00 ea. So for less than 4.00 you have an LCD that is really useful.

    1. especially since these are very cheap as well :-)
      I must say though that I did a 2 wire interface with a 164 shift register that I use for attiny’s and for a nano where i wanted to use ALL the analogue ports and couldn’t sacrifice A4 and A5.
      I may try the 1 wire… just for the heck of it :-)

      1. but you have to take into account the velocity factor due to the color of the wire.

        if you are running timing-critical connections and you want all the signals to get there at the same time, you should use the same color and the same length of wire OR if you change colors, you have to account for the change in the speed of-

        oh, I can’t. I just can’t. I’ll stop here.

        1. Some electrons pick the scenic route, and white just dont cut it, they want something interresting like violet or yellow or blue. So white may not work, you have to know your electrons’ mood

    1. Yes, but be careful not to use red wires, they are linked to the microcontroller’s self-destruct subroutines.
      While the damage to your workbench will likely be negligible, there will be long term damage to the space-time continuum, possibly even fracturing subspace.

  2. Straightly speaking when you use the SPI hardware, the HW reserved the MISO whether you are really using it or not. So in reality this is taking up 4 I/O lines instead of 3 as claimed unless you are bit banging in software.

    There are LCD with SPI interface. “Nokia 5110” (graphics) which are around the same price $3 as character display from China from the usual places.

    1. Technically speaking, you can still use the MISO pin for something else, driving something from it. The ATmega SPI interface does not set up I/O automatically, setting up the pin’s DDR is left to the user. That being said, nothing stops you from using the MISO pin as generic I/O, even with the SPI interface active. You must, however discard any data that you would obtain from SPIDR after any SPI transaction as it would be garbage in this situation [lest you are driving a second slave from the same port, in which case, four wires be needed, the fourth one as a slave select for this circuit, with its glue logic of course].

      1. You can use the pin only as *input*, not for *driving* signals as you claim as it is now an *input only* pin.

        Page 164 of the Atmega 328 datasheet.
        MISO Input (Master mode)

        I did cheat using it as my Nokia 5110 /Reset. In my LCD init routine, the pin was init as an I/O and driven low As soon when SPI is turned on, I have a pull up resistor to override the pin which is now an input level to high, deasserting /Reset.

    2. You can pair the ‘595 with some ‘165s to latch and scan out buttons while driving the LCD. You can get away with having more ‘165s than ‘595s or vice-versa since the registers are latched on /CS.

  3. nad here we have another great alternative to the PCF8574 (i2c port expander). I guess this adds to the list of ways to save pins/routing effort/whatever. however this method doesn’t give a way to read data, which probably hardly ever is an argument.

  4. It’s more efficient to tie both sck and rck pins to the same arduino pin and the third arduino pin to the display’s enable line. The shift register outputs will be updated on every clock cycle but that’s ok because they will only be read by the display once it’s enable pin is toggled. This way it’s not necessary to update all the bits twice serially just to toggle the enable line. I’ve done it, works like a charm.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

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