Saturday, 16 January 2010

Controlling an LCD Display with a Shift Register

When I first ordered my Arduino Experimentation Kit from those nice people at oomlout I also ordered a 16 character by 2 line LCD display.

It was really easy to set up and use thanks to the instructions that came with it and the LiquidCrystal library bundled with the Arduino software.
The only problem is that it takes up a lot of valuable output pins, 6 in 4bit mode and 10 in 8bit mode, this makes it difficult to use in large projects, as you can quickly run out of pins.

The solution to this was quite obvious; use a shift register. So I fired up Google and had a look to see what other people had done. I found a great article on the Arduino playground (here) except I could figure out how to get their circuit to work with my shift register, as they use 74*LS*164 but I had a few 74HC595 registers knocking about. I also tried the other article on Arduino playground, but that one doesn't work very well, as it has large delays in it and you have to make sure that data you are sending to it is in the correct format (for example, it doesn't like numbers, you have to convert them into strings first)

So, here are my goals
  • Operate the LCD screen using a shift register
  • Use no more than three data pins
  • Maintain full compatibility with the LiquidCrystal library

The first two these are quite simple. Use the circuit below for a 4bit interface:


This circuit will allow us to control the output of the display, as well as the LED backlight. The backlight is controlled by an N-Channel MOSFT connected to pin QF on the shift register. We are using a MOSFET because the input impedance of the MOSFET is very very high which makes it ideal for using in logic circuits.

To meet the third goal I decided to modify the LiquidCrystal library. The reason being that the wonderful people who wrote it in the first place already did all the hard work of programming the methods for initialising the display and outputting data so it would be a bit daft to re-write all of that when all that is really needed is to change the way that the LiquidCrystal library sends data to the display.

After a couple of hours I had successfully rewritten the 'send', 'write8bits' and 'write4bits' methods and began testing.
The image above looks very complicated, but that is because those two bread boards contain both the 8bit and 4 bit versions (the screen is plugged into the 8bit interface).

In conclusion: the shift register interface is very simple to build and not too hard to program and makes the LCD screen easier to use in your projects.


You can download my completed ShiftLCD Library here

71 comments:

  1. Hey Chris, nice work. I was just asking this question on an arduino forum (adafruit.com) and sure enough i came across your post. Great work. Given the principle it should be easy enough to scale that up to more LCD's if you daisy chain more 595 shift registers right? I was looking to implement 4 16x1's but wanted a way to conserve pin outs by utilizing a shift register. I think you've pointed me in the right direction.

    ReplyDelete
  2. Thank you very much! You really helped me improving my project. I love the internet with its kind people :-)

    ReplyDelete
  3. Hi sir,

    I am N.Nandhakumar, from India. I am a Final Year student doing project on Arduino.I was searching a lot to interface JHD162a 16*2 display with GPS [shielded] and Arduino with less than 5 pins.

    I found your post and it was really useful. I built the schematic you have told, but the LCD dint respond.I get only black blocks in the first line of the LCD.I am using a 74HC595 and built it on a BreadBoard.

    I have few doubts in the schematic like

    The list of Components used for the circuit.
    Few more details of MOSFET.

    Please help me out.

    Waiting for your valuable suggestions.

    Regards
    N.Nandhakumar

    ReplyDelete
  4. Hi,

    Very nice project! Is it possible to add 3 more shift registers? Right now im contolling 3, 7segment displays with 3 595`s. The 595lcd has to go in front of them.

    Thanks!

    Collin

    ReplyDelete
  5. chris, i took a look at your code and it looks great! did you happen to make anymore attempts at the 74ls164n? i've been tinkering with it for a bit, but its looks the two ICs are a little different... any plans for a 2 wire version? im off to dig for 595's! cheers!
    -john c.

    ReplyDelete
    Replies
    1. https://arduinodiy.wordpress.com/2014/01/12/two-wire-interface-for-lcd/

      Delete
  6. Hi Chris

    I liked and appreciated very much your shift lcd library and the way you created the Shift LCD. Actually I'm using ths as part od a complete motor step controller based on Arduino with several enhancements. Please, contact me as soon as possible, thank you.

    Enrico aka Alicemirror
    (enrico.miglino@ovi.com)

    ReplyDelete
  7. Chris,

    Its brilliant, thanks! I've also combined it with some AND gates so I use 2 pins to select which device is being controlled by the shift register, and then 3 pins for shift registers. I now have a total of 5 digital pins used for 4 different types of display (2xlcd, 2x7seg display).

    What's best about it is that once I had rewired the board, changed the library it was importing, and used the shiftlcd initialisation, I didn't need to change anything else.

    Thanks very much

    Perry

    ReplyDelete
  8. Chris,
    I too had a number of HC595 available. So I downloaded your library to tried it our. As others have already said, Brilliant.

    I have a number of SPI controlled items in a project, and I am wondering it this library can be converted to use SCK and MOSI and a unique Strobe pin?

    Matthew

    ReplyDelete
  9. Very useful in theory, though I can't get it to work. I just get black bars on the first row and that's it. Checked all connections twice too. The lcds I'm using work just fine with the normal library, am I missing something?

    ReplyDelete
    Replies
    1. Hi,
      I have the same problem. What was the solution? :)

      Delete
  10. Scratch that, I had a 1uf capacitor in the circuit, and removing it fixed it.

    Thank you very much for this!

    ReplyDelete
  11. Hi Chris, nice work!
    Could you help me how to change the delayMicroseconds(); to some no delay() stops because I have a 8x8 LED matrix which starts flickering when I write to the LCD.
    I need the speed because there is a non flickering animation in the background. The rows of the matrix are turned on when a variable reaches a value from 0 to 7.



    void doCountTo8(){
    // count to 8 and set global 8 value
    unsigned long currentMillis = micros();
    if(currentMillis - previousMillis > 400) {
    previousMillis = currentMillis;
    Gl_Counter_8++;
    }
    if (Gl_Counter_8 == 8) {
    Gl_Counter_8=0;
    }
    }

    Thanks:
    Dan

    ReplyDelete
  12. thank you very much for suppling this wonderful library... i try too much to connect Parallel LCD with Serial fashion with 595 shift register,, i tried around 30 times buts i was fail but using your library i was success... thanks a lot....

    ReplyDelete
  13. Thanks, your solution works almost perfectly.
    I just saw an interesting behavior, not sure if this is an issue with your library or is native arduino library doing the same thing (haven't tested yet). When you do lcd.print("1234567890a234567890b234567890c234567890d234567890") with a 16x2 screen, on the second line only the string from letter "d" appears. Any Ideas what might be wrong?

    ReplyDelete
  14. Just installed the library and tested it with an auto-range ohm meter I am busy with at the moment. And it works like a charm. Thanks a lot.
    Saves me some pins for further expansion.

    ReplyDelete
  15. I seem to have a problem writing to the LCD after using backlightOn() and backlightOff().

    In the example Backlight.pde I have just added;
    lcd.setCursor(0,0);
    lcd.Print("some text");

    in the loop.

    After the first call to backlightOn() I get garbled characters.

    Is this a known issue, or am I doing something wrong?

    ReplyDelete
  16. Hello Chris,

    Thanks for your library which works very well with arduino uno...
    But I have recently bought the new chipkit uno32 ("100% compatible" they said...) and ShiftLCD doesn't work with it!
    After many research on google and on the chipkit forum ( http://www.chipkit.org/forum/index.php )I couldn't find ANY SOLUTION...(I am a newbie )
    Do you know how to transfer the library on the uno32?

    Thank you.

    Alexandre C from France

    ReplyDelete
  17. Hi Chris,

    Congrats on what i can see to be excellent code.

    However, summet is scuppering me...

    on compilation in arduino22, i get...

    expected',' or '...' before '&' token

    right at the start of the code..

    Here
    "/**
    * Computerised RC transmitter project
    * Arduino powered PPM transmitter
    * Version 0.2
    *
    * This is the first version to manage to sucessfully output a PPM train to the
    * transmitter and have a receiver decode it into servo movements.
    *
    * The idea behind this project is to take my old 35mHz Micron FM 6D transmitter
    * and replace the PPM encoder board with an Arduino based encoder, allowing me
    * to program in mixers, as well as adjust servo centers, end points and throws.
    *
    --* The PPM pulse chain is produced using--
    timer 1, a 16bit up/down timer.
    */"

    (where the two lines are)

    been over and over the code but cannot find a logical reason for it.

    Have you encountered this before and if so...what was the cause?

    Would love to have a play with your code, bt cant get any further.

    Many thanks.

    Mike.(Norwich UK)

    ReplyDelete
  18. HI Chris,

    Sorry to bother you, any chance you could give 30secs to advise on this?

    Many thanks.

    Mike. (UK)

    ReplyDelete
  19. Hello Chris,

    Thank you for this great library! Now I can go on designing my Arduino-controlled lab power supply / function generator... :-)

    Juha

    ReplyDelete
  20. Hello,

    I was wondering if anyone knew how to make this library work in 1.0?

    Here is the error that I am getting.
    In file included from HelloWorld.cpp:55:
    /Users/dan/Documents/Arduino/libraries/ShiftLCD/ShiftLCD.h:116: error: conflicting return type specified for 'virtual void ShiftLCD::write(uint8_t)'
    /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Print.h:48: error: overriding 'virtual size_t Print::write(uint8_t)'


    Thanks!

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
    2. Sorry, 1st attempt had a badly formatted link:

      You could start by taking a look at Arduino's Release notes here:
      http://arduino.cc/en/Main/ReleaseNotes

      If that doesn't do it try this one from Make:
      http://blog.makezine.com/2011/12/01/arduino-1-0-is-out-heres-what-you-need-to-know/

      Delete
    3. Hi!
      Just replace on line 116 void with size_t
      Also replace Wprorgam.h with Arduino.h

      Delete
  21. To everyone looking for this, can I recommend the more standard LCD3Wires setup and the arduino 1.0 compatible code I wrote do give full LiquidCrystal functionality?
    http://marc.merlins.org/perso/arduino/post_2012-01-23_LiquidCrystal-driver-support-LCD3Wire-hardware-_pebble-and-others_.html

    ReplyDelete
  22. I downloaded and try to use this library, but i giving me some errors even though i replace 116 void with size_t and replace Wprogram.h with Arduino.h
    I am using arduino1.0 Pleae help me

    ReplyDelete
  23. I get an error when compiling the sketch with the Arduino IDE 1.0.
    The error happens on all my computers.

    This is the error:

    In file included from HelloWorld.cpp:55:
    D:\Programma's\Arduino-1.0\libraries\ShiftLCD/ShiftLCD.h:116: error: conflicting return type specified for 'virtual void ShiftLCD::write(uint8_t)'
    D:\Programma's\Arduino-1.0\hardware\arduino\cores\arduino/Print.h:48: error: overriding 'virtual size_t Print::write(uint8_t)'


    How can I solve this problem?

    ReplyDelete
  24. Here's how to make the code compatible with Aruduino 1.0.

    In ShiftLCD.h
    Change line 116 to virtual size_t write(uint8_t);

    In ShiftLCD.cpp
    Change line 6 to #include "Arduino.h"
    Change line 256 to inline size_t ShiftLCD::write(uint8_t value) {

    I also encountered the backlight problem, and I came up with an ugly solution. I have no idea why it solves the issue but I realized that in my code I needed to turn ON the backlight twice before I can input any more text in properly. Same for off, I needed to call the Off twice, reseting the cursor each time and then text will display properly.

    // This will turn the backlight on
    void ShiftLCD::backlightOn(void) {
    _backlight = LCD_BL_PIN;
    updateBacklight();
    setCursor(0,1);
    updateBacklight();
    }

    // This will turn the backlight off
    void ShiftLCD::backlightOff(void) {
    _backlight &= ~LCD_BL_PIN;
    updateBacklight();
    setCursor(0,1);
    updateBacklight();
    }

    Hopefully some can shed some light on this issue and come up with a more elegant fix.

    ReplyDelete
    Replies
    1. Thanks! It works, but "size_t ShiftLCD::write(uint8_t value)" is on line 252 instead of 256!

      Delete
  25. muito bom mesmo,era justamente o que vinha procurando ha algum tempo...

    parabens...,muito bom mesmo ...

    ReplyDelete
  26. Hi Chris,

    Thanks for the information and well laid out documentation. I am currently attempting to interface a 4x20 LCD to an Atmega 328P. Will I require more than one 74HC595?

    ReplyDelete
  27. Thanx for ur post nd ur article, today I just tell u about a biggest retailar in electronics, ya Sargam Electronics is the biggest Retail Chain in Electronics in Delhi. Sargam deals with big brands like Samsung, Sony, Lg, Toshiba, Sansui, Hitachi, Voltas, Godrej, Azure, Nikon, Whirlpool, Dell, HP, Acer and many more brands. Sargam Electronics offers you to buy many electronics products like laptop,mobile,camera,washing machine,refrigerator,air conditionar and multiple electronics products at huge discount.

    ReplyDelete
  28. I could not make this work, even after some adjusts pointed by @Ckwong. Probably I miss something, because the lcd was showing some chars randomly. But it makes me understand how it should work. Thank you Chris Parish.

    At the end I got this: http://playground.arduino.cc/Main/LiquidCrystal.
    It works with my arduino uno 1.0 and. This is a good alternative.

    ReplyDelete
  29. I don't know the answer to that. But maybe one of the readers here can help answer your question here is some more interesting lcd screens

    ReplyDelete
  30. Thanks! It works, but "size_t ShiftLCD::write(uint8_t value)"

    By Marcello BOSS HD

    ReplyDelete
  31. This comment has been removed by the author.

    ReplyDelete
  32. Hi Chris. I find this post really useful but I cant make it compile on arduino 1.05. Please give me some pointers on how to make it work. thanks

    ReplyDelete
  33. Hello, Does this work with Arduino2560? what are the changes to make?

    ReplyDelete
  34. FIXED VERSION AVAILABLE.
    I have posted a clone of this library fixed for Arduino versions 1.0 and greater. You can download it from here: https://github.com/Chris--A/ShiftLCD_Fixed

    All credit to Chris Parish, all I did was add a few lines.

    @Darshan, the library looks like its fine for a Mega2560, with no changes at all.

    ReplyDelete
  35. A digital display with combination of high quality images and video makes a great impact on the buying decisions of buyers.
    High Bright LCD Displays

    ReplyDelete
  36. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
  37. Very effective ! Thanks for this awesome work. I wonder how i could use 2 LCD with this library ? Any idea someone ?

    ReplyDelete
  38. This comment has been removed by the author.

    ReplyDelete
  39. That's actually a really cool application. I didn't think it would be possible (or practical) to control an LCD with a shift register. That being said, how easy would it be to reapply something like in this arduino lcd tutorial?

    ReplyDelete
  40. I can't get the "Hello world" to be printed. I just see the "H" in the first column and then nothing after .
    lcd.print ("Hello world") // prints "h"

    ReplyDelete
  41. /*
    ShiftLCD Library - Hello World

    Demonstrates the use a 16x2 LCD display. The ShiftLCD library works with
    all LCD displays that are compatible with the Hitachi HD44780 driver.
    There are many of them out there, and you can usually tell them by the
    16-pin interface.

    This sketch prints "Hello World!" to the LCD
    and shows the time.

    The circuit:

    ---Shift Register 74HC595---
    * SR Pin 14 to Arduino pin 2
    * SR Pin 12 to Arduino pin 3
    * SR Pin 11 to Arduino pin 4
    * SR Pin 8 to Ground
    * SR Pin 16 to +5v
    * SR Pin 13 to Ground
    * SR Pin 10 to +5v
    -----Shift Reg to LCD--------
    * SR Pin 15 to D7
    * SR Pin 1 to D6
    * SR Pin 2 to D5
    * SR Pin 3 to D4
    * SR Pin 5 to MOSFET gate
    * SR Pin 6 to Enable
    * SR Pin 7 to RS
    -----LCD HD44780-------------
    * Vss to Ground
    * Vdd to +5V
    * Vo to 10k Wiper
    * R/W to Ground
    * 5v to +5v
    * Gnd to MOSFET Drain
    ------N Chanel MOSFET--------
    * Source to Ground
    * Gate to SP Pin 5
    * Drain to LCD Gnd
    * 1k Resistor Between gate and source

    For a more detailed schematic, please see my blog:

    http://cjparish.blogspot.com/2010/01/controlling-lcd-display-with-shift.html

    Library modified from the original LiquidCrystal Library
    This example originaly by Tom Igoe, Jul 2009
    Example modified for use with ShiftLCD
    Chris Parish, January 12th 2010

    */

    // include the library code:
    #include

    // initialize the library with the numbers of the interface pins
    ShiftLCD lcd(2, 4, 3);

    void setup() {
    // set up the LCD's number of rows and columns:
    lcd.begin(16, 2);
    // Print a message to the LCD.
    lcd.print("Hello, World!");
    }

    void loop() {
    // set the cursor to column 0, line 1
    // (note: line 1 is the second row, since counting begins with 0):
    lcd.setCursor(0, 1);
    // print the number of seconds since reset:
    lcd.print(millis()/1000);
    }
    ==== X==== This is the code I am using ==X==

    ReplyDelete
  42. Nice Blog, I really wonder to visit your blog, Thanks a lot! for sharing the useful Information.
    iphone job Oriented course
    iphone app training course
    Best ios training in Hyderabad

    ReplyDelete
  43. This is why it is far better that you can pertinent analysis ahead of producing. It will be possible to post greater article using this method. http://gecey.com/transparent-monitor

    ReplyDelete
  44. Arduino: 1.8.9 (Windows 8.1), Board: "Arduino/Genuino Uno"

    In file included from D:\arduino\HelloWorld_shift_lcd\HelloWorld_shift_lcd.ino:54:0:

    C:\Users\Ahmed\Documents\Arduino\libraries\ShiftLCD/ShiftLCD.h:116:16: error: conflicting return type specified for 'virtual void ShiftLCD::write(uint8_t)'

    virtual void write(uint8_t);

    ^

    In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h:26:0,

    from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:29,

    from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:232,

    from sketch\HelloWorld_shift_lcd.ino.cpp:1:

    C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:51:20: error: overriding 'virtual size_t Print::write(uint8_t)'

    virtual size_t write(uint8_t) = 0;

    ^

    exit status 1
    Error compiling for board Arduino/Genuino Uno.

    This report would have more information with
    "Show verbose output during compilation"
    option enabled in File -> Preferences.

    i got an error to run this code or one of the example codes in the shiftlcd library. i tried changing "WProgram.h" to "Arduino.h", but this error now pops up. help is greatly appreciated, thank you.

    ReplyDelete
  45. Lcd video screen Lcd Video Screen - 7 inch shelf mounting small digital advertising screen for promotion, POS promotional auto play lcd media player is a good choice for video display.

    ReplyDelete
  46. I got some valuable points through this blog. 4.3 inch touch screen

    ReplyDelete
  47. I agree with a lot of the points you made in this article. If you are looking for the led video wall singapore, then visit zoomvisual.com.sg. I love your content, they are very nice and very useful to us and this text is worth everyone’s attention.

    ReplyDelete
  48. digital signage, digital media, digital signage player, digital advertising, advertisement products,digital signage manufacturer

    digital signage players solutions experts, since 1996, digital signage manufacturer,digital media, digital advertising, digital signage company, buy advertisement products, import china goods at commercial-display-manufacturer.com

    Visit here:- Industrial lcd monitor

    ReplyDelete
  49. Thanks for sharing such an amazing article, really informative

    Visit here : LCD Display Screen

    ReplyDelete
  50. Thanks for sharing such a nice blog. Sunul provides the best services of display manufacturer. For more info, visit their website.

    ReplyDelete
  51. This comment has been removed by the author.

    ReplyDelete
  52. Sound system design, audio video presentation system design and acoustical design services throughout India

    Display Panels Manufacturers In India
    Digital Signage Display Solutions In India
    Audio Video Meetings With Konftel In India
    Audio Video Project Management
    Board Room Conference Solutions Suppliers In Delhi

    ReplyDelete
  53. This comment has been removed by the author.

    ReplyDelete
  54. This comment has been removed by the author.

    ReplyDelete
  55. This comment has been removed by the author.

    ReplyDelete
  56. Quality and affordable sound system design, audio/video presentation system design and acoustical design solutions throughout India.
    Top AV Companies In Indial
    Top AV Companies In Indial

    ReplyDelete