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):
- VCC (3v arduino output)
- GND – Not needed, but if you do some sites say to connect via a small capacitor
- SCE – Pin 7
- RST – Pin 6
- D/C – Pin 5
- DN – Pin 4
- SCLK – Pin 3
- 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);
}
In: Uncategorized · Tagged with: arduino



on July 7, 2011 at 1:15 pm
Permalink
Hi, this code doesn’t work for me, screen remain off.could you post also your schematics?
on July 7, 2011 at 1:21 pm
Permalink
Sorry – I don’t have a schematic, but the post lists the pins to connect.
on July 7, 2011 at 10:39 pm
Permalink
I’ve tried with an Arduino Uno but nothing.. display stay off
on July 10, 2011 at 4:24 pm
Permalink
It works for me on a duemilanove clone. I did connect pin 2 to ground. Thanks posting it!
-transfinite
on August 25, 2011 at 12:34 pm
Permalink
Hey, don’t you want 3.3V on those input pins, too?
on October 24, 2011 at 5:00 am
Permalink
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.
on October 28, 2011 at 10:04 pm
Permalink
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
on November 12, 2011 at 3:11 pm
Permalink
[...] just to wire it all up, then test. I found a great scrolling message example by Stuart Lewis with wiring instructions and code, although he wired his screen directly with 5v. It looks [...]
on December 2, 2011 at 5:54 pm
Permalink
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.
on February 3, 2012 at 7:25 pm
Permalink
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
on February 4, 2012 at 10:45 pm
Permalink
Nice work Stuart….. Thanks heaps, I’m building an alarm and using this in RFID wall plate….
on February 27, 2012 at 1:42 am
Permalink
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
on February 27, 2012 at 4:18 am
Permalink
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)
on May 9, 2012 at 4:28 pm
Permalink
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.