Fix LCD flickering problem - Nokia 5110

I have a Nokia 5110 LCS connected to Arduino Uno board. I use it to display temperature, humidity and humidex. Everything works fine so far. But problem is screen flickers a bit. I have tried to figure out to solve myself, but still no success.

Here is the code:

// Sources:
// http://playground.arduino.cc/Code/PCD8544
// http://dlnmh9ip6v2uc.cloudfront.net/datasheets/LCD/Monochrome/Nokia_5110_Example.pde
// http://forum.arduino.cc/index.php?topic=176794.0
#include "DHT.h"
#define DHTPIN 8
#define DHTTYPE DHT22
#include <SPI.h> // We'll use SPI to transfer  data. Faster!
#define PIN_SCE   7
#define PIN_RESET 6
#define PIN_DC    5
#define PIN_SDIN  4
#define PIN_SCLK  2
#define PIN_LCD   3 // backlight
 

#define PIN_FADER A1 // analog
#define PIN_TMP   8 // analog
#define LCD_C     LOW
#define LCD_D     HIGH
#define LCD_COMMAND  0
#define LCD_X     84
#define LCD_Y     48
 
DHT dht(DHTPIN, DHTTYPE);

char strBuffer[30];
int txtCyclesMax = 20;
int txtCyclesCur = 0;
 

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 backslash
,{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 ?
,{0x78, 0x46, 0x41, 0x46, 0x78} // 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);
  pinMode(PIN_LCD, OUTPUT);
  digitalWrite(PIN_LCD, HIGH);
 

  digitalWrite(PIN_RESET, LOW);
  digitalWrite(PIN_RESET, HIGH);
  LcdWrite(LCD_C, 0x21 );  // LCD Extended Commands.
  LcdWrite(LCD_C, 0xB1 );  // Set LCD Vop (Contrast). 
  LcdWrite(LCD_C, 0x04 );  // Set Temp coefficent. //0x04
  LcdWrite(LCD_C, 0x13 );  // LCD bias mode 1:48. //0x13
  LcdWrite(LCD_C, 0x0C );  // LCD in normal mode.
  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);
}
 

void setup(void)
{
  pinMode(PIN_TMP, INPUT);
  pinMode(PIN_FADER, INPUT);
  Serial.begin(9600);
  dht.begin();
  LcdInitialise();
  LcdClear();
  LcdString("Starting");
}
void loop(void)
{
  delay(15);
  long contrast = analogRead(PIN_FADER);
  contrast = (contrast * 255)/1024;
 
  Serial.print("Contrast:");
  Serial.println(contrast);
  txtCyclesCur = txtCyclesCur + 1;
  setContrast(contrast);
  if (txtCyclesCur > txtCyclesMax) {
    LcdClear();
    
    float h = dht.readHumidity();
    float t = dht.readTemperature();
    float f = dht.readTemperature(true);
    float hi = (dht.computeHeatIndex(f, h) - 32)*5/9;

    gotoXY(0,0);
    
    LcdString("Temp.:");
    itoa(t,strBuffer,10);
    LcdString(strBuffer);
    LcdString(" C  ");
    
    LcdString("Humi:");
    itoa(h,strBuffer,10);
    LcdString(strBuffer);
    LcdString(" %   ");
    
    LcdString("Humidex:");
    itoa(hi,strBuffer,10);
    LcdString(strBuffer);
    LcdString(" C");
  };
}
void setContrast(byte contrast)
{
  analogWrite(PIN_LCD, contrast);
}

// position the 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.  
}

Proably bad wiring. I notice something unusual on pin A1. If it is the display that is flickering, this might have something to do with it. It is also possible that 5110 cannot handle the data feed rate. At the moment you are reading and sending data about 50 times a second. Even if 5110 can handle that, I bet you can't, so it might be time to reconsider. You may find that loop cycle is actually down to the 5110, and that can't possibly be a good idea.

You might consider using a library instead of wading though all that stuff. I use the Philips PCD8544, but I think the Henning Karlsen might be better.

You also might consider what you are doing rather than what you merely intend to do. Writing

#include <SPI.h> // We'll use SPI to transfer  data. Faster!

doesn't mean you are actually using SPI.

Hrmm. Bad wiring? Even I don't know how to wire better. Maybe, because I have connected digital wires using 10k resistors without any level shifter, and LED pin using 330R resistor. A1 pin used to adjust brightness. I will try to wire it again. Also I'm going to visit local store to see if any level shifter is in stock.

Removed SPI line. It was a mistake.

I will back again. Thanks!

nebulae:
Maybe, because I have connected digital wires using 10k resistors without any level shifter,

And maybe not. Irrespective of whether it is a good idea or not, that is a fixed situation, whereas you have a varying problem.

A1 pin used to adjust brightness

Probably something you don't need, and possibly the cause of the problem. If you are referring to the brightness of the LEDs, you might question whether you need the LEDs at all. This particularly applies of you have blue LEDs.

Also I'm going to visit local store to see if any level shifter is in stock.

I don't think you need any level shifters, you can just run it off the 3.3v pin.

Take a look at reply # 1 again. The first paragraph mentions more than bad wiring. You probably should consider what Nick said about the data feed rate.

Don

Of course! I have to check my code again. Actually nearly everything was bad designed and I found to many mistakes. Know I have more problems. :slight_smile:

I would like to ask another question, it is necessary to connect SDIN and SCLK pins to Arduino's MOSI and SCK pins, in't it?

nebulae:
, it is necessary to connect SDIN and SCLK pins to Arduino's MOSI and SCK pins, in't it?

No.

Hi,

I have the same screen flicker problem with both my Nokia 5110 LCD's which have just arrived.
One works better than the other; but they both flicker. The contrast varies all the time too.

All my contacts / wiring to the display are as good as I think I can get them, and I took time to solder the header pins carefully to the 5110 with a clean hot iron.

I have given a detailed outline of what I think causes the screen flickering and contrast variation problem with disassembly, photo's and further thoughts here:

Hmmm... Very old post... The reason for the flicker is the use of the LCDClear() command: See source in the first post.

Oliver