I am interfacing an LCD with an Arduino. Sometimes it shows nothing after uploading the program. What should I do?

enter image description here

  • From what Isee, it does not show "nothing" but it shows entirely black points which is different. If you could post the code you u;load that might help people here trying to find out what happens.
    – jfpoilpret
    Commented Aug 19, 2016 at 19:51
  • 1
    Cannot exactly see from the image, but check your soldering. I feel like some of the pins might be in contact. Also, try changing the contrast with a potentiometer and see what happens.
    – shurup
    Commented Aug 20, 2016 at 3:21

1 Answer 1


An LCD will show blocks like that if it isn't initialized correctly. You may have an intermittently-bad connection on one or more of the control lines. [But see edit 1, below, regarding contrast adjustment.]

To diagnose intermittent connections, you could run a sketch that repeatedly initializes the LCD and then displays different sets of characters for a few seconds. This will allow you to wiggle different pins and find out which is responsible for the bad connection.

To avoid intermittent connections, you could use a shield with soldered pins, or could get multipin shells to replace the single-pin shells of the Dupont-type connectors shown in the photograph. Having adjacent connectors fixed in a single multipin shell results in more-stable connections.

Edit 1: As noted in a comment, blocks appearing on both lines is typical of contrast adjustment problems or missing contrast voltage. On the other hand, blocks appearing on just the first line is typical of incorrect initialization, which could be caused by poor connections or by software errors.

Below is a sketch that repeatedly initializes the LCD and then displays different sets of characters for a few seconds each.

Note, if you don't have the Streaming.h contributed library installed, you can get Streaming5.zip from arduiniana.org.

Note, if not using an I2C-interfaced LCD, change the included LCD library .h from LiquidCrystal_I2C.h to whatever is appropriate, and remove I2C-address-related stuff from the sketch. If you are using an I2C-interfaced LCD on a known fixed address, remove the lcd.setAddress(address); and lcd.getAddress(address); stuff. Those routines are not part of the usual LCD libraries; they probably can be added by subclassing LiquidCrystal_I2C, but on my system I added code as shown after the sketch.

/* Screen-test sketch for PCF8574/PCF8574A/PCF8574T I2C LCD Backpack 
Uses library from https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads GNU General Public License, version 3 (GPL-3.0) */
#include <Streaming.h>
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

enum { LCDcols=16, LCDrows=2 };        // # of rows and cols on LCD
enum { LCDaddr2=0x27, LCDaddr3=0x3F}; // For TI PCF8754 or PCF8754A 
LiquidCrystal_I2C lcd(LCDaddr2,2,1,0,4,5,6,7);

void initLCD(byte address) {
  byte cdata[8];
  Serial << "initLCD(" << _HEX(address) << ')' << endl;
  lcd.setAddress(address);       // Set LCD I2C address
  Serial << "LCD address ... " << _HEX(lcd.getAddress()) << endl;
  // activate LCD module
  lcd.begin(LCDcols, LCDrows);

  // Load custom characters
  for (int c=0; c<8; ++c) {
    unsigned int d = ((c+4)<<12 | (c|3)<<9 | (c|2)<<6 | (c|1)<<3 | c) ^ 0x5555;
    //Serial << "c=" << c << "  d=" << _HEX(d) << endl;
    for (byte k=0; k<8; ++k)
      cdata[k] = d >> k;
    lcd.createChar(c, cdata);
  lcd.home ();

void setup() {
  Serial << "Starting up" << endl;
  Wire.begin();                 // Setup to wirescan to check for 8754 addr
  Serial << "after Wire.begin()" << endl;
  TWBR = 152;  // 50 kHz, use if it works, or use slower rate
  TWBR = 158;  // 12.5 kHz, = slower rate 
  TWSR |= bit (TWPS0);  // change prescaler
  Serial << "after TWBR / TWSR" << endl;
  Wire.beginTransmission (LCDaddr2);
  Serial << "after Wire.beginTransmission()" << endl;
  if (Wire.endTransmission() == 0) // Does 0x27 succeed?
    initLCD(LCDaddr2);          // Set up with 0x27 address
    initLCD(LCDaddr3);          // Set up with 0x3F address
  Serial << "after initLCD()" << endl;

void show(char base, byte delt) {
  enum {MD=2000};
  byte k, ro;
  for (ro=0; ro<LCDrows; ++ro) {
    lcd.setCursor(0, ro);
    for (k=0; k<LCDcols; ++k) {
      base += delt;
  if (base==' ') {
    lcd.setCursor(1, 1);
    lcd << "LCD @" << _HEX(lcd.getAddress()) << " =" << lcd.getAddress();

long p=0;
void loop() {
  byte c;
  Serial << "Pass " << p++ << " on " << _HEX(lcd.getAddress()) << " at t=" << millis() << endl;
  lcd.home ();          // Set cursor to 0,0
  show('#', 0);         // Screen of # characters
  show(' ', 0);         // Screen of ' ' characters
  show('@', 0);         // Screen of @ characters
  show( 0,  1);         // lo specials + ' '...'/'
  for (c=' '; c < '~'; c+=16)
    show(c, 1);

  while (Serial.available()) {
    c = Serial.read();
    if (c == '2') initLCD(LCDaddr2);
    if (c == '3') initLCD(LCDaddr3);

To add lcd.setAddress(address); and lcd.getAddress(address); routines:

// add after void setBacklight(...); in LiquidCrystal_I2C.h
void setAddress(uint8_t addr);
uint8_t getAddress();


// add after void setBacklight(...); in LiquidCrystal_I2C.cpp
void LiquidCrystal_I2C::setAddress(uint8_t addr) {
  LiquidCrystal_I2C::_Addr = addr;
uint8_t LiquidCrystal_I2C::getAddress() {
  return LiquidCrystal_I2C::_Addr;
  • Blocks on the first line means it's incorrectly initialized. But blocks on the both lines means more likely bad contrast voltage.
    – KIIV
    Commented Sep 18, 2016 at 18:19
  • @KIIV, that sounds correct Commented Sep 18, 2016 at 18:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.