Comments: Graphic LCD Hookup Guide


Comments 14 comments

  • I only got the code sample to work by restoring the commented code in the LCDWrite() function.

    //Send the data
      digitalWrite(scePin, LOW);
      SPI.transfer(data); //shiftOut(sdinPin, sclkPin, MSBFIRST, data);
      digitalWrite(scePin, HIGH);

    I simply dropped the SPI.transfter call and left the commented code of shiftOut.

    //Send the data
      digitalWrite(scePin, LOW);
      shiftOut(sdinPin, sclkPin, MSBFIRST, data);
      digitalWrite(scePin, HIGH);

    In addition, I used the following setting in the lcdBegin() function to get the best results of contrast and other capabilities:

    LCDWrite(LCD_COMMAND, 0x21); //Tell LCD extended commands follow
    LCDWrite(LCD_COMMAND, 0xc8); //Set LCD Vop (Contrast)
    LCDWrite(LCD_COMMAND, 0x12); //LCD bias mode 1:48 (try 0x13)
    LCDWrite(LCD_COMMAND, 0x20); //chip is active, horizontal addressing, use basic instruction set
    //We must send 0x20 before modifying the display control mode
    LCDWrite(LCD_COMMAND, 0x09); //temperature control
    LCDWrite(LCD_COMMAND, 0x0C); //Set display control, normal mode.
  • ——————– Tech Support Tips/Troubleshooting/Common Issues ——————–

    Scrolling Text

    For code to scroll text, try looking at this blog post => [ ].

  • Great tutorial! However (at least IMHO) you have missed the best 5V to 3.3V level translation option which is usually the 74ahc family. In this case the 74ahc367 hex tristate buffer provides the necessary 5 outputs (with one section unused) for the translation in a single 16 pin DIP package. Note despite some information on the net, the 74HC series is not (at least safely) 5V tolerant. On 74hc there is a clamp diode to vcc on the input which will draw a lot of current when driven with a 5V input. The secret is this line on the data sheet:

    Not 5V tolerant 74hc367 (at least not without heavy current draw!):

    Input clamp current, IIK (VI < 0 or VI > VCC) (see Note 1) ±20 mA

    5V tolerant 74ahc367

    Input clamp current, IIK(VI< 0) –20 mA

    the -20 ma indicates no output clamp diode present as does the lack of VI > VCC on the ahc parts. Note the 74ahc transceivers (such as the 74ahc245) are not 5V tolerant, the possibility the pin can be an output apparently requires the vcc clamp diode, but the buffers, 4 bits 74ahc125, 6 bits 74ahc365/367, 8 bits 74ahc240-244 and 74ahc541 (better pin out!) are all 5V tolerant on their input pins and are all available in dip packages. For the Nokia this setup is working for me (I pulled all the 367 inputs up to 3.3v via a 100K 9 pin SIP bussed resistor pack, pulling up to 5V works as well but requires an extra wire for no real gain assuming 3.3v is above the Arduino input threshold).

    Arduino pin 74ahc367 pin nokia lcd signal name

    gnd        1          -        oe1/     tristate enable active low
     7                 2          -            sce/     chip select in  (5V)
     -                 3          3        sce/     chip select out (3.3v)
     6                 4          -        rst/     reset in  (5v) 
     -                 5          4        rst/     reset out (3.3v) 
     5                 6          -        d/c              data/command in  (5v)
     -                 7          5        d/c              data/command out (3.3v)
    gnd        8          2        gnd      Ground
     -                 9          6        dn(mosi) mosi out (3.3v)
     11       10          -        dn(mosi) mosi in  (5v)
     -                11          7        sclk     sck out  (3.3v)
     13       12          -        sclk     sck in   (5v)
     -                13          -        unused   (3.3v output)
    gnd       14          -        unused   tie to gnd or 3.3/5v (not floating!)
    gnd       15          -        oe2/     tristate enable active low
    3.3v              16          1        vcc      3.3V vcc
     9        - 330 resistor  8        LED      led backlight 
    in the hookup doc a minor typo (the info is elsewhere, just not right here) pin numbers are missing in the "The data pins are connected as follows:"  box:



    should be:

    7 sclk

    8 LED

    as well in Example Code 1: LCD Demo

    the url on the codebender reference would be better as

    which will step you through autoloading and testing the necessary drivers (which the download button doesn’t!) to make codebender work (at least on Firefox). Very handy application for quickly trying some code!

    Peter Van Epp

  • ——————– Tech Support Tips/Troubleshooting/Common Issues ——————–


    If the display is not showing pixels even with the with the correct logic levels and example code [ ], they may just have slight variances in the way that they were manufactured. You can see the pixels faintly on the defective screen at an angle or pushing down on the LCD. You will need to try and set the contrast on line 86 to a value of 60. I think there are some variances in the LCD’s contrast which might explain why certain LCDs have issues displaying defined pixels on the screen.

  • Concerning the off-by-one error…

    The line defining the bitmap for the backslash character will cause problems if there isn’t a space after the backslash character:

      ,{0x02, 0x04, 0x08, 0x10, 0x20} // 0x5c \

    Without a space after the \ the following line will be treated as part of the // comment and thus ignored and this will cause an off-by-one error for all following characters.

  • Hey all - I found Russky’s comment extremely helpful. Changing

    SPI.transfer(data); //shiftOut(sdinPin, sclkPin, MSBFIRST, data);

    to this:

    shiftOut(sdinPin, sclkPin, MSBFIRST, data);

    solved my problems.

    Also regarding the off-by-one character issue: there seems to be an error in the ASCII[] array. The array item for the character ‘]’ is listed twice:

      ,{0x00, 0x41, 0x41, 0x7f, 0x00} // 0x5d ]
      ,{0x00, 0x41, 0x41, 0x7f, 0x00} // 0x5d ]

    Deleting one of those lines solves the off-by-one problem.


  • For those interested, I was able to scroll images across the screen by simply adding a simple new function of getPixel that allowed me to essentially loop over my image, getting the current value at a location, then placing that value slightly left or right on the display, over and over, scrolling the image left or right.

    // get a single pixel
    int getPixel(int8_t x, int8_t y, char *image) {
      if ((x < 0) || (x >= LCD_WIDTH) || (y < 0) || (y >= LCD_HEIGHT))
        return 0;
      return (image[x+ (y/8)*LCD_WIDTH] >> (y%8)) & 0x1;  

    Hope this helps others!

  • Anyone know how to write a function that would scroll a bitmap (such at the sample xkcd cartoon) across the screen coming from completely off the screen on one side to off the screen on the other side?

    I’ve done something simple with using GotoXY, but that has problems with the wrapping of the image. I think I need to write parts of the xkcd bitmap to parts of the displayMap array but I’m finding that difficult to calculate how to do that.

  • I followed the writeup for the hookup and copied the code provided into a sketch. The code compiles and runs, but I don’t see anything on the display. I DO see the LED backlight brightness changing, so the coad has uploaded and runs…

    I’ve played around with a few things. I can modify the LED backlight, and can send data to the serial monitor with debug statements configured to show the bytes that LCDWrite is sending out the data line. So it’s TRYING to do something. I’ve experimented with the screen contrast and have tried changing the write method from SPI back to the commented out shiftOut statement.

    I’ve also downloaded the sketch: which runs and displays to the LCD, but there is something weird going on with the ASCII table. Sometimes it works, but also I’m getting values that are off by one, and other values that are gibberish.

    Any suggestions?

    • Same thing just happened to me with an UNO. The example code didn’t work, so I re-wired to match the default pin settings in the sketch linked by Member #551051 and now both the example code and the linked sketch work correctly:

      • Move MOSI/DIN from pin 11 to pin 4
      • Move SCLK from pin 13 to pin 3

      const int scePin = 7; // SCE - Chip select, pin 3 on LCD const int rstPin = 6; // RST - Reset, pin 4 on LCD const int dcPin = 5; // DC - Data/Command, pin 5 on LCD const int sdinPin = 4; // DN(MOSI) - Serial data, pin 6 on LCD const int sclkPin = 3; // SCLK - Serial clock, pin 7 on LCD const int blPin = 9; // LED - Backlight LED, pin 8 on LCD

    • For the code that doesn’t work, I’d really expect the problem to be contrast. Try using the same contrast as that of the sketch that works (I notice that one sets it to 55 and another to 40). Maybe even try every possible contrast value (0-127) with a for loop after you’ve drawn something.

      For the sketch that does work for you, which characters are printing gibberish or wrong values? Is it repeatable?

      • I’m having the same problem described above. I’ve tried contrast values from 0-127 with no luck. I also tried the sketch mentioned above and it works, with some ASCII table weirdness. The lower-case letters seem to be shifted. The display reads ‘Hfmmp Wpsme!’

  • When I click on the link to download LCD Assistant I get a message that I’m being blocked. Anyone else getting that or am I just special?

  • For me the PCD8544 is what I use instead of the typical 16x2 lcd screens. Not only can you do more with it, I think ease of use and connecting it up is about the same.

If you've found a bug or have other constructive feedback for our tutorial authors, please send us your feedback!