Problem with either LCD displayer or backpack

I have tried really really hard, for way too many hours and I'm unable to make my LCD displayer work properly.

I have made an experimental circuit to test the LCD. Basically, the LCD is connected directly to the Arduino and it doesn't work. I have done all the following:

  • Checked the wiring:
    Everything correct, I just have 4 wires
  • Used I2C scanner to get I2C address:
    0x20
  • Used I2C guesser to get LCD pin layout:
    Device found: MCP23008
    Only supports PCF8574
  • Added pull-up resistors to my experimental circuit:
    Adding it, makes the LCD contrast too high and nothing can be seen, even if adjusting the backpack potentiometer
  • Set LCD backpack mode as I2C:
    Was just a switch between SPI and I2C
  • Adjust the potentiometer on the LCD backpack:
    Adjusted properly so a row with white squares can be seen
  • Searched a lot of information, documentation, tutorials, arduino forums:
    Nothing worked
  • Tried 4 different libraries: Adafruit_LiquidCrystal-master, LiquidCrystal_I2C, Newliquidcrystal_1.3.5, SPI_IIC_LCD
    None of them worked, but Adafruit_LiquidCrystal-master is the library which I have had most "success"

First of all, the LCD and backpack was given to me, so to begin with, I didn't know what model the LCD displayer was because the backpack was hiding it. Searching in the Internet, I managed to get the LCD displayer model I am exactly using: Standard LCD 16x2 + extras [white on blue] : ID 181 : $9.95 : Adafruit Industries, Unique & fun DIY electronics and kits. About the backpack, unluckily, I haven't found anything regarding about it.

The furthest I could manage to make the LCD + backpack "to work" is using Adafruit_LiquidCrystal-master library as stated before and with the following testing code:

#include "Wire.h"
#include "Adafruit_LiquidCrystal.h"

Adafruit_LiquidCrystal lcd(0);

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.home();
  lcd.print("Test");
}

void loop() {
  if (Serial.available()) {
    lcd.clear();
    delay (500);
    lcd.write(Serial.read());
  }
}

To sum up the code, I initialize the LCD, print on its screen the word "Test" and then infinitely print each character the user sends by the serial port in the LCD for half a second and then erases it. Of course, the LCD doesn't do anything of this, the LCD only displays a row of white squares and turns on and off the LDC backlight when using lcd.clear()

If someone is kind enough to give me a working example program configured for my LCD + backpack that prints on the scren "Hello world!" or something similar, I just need to make my LCD + backpack work. I will be very grateful.

Adding a few attachment photos.
I know that the Arduino UNO is a chinese brand one, it was given to me, like the LCD.

You might try the hd44780 library. That library will work with MCP23008 backpacks, auto detects the I2C address and auto detects the backpack to LCD pin mapping. Best LCD library available to date. The library is available to be installed using the IDE Library Manager.

groundFungus:
You might try the hd44780 library. That library will work with MCP23008 backpacks, auto detects the I2C address and auto detects the backpack to LCD pin mapping. Best LCD library available to date. The library is available to be installed using the IDE Library Manager.

Tried the suggested library and used the default Hello world program after adding a few serial ports for checking stuff. The program gave me status = -4 which means: no such device or address

Okay, I changed the LCD initialization and added the address the I2C scanner gave me which is 0x20 and the program gave me this time status = 0, so it got past through the if (status) conditional but didn't print in the LCD "Hello, World!" as it was supposed to and then entered void loop ().

Not sure if this might be helpul or not but when using the correct I2C address (program I posted below), the LCD backlight turned off meanwhile in the default program, the LCD backlight was always on.

#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Clcd.h>

hd44780_I2Clcd lcd(0x20);

const int LCD_COLS = 16;
const int LCD_ROWS = 2;

void setup () {
  Serial.begin (9600);
  int status;
  status = lcd.begin(LCD_COLS, LCD_ROWS);
  Serial.println (status);
  if (status) {
    status = -status;
    hd44780::fatalError(status);
  }
  Serial.println ("Out of status");
  lcd.print("Hello, World!");
}

void loop () {
  Serial.println ("Loop");
  delay (1000);
}

I can only think of 2 options of why the lcd didn't print "Hello, World!":

  • Library failed to get correct pin mapping (which I believe this is the case)
  • The LCD itself has a problem

Waiting for new ideas which might solve my problem

#include <hd44780ioClass/hd44780_I2Clcd.h>

You used the wrong class. Replace that line with:

#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header

There is a diagnostic program in the I2Cexp class examples for the hd44780 library. If the code does not work after changing to the right class, load and run the diagnostic and post the results here.

The I2Clcd class is for LCD controllers that have a native I2C port. LCDs with the hd44780 LCD controllers and I2C expanders (backpacks) are different and use the I2Cexp class.

groundFungus:
The I2Clcd class is for LCD controllers that have a native I2C port. LCDs with the hd44780 LCD controllers and I2C expanders (backpacks) are different and use the I2Cexp class.

This fixed my problem.

Thanks!

It would be nice if you edit the title of your thread to add solved. It would prevent members from opening your thread to help you only to find that you no longer need help.

I have become stuck on another problem which makes zero sense.

My LCD seems to be unable to update itself when I send data to it. It can only print the first thing it finds and then "freezes". However, this also happens with example programs from the library.

I made the following program for testing purposes:

#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h>

hd44780_I2Cexp lcd;

const int LCD_COLS = 16;
const int LCD_ROWS = 2;

void setup () {
  int status;
  status = lcd.begin(LCD_COLS, LCD_ROWS);
  if (status) {
    status = -status;
    hd44780::fatalError(status);
  }
}

void loop () {
  for (int i = 0; i < 10; ++i) {
    lcd.print(i);
    delay (5000);
    lcd.clear(); 
  }
}

A program that infinitely prints every 5 seconds a number from 0 to 9. However, since my LCD gets "stuck" at the first thing it finds, it only prints 0. I gave the program a big delay, to check if the LCD was really slow in updating himself but that doesn't seem the case because of what I will say after this.

Surprisingly, I2CexpDiag, works fine. In the end of I2CexpDiag, there is a part where the LCD has to keep updating the runtime of the program every second and it doesn't freeze.

So no idea, how to fix this. As I said, makes no sense to me.

Me either. The author of the hd44780 library, bperrybap, frequents this forum. Perhaps he will know what might be the issue. The code works fine with my I2C LCD, but it is PCF8574 based.

I have some new information.

Using the UpTime example and modifying it for testing purposes.

#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h>

hd44780_I2Cexp lcd;

const int LCD_COLS = 16;
const int LCD_ROWS = 2;

void setup () {
  Serial.begin(9600);
  int status;
  status = lcd.begin(LCD_COLS, LCD_ROWS);
  Serial.print("Setup status: ");
  Serial.println(status);
  if (status) {
    status = -status;
    hd44780::fatalError(status);
  }
  lcd.print(" UpTime");
  if(LCD_ROWS < 2) delay(3000);
}

void loop () {
  static unsigned long lastsecs = -1;
  unsigned long secs;
  int status;
  secs = millis() / 1000;
  if(secs != lastsecs) {
    lastsecs = secs; 
    status = lcd.setCursor(0, 1);
    Serial.print("Loop status: ");
    Serial.println(status);
    if (status) {
      status = -status;
      hd44780::fatalError(status);
    }
    PrintUpTime(lcd, secs);
  }
}

void PrintUpTime (Print &outdev, unsigned long secs) {
  unsigned int hr, mins, sec;
  mins =  secs / 60;
  hr = mins / 60;
  mins = mins % 60;
  sec = secs % 60;

  if(hr > 99) hr %= 100;
  if(hr < 10) outdev.write('0');
  outdev.print((int)hr);
  outdev.write(':');
  if(mins < 10) outdev.write('0');
  outdev.print((int)mins);
  outdev.write(':');
  if(sec < 10) outdev.write('0');
  outdev.print((int)sec);
}

The following happens, in 95% of times, the program will never leave the void setup because status = -3 which means device not support.

Okay, that itself is weird because I can see things written on the LCD, but wait a moment if the program never leaves the void setup (if (status) conditional), how the hell it managed to print "UpTime" and then "00:00:00", of course the program freezes at first input, so it stays "00:00:00".

In rare cases, 5% of times, the program will work fine becauses status = 0. Yep, don't ask me why, cause no idea. But this is not a solution, to my problem, I need a definitive solution!

Also, read all the I2CexpDiag program to find why in that program it always work but got nothing useful.

The diagnostic sketch should always be the first thing run on new h/w.
It is designed to test the s/w and hardware interface and then the LCD ram to try to detect issues.
What results do you get from the diagnostic sketch?
(post the output)

--- bill

Also, can you post some photos of you LCD & backpack. So we can take a look at it and look at the soldering and wiring.
When results are strange, often there can be a soldering or wiring issue.

--- bill