Hello friends, I hope you all are doing great. Today, I am going to share the new Nokia 5110 LCD Library for Proteus V1.0. The Nokia 5110 LCD is the little graphic screen of the old Nokia phones: 84 x 48 pixels, a backlight, and a price that made it a favourite of Arduino beginners for years. It is still one of the cheapest ways to put text, numbers and small pictures on a project. With this Nokia 5110 LCD Library for Proteus, your sketch draws on a Nokia 5110 that behaves like the real one, including its famous contrast trouble.
This is our own model of the module, with the PCD8544 controller written from its datasheet: the SPI interface bit by bit, both instruction sets, the contrast voltage and the backlight. You get four devices: a blue and a white backlight, each as Nokia 5110 Simple, with a live STATUS panel on the schematic, and Nokia 5110 Advance, with a pop-up window, a bus log and four LCD test tools. The demo runs on our Arduino UNO V4.0, with its serial monitor built into the board.
NOTICE: This library is very special to our team. The Nokia 5110 looks simple, but its PCD8544 hides a lot: two instruction sets, a contrast voltage that is different on every module, and a backlight that some boards switch on with HIGH and others with LOW. We modelled all of that from the datasheet, tested it with the real Adafruit library bit by bit, and made the model tell you what went wrong: a contrast that is too high or too low, a missing reset, an address sent in the wrong instruction set. It took our team a lot of hard work and many test runs. Your feedback is the fuel that keeps us going, so please tell us what you think in the comments below or in the LCD Library board of our forum. And if our free libraries help you, you can buy us a coffee. So, let's get started with the Nokia 5110 LCD Library for Proteus V1.0:
What is a Nokia 5110 LCD?
A Nokia 5110 LCD is a small graphic LCD module: an 84 x 48-pixel monochrome glass with the PCD8544 controller, on a board of about 43 x 43 mm with an 8-pin header. It comes from the Nokia 5110 and 3310 phones, and the modules sold today are made for hobby use, most often on a red or a blue board. It is an LCD, not an OLED: the pixels do not make light, they block it. In daylight you read it like a calculator, and in the dark the backlight behind the glass, usually blue or white LEDs, lights it up.
The PCD8544 only knows pixels. Your Arduino library draws letters, lines and pictures into a picture in its memory and sends it to the display over SPI. For the Nokia 5110, that is the job of the Adafruit PCD8544 Nokia 5110 LCD library (its class Adafruit_PCD8544) together with the Adafruit GFX library. U8g2 has a PCD8544 driver too. If you know our OLED libraries, the drawing commands are the same; only the display object, the colours (BLACK and WHITE) and the contrast differ.
The Nokia 5110 at a Glance
| Feature | Value |
|---|---|
| Display | 84 x 48 pixels, monochrome LCD (dark pixels on a light glass), about 1.5" |
| Controller | PCD8544: 504 bytes of display RAM, 6 banks of 84 columns |
| Interface | SPI, write only: CLK, DIN, CE (chip enable), DC (data / command), up to 4 Mbit/s |
| Pins | RST, CE, DC, DIN, CLK, VCC, BL, GND on the red board |
| Supply | 3.3 V (the PCD8544 runs from 2.7 to 3.3 V) |
| Contrast | Set by the sketch: Vop, the LCD voltage, 3.06 V + 0.06 V x Vop |
| Backlight | LEDs on the BL pin; with PWM it dims |
| Arduino libraries | Adafruit PCD8544 + Adafruit GFX: Adafruit_PCD8544 display(5, 4, 3) |
Terms You Will See in This Article
| Term | Meaning |
|---|---|
| SPI | A serial bus: the Arduino clocks the data out on DIN with CLK, CE selects the chip |
| DC (D/C) | Tells the PCD8544 whether a byte is a command (low) or picture data (high) |
| Bank | A band of 8 pixel rows; one byte of a bank is 8 pixels on top of each other |
| Vop | The LCD operating voltage; it sets the contrast |
| Bias | How the controller divides that voltage among the 48 rows; 1:48 suits this glass |
| Extended instruction set | The second command set (after 0x21): Vop, bias and temperature coefficient |
| Frame | One whole picture: the banks one display() of the library sends |
How the PCD8544 Works
Everything the Arduino sends is one byte at a time over SPI: CE goes low, eight bits go out on DIN, one on every rising edge of CLK, most significant bit first, and DC says what the byte is. The controller reads DC together with the eighth bit: low means a command, high means data for the display RAM. That is the whole bus; the PCD8544 never answers.
The commands come in two instruction sets. FUNCTION SET (0x20 to 0x27) works in both and chooses between them with its H bit; it also holds the power-down bit and the addressing direction. The rest depends on H:
| Byte | Basic set (H = 0, after 0x20) | Extended set (H = 1, after 0x21) |
|---|---|---|
| 0x08 - 0x0D | DISPLAY CONTROL: blank, normal, all segments on, inverse | Ignored |
| 0x40 - 0x45 | Y address: the bank (0 - 5) | Ignored |
| 0x80 - 0xD3 | X address: the column (0 - 83) | Vop: the contrast (0x80 + Vop, 0 - 127) |
| 0x04 - 0x07 | Nothing | Temperature coefficient (0 - 3) |
| 0x10 - 0x17 | Nothing | BIAS system (0 - 7) |
Look at the third row: the same byte means two things. 0x80 is "column 0" in the basic set, but "Vop 0" in the extended set, and Vop 0 switches the LCD voltage off. A sketch that forgets to send 0x20 before its addresses loses the whole picture. We will see this below, because our model does exactly that.
Picture data goes into the RAM at the X / Y address, and the address moves on by itself after every byte: across the bank first (horizontal addressing), and at the end of the bank on to the next one. One byte is 8 pixels on top of each other, bit 0 on top, so 6 banks of 84 bytes, 504 bytes, make the whole 84 x 48 picture.
After power-on, the datasheet asks for a reset pulse on RST: until then, every register is undefined. The reset puts the chip in power down with the display blank and Vop 0, so every sketch must set the contrast before it sees anything. The library's begin() does all of this.
What's New in Nokia 5110 LCD Library for Proteus V1.0
Here is what the first version brings:
- The Nokia 5110 module on our own model in
TEPNOKIA5110.DLL: the PCD8544 with its SPI interface, both instruction sets, the 504-byte RAM and the reset. - The contrast made real: Vop against what this module needs (the BESTVOP property), faint below it, grey above it, with the words GOOD, LOW, HIGH, TOO LOW or TOO HIGH on the panel.
- The backlight with PWM on the BL pin, and a BACKLIGHT property for boards that light with BL HIGH or with BL LOW.
- The classic mistakes caught: no reset pulse, Vop 0, an X or Y address in the extended set, power down, a byte cut by CE, VCC above 3.3 V and a reversed supply.
- A real red Nokia 5110 board on the schematic: drawn at twice the real size, with the metal frame, the glass, the 8-pin header and our LEDs and panel button.
- Four devices in
TEPNOKIA5110.LIB: blue and white backlight, each Simple and Advance. - Four LCD test tools on the Advance: Init check, SPI bus, Contrast and Pixels, plus Freeze and a pixel grid on the big glass.
- A two-UNO demo on our Arduino UNO V4.0: the Adafruit PCD8544 library, a dashboard, a contrast SWEEP, the WRONGSET trap, a dimmable backlight and more Serial commands.
- A compact package: about 1.27 MB, without the C++ source code.
Nokia 5110 Simple vs Nokia 5110 Advance
All four devices share one model and the same board. They differ in the backlight colour and in where you see the extras:
| Device | Name in Pick Devices | Backlight | Extras |
|---|---|---|---|
| NOKIA5110BLUETEP | Nokia 5110 LCD 84x48 V1.0 Blue - Simple | Blue | STATUS panel on the sheet |
| NOKIA5110BLUEADVTEP | Nokia 5110 LCD 84x48 V1.0 Blue - Advance | Blue | Pop-up window and tools |
| NOKIA5110WHITETEP | Nokia 5110 LCD 84x48 V1.0 White - Simple | White | STATUS panel on the sheet |
| NOKIA5110WHITEADVTEP | Nokia 5110 LCD 84x48 V1.0 White - Advance | White | Pop-up window and tools |
Pick a Simple LCD when you want the controller's state and its warnings right on the schematic. Pick an Advance LCD when the schematic is crowded, or when you want the bus log, the tools and a big copy of the glass.
Download Nokia 5110 LCD Library for Proteus
Click the button below to download Nokia-5110-LCD-Library-for-Proteus-v1.0.zip (about 1.27 MB, without the C++ source code):
Nokia 5110 LCD Library for Proteus V1.0- README.txt: a detailed guide to the files, the wiring, the controller, the test tools and real hardware.
- Proteus Library Files:
TEPNOKIA5110.LIB(all four devices) and our Arduino library V4.0,ArduinoV4TEP.LIB, with the Arduino UNO V4.0 of the demo. - Proteus Model Files:
TEPNOKIA5110.DLLandTEPARDUINO.DLL. - Proteus Simulation:
Nokia-5110-LCD-ArduinoUnoV4.pdsprj,Nokia5110_Demo.hex(both UNOs run it) and copies of both DLLs. - Arduino Code:
Nokia5110_Demo.ino, the demo sketch. It needs the "Adafruit PCD8544 Nokia 5110 LCD library" from the Library Manager, which offers Adafruit GFX and Adafruit BusIO too.
The Arduino files are the ones of our Arduino Library for Proteus V4.0, so if you have it installed, they are the same. No Proteus yet? Read How to Download and Install Proteus 7 and 8. New to libraries? Follow How to Install a New Library in Proteus.
How to Install Nokia 5110 LCD Library for Proteus
- Close Proteus and extract the whole zip file to a normal folder, for example your Desktop.
- Copy the two files from Proteus Library Files into the LIBRARY folder, usually
C:\Program Files (x86)\Labcenter Electronics\Proteus 8 Professional\LIBRARY(on some PCsC:\ProgramData\Labcenter Electronics\Proteus 8 Professional\LIBRARY; use the folder that already holds Proteus's own .LIB files). - Copy
TEPNOKIA5110.DLLandTEPARDUINO.DLLfrom Proteus Model Files into the MODELS folder. - Delete
TEPNOKIA5110.IDXfrom the LIBRARY folder if there is one; Proteus makes a new index. - Start Proteus, press P and search for NOKIA. You get the four devices.
Tip: the demo project needs the .hex file and the two DLLs beside it, so keep the Proteus Simulation folder together. The library was tested in Proteus 8.5; Proteus 7 is not supported.
The Nokia 5110 Board in Proteus
The part looks like the common red module: the board with its four mounting holes, the metal frame round the LCD glass, and the 8-pin header on the top edge, pins pointing up and printed RST, CE, DC, DIN, CLK, VCC, BL, GND. We drew it at twice the real size, so the 84 x 48 pixels stay readable on a schematic. Here is LCD1, the blue Simple LCD, running the demo's dashboard:
Pinout
| Pin | Name | What it does | Demo connection |
|---|---|---|---|
| 1 | RST | Reset, active low (the PCD8544's RES) | D3 (label D3_1) |
| 2 | CE | Chip enable, active low (SCE) | D4 (label D4_1) |
| 3 | DC | Data / command (D/C): high = data | D5 (label D5_1) |
| 4 | DIN | Serial data in (SDIN, the SPI MOSI line) | D11, hardware SPI (label D11_1) |
| 5 | CLK | Serial clock (SCLK) | D13, hardware SPI (label D13_1) |
| 6 | VCC | Supply, 3.3 V | The UNO's 3.3V pin (label 3V3_1) |
| 7 | BL | Backlight; PWM dims it | D9, a PWM pin (label D9_1) |
| 8 | GND | Ground | GND (net label) |
The Board Up Close
Everything on the board is drawn by the model and changes while the simulation runs. The backlight lights the glass in its colour, a little brighter in the middle like a real LED backlight, and the pixels darken it as much as the contrast allows. The PWR LED is lit while the module has power, and the SPI LED flashes green whenever a byte reaches the LCD. A real module has no such LEDs, so these are our additions to help you see what happens.
LEDs and Indicators
| Indicator | What it shows | On the real module? |
|---|---|---|
| The glass | The backlight colour and brightness, the pixels as dark as Vop makes them | Yes |
| PWR LED (red) | Lit while the module has power | TEP addition |
| SPI LED (green) | Flashes when a byte reaches the LCD | TEP addition |
| SIMPLE / ADVANCE badge, PANEL / OPEN PANEL | Which device this is, and the panel button | TEP addition |
Component Properties
| Property | Meaning | Default |
|---|---|---|
| PANEL | Simple devices only: the STATUS panel at the start, OPEN or CLOSED | OPEN |
| BACKLIGHT | The BL level that lights the backlight, HIGH or LOW | HIGH |
| BESTVOP | The Vop this module looks best at, 20 - 100: a "different module" moves the contrast window | 55 |
Every run starts from these properties. A bad value goes to the simulation log and the default is used.
Contrast: Why Every Nokia 5110 Needs Its Own Vop
Here is the question every Nokia 5110 user asks once: "my display is blank" or "my display is all grey". The answer is almost always the contrast. The PCD8544 makes the LCD voltage itself, and the sketch sets it with Vop, from 0 to 127: VLCD = 3.06 V + 0.06 V x Vop. Too low, and the pixels hardly darken; too high, and the clear pixels darken too, until the whole glass is grey. Because the glass and the chip differ a little from module to module, the right Vop differs too: one module looks perfect at 50, the next at 60.
Our model works the same way. The BESTVOP property says what this module needs (55 by default). From about 12 below it to 16 above it, the picture is GOOD; further away it is LOW or HIGH, and then TOO LOW (faint) or TOO HIGH (dark). We typed CONTRAST 85 into ARD1's monitor:
The simulation log gets a line too: "contrast TOO HIGH (DARK) - Vop 85, this module looks best at 55 (the BESTVOP property): the clear pixels go grey - lower it (setContrast)". CONTRAST 55 brings the picture back. The demo's SWEEP command steps Vop from 25 to 95 with the value big on the glass, so you can find the best value of a real module in a few seconds. The bias matters too: 3 (1:48) or 4 suit this 48-row glass, and other values cost contrast.
The Backlight: BL HIGH or BL LOW, and PWM
The backlight LEDs hang on the BL pin. On many red modules BL HIGH switches them on; on others, BL LOW does, because the LEDs are wired from VCC to BL. That is what the BACKLIGHT property is for. With BL on a PWM pin, analogWrite() dims it: the model measures the share of time BL is on, every 20 ms. We typed LIGHT 60:
With the backlight off (LIGHT OFF), the glass shows its own grey-green colour and the dark pixels on it, as a real module does in daylight.
The Extended-Set Trap: Why the Picture Disappears
Now the mistake that costs people hours. A sketch sets the contrast in the extended set and then, without going back to the basic set, sends its X and Y addresses. Our demo has a command that does exactly that, WRONGSET:
display.command(PCD8544_FUNCTIONSET | PCD8544_EXTENDEDINSTRUCTION);
display.command(PCD8544_SETYADDR | 0);
display.command(PCD8544_SETXADDR | 0);
display.command(PCD8544_FUNCTIONSET);
Follow the bytes, as the model does:
- 0x21 switches to the extended set (H = 1).
- 0x40 is meant as "bank 0", but the extended set has no Y address: the chip ignores it.
- 0x80 is meant as "column 0", but in the extended set it is Vop 0: the LCD voltage goes off.
- 0x20 goes back to the basic set, too late: the picture is gone, although the RAM still holds it.
The model does not just go blank: it knows the 0x40 came in the wrong set, so it reads the next Vop byte as a likely X address. The simulation log says "0x80 SENT IN THE EXTENDED INSTRUCTION SET (H = 1) - there an X address (80-D3) sets Vop and a Y address or display control is ignored: send 0x20 (basic set) first", and the Bus log marks both bytes in red. CONTRAST 55 brings the picture back. The fix in your own code: send 0x20 before any X / Y address or DISPLAY CONTROL.
Nokia 5110 Simple: The STATUS Panel
Under the Simple LCD sits the LCD STATUS panel (see the pictures above):
| Part | What it shows |
|---|---|
| Banner | READY (84x48, Vop, the display mode), WAITING FOR SPI, NO RES PULSE, IN RESET, POWER DOWN, NO LCD VOLTAGE - VOP 0, VOP 0 - AN X ADDRESS SENT IN THE EXTENDED SET?, DISPLAY BLANK, STILL IN THE EXTENDED SET, CONTRAST TOO HIGH / TOO LOW, VCC above 3.3 V, SUPPLY REVERSED or NO POWER |
| DISPLAY | NORMAL, INVERSE, ALL ON, BLANK or POWER DOWN |
| CONTRAST | Vop and the LCD voltage, for example 55 6.36 V |
| BIAS, ADDRESSING | The bias with its multiplex rate; horizontal or vertical addressing |
| BACKLIGHT | ON (BL HIGH), OFF, or the PWM share in % |
| VCC, SPI | The supply voltage; the measured SPI clock |
| FRAME, WRITES | How long one whole picture takes on the bus; the bytes the controller took |
| IGNORED | Bytes in the wrong instruction set, unknown commands, out-of-range addresses, bytes sent during reset or without power, and cut bytes |
| Bus | The last 6 transfers, newest first |
The red X in the panel's header closes it, and PANEL on the board opens it again.
Nokia 5110 Advance: The Pop-Up Window
The Advance LCD keeps only the module on the schematic; LCD2, the white Advance LCD, is in the featured picture at the top. At Run, the "TEP Nokia 5110 LCD Advance" pop-up opens with the look of our TEP Serial Monitor: move it by its header, resize or minimise it, and reopen it with OPEN PANEL. The header has the Display, Bus log and Tests tabs and the theme, Settings and Help icons.
The Display Page
- The glass: a big copy of the LCD in its metal frame, every pixel visible.
- Tiles: DISPLAY, CONTRAST (VOP), LCD VOLTAGE, BIAS, ADDRESSING, INSTRUCTIONS (basic or extended), TEMP. COEFF. and BACKLIGHT.
- The RAM as stored: all 504 bytes, 6 banks of 84 columns, with the X / Y pointer in blue.
- Supply, contrast and frames: VCC, the contrast word against this module's best Vop, the frames received and how long the last one took, the last RES pulse and the pointer.
- The latest transfers: the last commands and data runs, newest first.
Above the glass, GLASS: Live / Freeze holds the picture, and PIXEL GRID: On (x / y) draws a line every 8 pixels with the x and y numbers, Adafruit GFX's coordinates.
The Bus Log Page
The Bus log lists what the controller took, newest first: one row per command with its meaning, or one row per run of picture data. Read it from the bottom up and you see how Adafruit's display() sends a picture: for every bank, a Y address, an X address and 84 data bytes, and at the end one more Y address, bank 0. A command read in the extended set is marked CMD H=1. The Problems filter keeps only what went wrong; after WRONGSET on LCD2 it shows the two bytes in red:
The Tests Page: Four LCD Test Tools
The tools read the bus as the model sees it during the running simulation. Each has a "Good for:" line and a verdict per row: green is fine, amber means check, red means wrong. All the results below come from LCD2 in Proteus 8.5.
1. Init Check: Is begin() Right?
| Check | Result in the picture |
|---|---|
| Power | VCC 3.30 V |
| RES pulse | 1.027 ms long, 66.2 ms after power-on (the bootloader's delay - fine) |
| Power down | Active (PD = 0) |
| Extended set | Used (0x21) for the bias and Vop |
| Bias | 4 (1:40 / 1:34), right for this 48-row glass (Adafruit's default) |
| Contrast (Vop) | 55 = 6.36 V: GOOD (this module looks best at 55) |
| Temperature coeff. | TC 0 (the reset value, fine at room temperature) |
| Back to the basic set | Yes (H = 0): X / Y addresses and the display mode work |
| Display mode | NORMAL, 67.6 ms after power-on |
| RAM | Written |
| Verdict | Initialised like the datasheet |
Good for: "a blank, faint or all-dark Nokia 5110 - is the sketch's begin() right (reset, bias, contrast)?" Below the rows, the start-up as the sketch sent it: power on, the RES pulse, then 21 14 20 (the bias), 21 B7 20 (Vop 55), 20 and 0C (display normal), then the first frame. The datasheet asks for the RES pulse within 30 ms of power-on; on an Arduino the bootloader starts the sketch later, which every real Arduino and Nokia 5110 survives, so the row stays green with a note. After WRONGSET, the same tool turns red:
2. SPI Bus: Is the Sketch Talking to This LCD?
| Row | Result in the picture |
|---|---|
| Wiring | All six signals connected (the demo: CLK D13, DIN D11, DC D5, CE D4, RST D3, BL D9) |
| Measuring for | 25.300 s of simulation: 996 SCE stretches, 26892 bytes |
| Commands / data | 684 command bytes (D/C low), 26208 data bytes (D/C high) |
| CLK | 4.00 MHz (the PCD8544 takes up to 4 Mbit/s) |
| Bytes per SCE stretch | Up to 84 (Adafruit: one command, or one bank of data, per stretch) |
| Time per frame | 5.50 ms on the bus (min 5.49 ms, max 5.54 ms); a full frame is 504 bytes |
| The sketch sends | 2.0 frames per second (one every 492 ms) |
| Bus busy | 1.08 % of the time (CE low) |
Good for: "a blank LCD - a pin not wired, the clock too fast, SCE (CE) or D/C (DC) wrong, slow frames." The UNO's hardware SPI runs at 4 MHz, exactly the PCD8544's limit. A whole frame is only 504 bytes, so even with the library's overhead it takes 5.5 ms: the Nokia 5110 is fast enough for smooth animations. The table at the bottom shows each CE-low stretch: a command byte with D/C LOW, or a bank of 84 data bytes with D/C HIGH. If CE goes high in the middle of a byte, the tool counts a cut byte in red, because the PCD8544 drops those bits.
3. Contrast: Where Is Vop?
| Row | Result in the picture |
|---|---|
| Vop | 76 (0xCC) = VLCD 7.62 V - HIGH |
| This module | Looks best at Vop 55 (the BESTVOP property: modules differ) |
| Set pixels | 95 % dark |
| Clear pixels | 30 % grey - Vop too high: lower it |
| Bias | 4 (1:40 / 1:34) |
| Wrong set | Vop came from 0x80 after a Y address (the earlier WRONGSET) |
| In the sketch | display.setContrast(55); or display.begin(55, 4); |
Good for: "a faint or all-dark picture - every Nokia 5110 needs a slightly different Vop." The scale shows the whole range at once: red far away, amber close, green in the good window around this module's best value. The five swatches show how the glass looks at five Vop values with this backlight and bias, and the last row gives you the line for your sketch.
4. Pixels: Where Does a Pixel Live in the RAM?
Good for: "drawing code and bitmaps - click a pixel: its bank, column, bit and the byte the RAM holds." We clicked x 1, y 18, a pixel of the H: bank 18 / 8 = 2, bit 18 % 8 = 2, column 1. In Adafruit's buffer the same pixel is byte 1 + 2 x 84 = 169, and to write it yourself you would send Y = 0x42 and X = 0x81 in the basic set, then the byte.
Nokia 5110 LCD with Arduino in Proteus
Open Nokia-5110-LCD-ArduinoUnoV4.pdsprj from the Proteus Simulation folder, with Nokia5110_Demo.hex and both DLLs beside it. The demo runs on two of our Arduino UNO V4.0 boards from the Arduino UNO Library for Proteus V4.0: the board has working ON / L / TX / RX LEDs, a RESET button and a serial monitor built into the board, so there is no Virtual Terminal to wire. Both UNOs run the same HEX file:
- NODE 1 - SIMPLE (on-sheet panel, blue): ARD1 with LCD1 (blue backlight, Simple).
- NODE 2 - ADVANCE (pop-up panel, white): ARD2 with LCD2 (white backlight, Advance).
Wiring
| LCD pin | Arduino UNO | Why |
|---|---|---|
| RST | D3 | Reset (any pin) |
| CE | D4 | Chip enable (any pin) |
| DC | D5 | Data / command (any pin) |
| DIN | D11 (MOSI) | Hardware SPI data |
| CLK | D13 (SCK) | Hardware SPI clock |
| VCC | 3.3V | The PCD8544 is a 3.3 V chip |
| BL | D9 | A PWM pin, so the backlight can dim |
| GND | GND | Ground |
| Serial monitor | Nothing to wire | Built into the UNO V4.0 on D0 / D1, like the real UNO's USB chip |
On an Arduino UNO, the hardware SPI pins are D11 (MOSI) and D13 (SCK) (see our Introduction to Arduino UNO); CE, DC, RST and BL can be any pins. Every LCD pin goes through a short wire to a net label: terminals with the same name are connected. D3_1 at LCD1's RST meets D3_1 at ARD1's D3, and so on; VCC goes to 3V3_1, the label on the UNO's 3.3V pin, and node 2 has its own labels ending in _2.
The Arduino Code
The demo sketch, Nokia5110_Demo V1.0, uses the Adafruit PCD8544 Nokia 5110 LCD library (version 2.0.3) with the Adafruit GFX library (version 1.12.6) and Arduino's SPI library. It starts with the display object; with three pin numbers, the library uses the UNO's hardware SPI for CLK and DIN:
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
Adafruit_PCD8544 display(5, 4, 3); // DC, CE (chip select), RST - CLK and DIN are the UNO's SPI pins D13 / D11
const byte BACKLIGHT = 9; // BL: HIGH = backlight on (most modules), PWM dims it
In setup(), the sketch clears the library's buffer first (it starts with Adafruit's splash picture), then begin() sends the RES pulse, the bias, the contrast and DISPLAY NORMAL, the start-up you saw in the Init check:
display.clearDisplay(); // (an empty first frame instead of the library's splash)
display.begin(contrast, bias); // RST pulse, bias, contrast, normal mode
Everything the sketch draws goes into the 504-byte buffer first, in BLACK (a dark pixel); display() sends it, and the demo counts the frames:
void show() { display.display(); frames++; }
The backlight is a plain analogWrite() on D9:
void setLight(byte level) { // BL HIGH = on (most modules); 0 - 255 dims it with PWM
light = level;
analogWrite(BACKLIGHT, light);
}
SWEEP shows the contrast range on the glass. setContrast() sends 0x21, 0x80 + Vop and 0x20, so it goes back to the basic set itself:
for (byte v = 25; v <= 95; v += 5) {
display.setContrast(v);
display.clearDisplay();
display.setTextColor(BLACK);
display.setTextSize(1);
display.setCursor(0, 0);
display.print(F("CONTRAST"));
display.setTextSize(3);
display.setCursor(24, 16);
display.print(v);
show();
Serial.print(F("Contrast ")); Serial.println(v);
delay(400);
}
SLEEP and WAKE use the library's command() with FUNCTION SET: the power-down bit blanks the glass, and the RAM keeps the picture:
display.command(PCD8544_FUNCTIONSET | PCD8544_POWERDOWN); // power down: the glass goes blank, the RAM stays
To change the sketch, install the libraries from the Library Manager, export a new HEX file and load it into both UNOs; see How to get the HEX file from Arduino. New to Arduino? Start with our Arduino Tutorial for Beginners.
Serial Monitor Commands
| Command | What it does |
|---|---|
| HELP | The command list |
| STATUS | The screen, the text, the lower part, contrast, bias, inverse, the backlight, asleep or awake, the frames |
| TEXT <text> | The big line (up to 14 characters; 7 fit at size 2) |
| SIZE <1-2> | Its text size |
| GRAPH / BAR <0-100> | A moving sine wave / a bar in the lower part |
| LOGO, SHAPES, DASH | The TEP logo, GFX shapes with a frame round the whole glass, the dashboard again |
| CONTRAST <0-127> | Vop, the LCD voltage (the demo starts at 55) |
| SWEEP | Vop 25 to 95 in steps of 5, the value big on the glass, then back |
| BIAS <0-7> | The bias system (Adafruit's default 4) |
| LIGHT ON / OFF / <0-255> | The backlight on D9, with PWM |
| INVERT ON / OFF | Inverse: the controller swaps dark and clear pixels |
| SLEEP / WAKE | Power down / up (the RAM is kept) |
| WRONGSET | The classic mistake: Y 0 and X 0 sent in the extended set |
| CLEAR | An empty screen (DASH brings the dashboard back) |
How to Run the Demo
- Press Run. Both UNOs' monitor windows and LCD2's pop-up open; move them aside, as they open over the schematic. The LCDs show the TEP logo for a second, then the dashboard.
- Type STATUS, CONTRAST 85, CONTRAST 55 and LIGHT 60 in ARD1's monitor and watch LCD1 and its panel.
- Type WRONGSET, then CONTRAST 55, and SWEEP in ARD2's monitor.
- On LCD2's pop-up, turn on the pixel grid, look at the Bus log, and run the four tools.
- Press the RESET button of a UNO: the bootloader flashes L, and the sketch starts again 1 s later.
Nokia 5110 LCD Proteus Simulation Results
The Built-in Serial Monitor in Its Simple Interface
Each Arduino UNO V4.0 carries its own copy of our TEP Serial Monitor Advance, wired inside the board to D0 / D1 like the USB chip of a real UNO. Its window, "TEP Arduino UNO - ARD1", opens at Run, and a click on the board's USB port opens it again. The screenshots show its Simple interface: only the log and the line to send.
- Switch to it: press Ctrl+Shift+U, or use the monitor's ... menu.
- Back to the full view: press Esc; the full view has the Board, Monitor and Plotter tabs.
Read all about the monitor in TEP Serial Monitor Advance for Proteus.
ARD1: STATUS, CONTRAST, LIGHT and WRONGSET
The featured picture at the top shows ARD1's start and its STATUS answer:
Nokia 5110 V1.0 demo - The Engineering Projects
LCD ready: contrast 55, bias 4
Type HELP for the commands
STATUS
Nokia 5110 84x48 (PCD8544)
Screen: dashboard
Text: Hello (size 2)
Lower part: sine wave
Contrast 55, bias 4, inverse off
Backlight 255/255 on D9, awake
Frames sent: 103
Then the commands behind the pictures above, contrast, backlight and the extended-set trap:
CONTRAST 85
OK - contrast 85
CONTRAST 55
OK - contrast 55
LIGHT 60
OK - backlight 60
LIGHT ON
OK - backlight 255
WRONGSET
Sent Y 0, X 0 in the EXTENDED set: X became Vop 0
CONTRAST 55 brings the picture back
CONTRAST 55
OK - contrast 55
Every answer starts with OK, so you see at once that the sketch understood the command. WRONGSET explains itself, and the model confirms it on the panel and in the log.
ARD2: SWEEP
Contrast 45
Contrast 50
Contrast 55
Contrast 60
Contrast 65
Contrast 70
Contrast 75
Contrast 80
Contrast 85
Contrast 90
Contrast 95
Back to contrast 55
While SWEEP runs, the value stands big on LCD2's glass: faint at 25, crisp around 55, grey from about 75. On a real module, note the value that looks best and use it with setContrast().
Troubleshooting
- The glass stays plain and the PWR LED is off: no power. Check VCC and GND (the panel says NO POWER with the voltage; the module needs 3.3 V).
- WAITING FOR SPI: nothing reached the LCD. Check CLK to D13, DIN to D11, CE and DC; the SPI bus tool lists the pins that are not connected.
- NO RES PULSE: RST never went low after power-on. Wire RST and call
display.begin(), which pulses it. - NO LCD VOLTAGE - VOP 0: the contrast was never set, or set to 0.
begin()sets it;display.setContrast(55)too. - VOP 0 - AN X ADDRESS SENT IN THE EXTENDED SET?: send 0x20 before X / Y addresses and DISPLAY CONTROL.
- DISPLAY BLANK or POWER DOWN: send DISPLAY NORMAL (0x0C), or FUNCTION SET 0x20 to wake the chip.
- CONTRAST TOO HIGH (grey or dark glass) / TOO LOW (faint picture): change Vop with
setContrast(), or the BESTVOP property if your module differs. - No backlight: check BL (D9) and the BACKLIGHT property, HIGH or LOW.
- Random dots for a moment at the start: the RAM before the first frame. Call
display.display()after drawing. - The part or the UNO is not simulated, or no monitor window: TEPNOKIA5110.DLL or TEPARDUINO.DLL is missing from MODELS and the project folder; a closed monitor opens again with a click on the UNO's USB port.
- The Advance pop-up does not appear: click OPEN PANEL on the board, or turn "Open the panel at Run" back on in Settings.
Things to Know Before Using a Real Nokia 5110 LCD
The demo sketch uses only SPI, the Adafruit libraries and Serial, so it runs on a real UNO and Nokia 5110 too. Keep in mind:
- 3.3 V: give the module 3.3 V. Its inputs are not 5 V tolerant on paper, so on a 5 V Arduino use a level shifter such as a 74HC4050, or 10 kohm resistors in series with RST, CE, DC, DIN and CLK. In Proteus no level shifting is needed.
- The contrast: every module needs its own Vop; most are fine between 40 and 70. Use SWEEP to find yours.
- The backlight: check whether your module lights with BL HIGH or BL LOW, and add a 330 ohm resistor if its LEDs have none.
- Pin names differ: the red module prints RST CE DC DIN CLK VCC BL GND, the blue SparkFun-style board VCC GND SCE RST D/C DN(MOSI) SCLK LED. They are the same signals.
- RAM: Adafruit_PCD8544 keeps a 504-byte picture buffer; our demo uses 1,128 bytes of the UNO's 2,048 with it.
- A slow glass: the LCD pixels need some time to change, and the glass gets faint in the cold; the temperature coefficient helps there.
Limitations of the Simulation
- Not modelled: the LCD's slow response and temperature (the temperature coefficient is stored and shown), timing violations shorter than the simulation's edges, the current draw, and damage from 5 V or a reversed supply (the model only warns). The PCD8544 has no read, so nothing is read back.
- The board is drawn at twice the real size; the LEDs, the badge and the panel button are TEP additions.
- The model is our own implementation, written from the PCD8544 datasheet. Nokia is a trademark of Nokia Corporation; PCD8544 is a Philips (now NXP) part. This library is not made or endorsed by Nokia, NXP, Adafruit or Labcenter.
- Licences: the demo sketch uses Adafruit PCD8544 2.0.3, Adafruit GFX 1.12.6 (BSD licence), Adafruit BusIO and Arduino's SPI library. The HEX file contains them and the Arduino AVR core 1.8.6, which includes LGPL-licensed code; its source code is on GitHub. The README holds the Adafruit licence texts.
- Tested in Proteus 8.5 in October 2026 (the demo as shipped on two Arduino UNO V4.0 boards with their built-in monitors, the dashboard, the Serial commands, the contrast, the backlight, WRONGSET, SLEEP / WAKE and SWEEP, the panel, the pop-up and the four tools, and every screenshot here; about 0.3 - 0.4 x real time with the pop-up and both monitors open on a busy PC) and with automatic PC checks, 0 failed: 97 with the real demo sketch and the unmodified Adafruit libraries talking bit by bit to the model, where the glass equals Adafruit's own buffer after every frame, 89 on the PCD8544 and its SPI interface, and the demo project read back from disk. Proteus 7 is not supported.
If you like this display, have a look at our other graphic displays too, the OLED SSD1306 Library for Proteus V1.0 and the OLED SH1106 Library for Proteus V1.0, and at our character LCDs, the LCD 16x2 Library for Proteus V3.0 and the LCD Keypad Shield Library for Proteus V1.0.
So, that was all about the Nokia 5110 LCD Library for Proteus V1.0. I hope the two instruction sets, the contrast and the backlight make the Nokia 5110 easy to understand, so your display works the first time you wire a real one. If you use the Nokia 5110 LCD Library for Proteus in a project, please share your feedback in the comments or in our forum, and if you have any questions, ask in the comments and I will help you out. Till the next tutorial, take care and have fun!