Scrolling Text with an Arduino and Nokia 5110 screen

A while ago I purchased a nice little Nokia 5110 screen from MindKits.co.nz (or Sparkfun). It comes complete with a little PCB and a built-in PCD8544 controller.  It took  me a while looking at some different demos on the web to get it working – but once you’ve got it worked out, it is very easy.

It has 8 pins, connect these as follows (or adjust the code below for the correct arduino pins):

  1. VCC (3v arduino output)
  2. GND – Not needed, but if you do some sites say to connect via a small capacitor
  3. SCE – Pin 7
  4. RST – Pin 6
  5. D/C – Pin 5
  6. DN – Pin 4
  7. SCLK – Pin 3
  8. LED (backlight) – No needed, but if you do, remember to use a current limiting resistor!

I took one of the example pieces of code, and improved it with a scroll routine.  Call the ‘scroll(“Message”)’ function in the main loop, and each time the loop repeats, it will scroll the message on one more character, and when needed, it starts looping again.

Here is a video of it working, and below that is the code:

/*
Scrolling text example code
Modified from: http://www.arduino.cc/playground/Code/PCD8544
*/

// The pins to use on the arduino
#define PIN_SCE   7
#define PIN_RESET 6
#define PIN_DC    5
#define PIN_SDIN  4
#define PIN_SCLK  3

// COnfiguration for the LCD
#define LCD_C     LOW
#define LCD_D     HIGH
#define LCD_CMD   0

// Size of the LCD
#define LCD_X     84
#define LCD_Y     48

int scrollPosition = -10;

static const byte ASCII[][5] =
{
 {0x00, 0x00, 0x00, 0x00, 0x00} // 20
,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 '
,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d -
,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c ¥
,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j
,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ←
,{0x00, 0x06, 0x09, 0x09, 0x06} // 7f →
};

void LcdCharacter(char character)
{
  LcdWrite(LCD_D, 0x00);
  for (int index = 0; index < 5; index++)
  {
    LcdWrite(LCD_D, ASCII[character - 0x20][index]);
  }
  LcdWrite(LCD_D, 0x00);
}

void LcdClear(void)
{
  for (int index = 0; index < LCD_X * LCD_Y / 8; index++)
  {
    LcdWrite(LCD_D, 0x00);
  }
}

void LcdInitialise(void)
{
  pinMode(PIN_SCE,   OUTPUT);
  pinMode(PIN_RESET, OUTPUT);
  pinMode(PIN_DC,    OUTPUT);
  pinMode(PIN_SDIN,  OUTPUT);
  pinMode(PIN_SCLK,  OUTPUT);

  digitalWrite(PIN_RESET, LOW);
  digitalWrite(PIN_RESET, HIGH);

  LcdWrite(LCD_CMD, 0x21);  // LCD Extended Commands.
  LcdWrite(LCD_CMD, 0xBf);  // Set LCD Vop (Contrast). //B1
  LcdWrite(LCD_CMD, 0x04);  // Set Temp coefficent. //0x04
  LcdWrite(LCD_CMD, 0x14);  // LCD bias mode 1:48. //0x13
  LcdWrite(LCD_CMD, 0x0C);  // LCD in normal mode. 0x0d for inverse
  LcdWrite(LCD_C, 0x20);
  LcdWrite(LCD_C, 0x0C);
}

void LcdString(char *characters)
{
  while (*characters)
  {
    LcdCharacter(*characters++);
  }
}

void LcdWrite(byte dc, byte data)
{
  digitalWrite(PIN_DC, dc);
  digitalWrite(PIN_SCE, LOW);
  shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data);
  digitalWrite(PIN_SCE, HIGH);
}

/**
 * gotoXY routine to position cursor
 * x - range: 0 to 84
 * y - range: 0 to 5
 */
void gotoXY(int x, int y)
{
  LcdWrite( 0, 0x80 | x);  // Column.
  LcdWrite( 0, 0x40 | y);  // Row.
}

void drawBox(void)
{
  int j;
  for(j = 0; j < 84; j++) // top
  {
    gotoXY(j, 0);
    LcdWrite(1, 0x01);
  }

  for(j = 0; j < 84; j++) //Bottom
  {
    gotoXY(j, 5);
    LcdWrite(1, 0x80);
  }

  for(j = 0; j < 6; j++) // Right
  {
    gotoXY(83, j);
    LcdWrite(1, 0xff);
  }

  for(j = 0; j < 6; j++) // Left
  {
    gotoXY(0, j);
    LcdWrite(1, 0xff);
  }
}

void Scroll(String message)
{
  for (int i = scrollPosition; i < scrollPosition + 11; i++)
  {
    if ((i >= message.length()) || (i < 0))
    {
      LcdCharacter(' ');
    }
    else
    {
      LcdCharacter(message.charAt(i));
    }
  }
  scrollPosition++;
  if ((scrollPosition >= message.length()) && (scrollPosition > 0))
  {
    scrollPosition = -10;
  }
}

void setup(void)
{
  LcdInitialise();
  LcdClear();
  drawBox();

  gotoXY(7,1);
  LcdString("Nokia 5110");
  gotoXY(4,2);
  LcdString("Scroll Demo");
}

void loop(void)
{
  gotoXY(4,4);
  Scroll("Scrolling Message from MindKits.co.nz / blog.stuartlewis.com");
  delay(200);
}

25 thoughts on “Scrolling Text with an Arduino and Nokia 5110 screen

  1. Leonardo

    Hi, this code doesn’t work for me, screen remain off.could you post also your schematics?

  2. transfinite

    It works for me on a duemilanove clone. I did connect pin 2 to ground. Thanks posting it!

    -transfinite

  3. Todd Freeman

    Hi, Stuart. Thanks for the write up. For the first time since buying this nokia 5110 LCD several months ago, I have text being displayed!

    I wanted to comment, not only to thank you for the article, but also say that the ground is required. I am using an arduino Uno, if that matters to you. I tried tying the ground in through a small capacitor as the display had a slight flicker, but no txt. When I removed the capacitor and went straight to ground with pin 2 from the LCD your text came right up.

  4. crunchy

    Thank you a lot for your work! Its works for me. with a lot of try on other site, I begin to think that my device was “kapout”.
    Do you think to use 5V level on a 3.3V is dangerous ?
    Sorry for my english

  5. Pingback: mcnewton's notes » Blog Archive » Nokia screen on Arduino

  6. steve

    Stuart,

    How would I display non-scroling text on this LCD? Just jump over the scrolling function straight to LcdCharacter?

    Based on the code, I am assuming that the max text lines is 5?

    Also, do pins 1, 3, 4, 5, 6, 7 all need to be at 3.3V (pin 2 at ground, pin 8 on 3.3 w/ resistor)?

    This requires a 6 channel logic leveler?

    Thank You.

  7. Troy Dixon

    I found that with the UNO, I had to put a trim pot in place from pin 2 to ground so i could adjust the contrast, if i go straight to ground from display pin 2 gives me a black screen, but if i go through a 10K trim pot (variable resistor – etc.) I can adjust the contrast and get an absolutely beautiful display with the scrolling text. no streaking whatsoever.!! Thanks for the code sample. – Troy Dixon

  8. JIndra

    Hello, I did not get it with pin 2: you do need ground as common reference for all other pins, right? What do you mean by “Not needed, but if you do some sites say to connect via a small capacitor”? Ground means ground, hard ground, zero, right?
    So why should it work without it (because on my Arduino 2009 the screen remains blank)? Small capacitor – to where?
    I am puzzled. To me all of this makes no sense at all :(
    — Jindra

  9. Jindra

    Sorry, I connected all data pins in reverse order, obviously :-)

    It works perfectly. I put LED pin directly on 3.3 V from Arduino, works fine (no regulation at all)

  10. Ajax Jones

    HI
    Great example. I connected the ground though and using an Arduino UNO so using 10K resistors in line with the data pins. Also set the value “Set LCD Vop” to B1 and got a much better contrast that way.

  11. Nick Pyner

    What a great piece of work! Neat, simple, and does what it is supposed to do. I can’t explain it but I have tried three demos and this is the only one that gives a decent output. Now, is it possible to display numerical data with this instead of text strings?

  12. Ben Porter

    Stuart,

    Nice work with this, works well. I was wondering if you’ve had a go at linking up more than one nokia screen? I’m working on a project where I want to have an array of screens all running one image and any insight into how I might achieve this would be very much appreciated.

    Cheers,

    Ben

  13. tm moniruzzaman sunny

    #define PIN_SCE 4
    #define PIN_RESET 3
    #define PIN_DC 5
    #define PIN_SDIN 6
    #define PIN_SCLK 7

  14. Eric-Jan

    Sorry, but i have to mention this the Nokia 5110 display is much cheaper at d x . c o m
    You may also look for the blue pcb version, which is even cheaper than the red pcb version,
    the blue pcb version has also round (pcb) edges, only i do read reports of scratches on the display surface, i bought 5 of the red version, these are in “mint” condition, and come with a pin header you have to solder yourself, but you might use more quality header(s) because you can use these in low hight female headers.

  15. João Carlos Soares de Souza

    Good morning, Stuart.
    I am still new in the area and enjoyed his explanation, just wanted to know how do I get the LEDs light up, because I intend to present their material in College (with your consent, of course), because I am trying to use the LCD, a joystick for Funduino control servos. I thank and congratulate you for your attention excellent material. João Carlos

  16. Eric-Jan

    You can start by connecting the pin marked “LED” on the pcb with a 1K ohm resistor to the suply voltage, if that’s too dim, change the value accordingly.
    They say you can also pwm the LEDs…

  17. Pingback: Make & Do – First Attempt | Sinead Jude Duffy

  18. Dj_Garfield

    OMG !! Thanks a Lot !!! I pray you like a “Messy” , I bought a 5110 LCD to begin a project for my Old Van , and I spend more than 48 hours to get this display working WITH YOUR Pinout AND your Code !!!
    I visit many many many website , where I found some pinout diagram , to another , that I though the LCD was burned to try different wiring (but allways behind 10k Resistors for all except the SCE pin behind a 1k resistor ), and I’m happy to see the nice scrolling you did for this demo !
    Now this is Working and I have to Understand the reason why it didn’t work before , I have to draw a sketch on a paper to see the diff bitween all the pinouts diagram I’ve been tested , I will use Fritzing to KEEP your sketch like a treasure and it will be my reference for the future !
    Thanks a lot , very very VERY MUCH !!

  19. Jordi

    Hi Stuart!

    Thanks to your blog, I’ve been able to test successfully my Nokia 5110 screen! My first attempts didn’t worked cause needed to tweak down the contrast value to 0x9F. After the tweak, I got all the time a black screen.

    Keep up the good work!! ;)

    Best wishes,

    Jordi

  20. Harigovind

    Hi Stuart
    First of all thank you for writing such a neat code. It works very well with the Arduino UNO board. But I am not able to get it working with a PIC. I am using PIC24FJ64GA002. I am getting a blank screen however much I try. Do you have any code that works with the PIC. I used spi communication, applied proper delay but still the screen remains blank.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>