Adafruit 20x4 LCD will not work

Hello All,

First time posting...

I have purchased an Adafruit 20x4 LCD (#198) and Adafruit I2C Backpack (#292) from Digi-Key.

I've carefully soldered them together (see photos for questions on solder job).

When I run the hd44780 Diagnostic tool (I2Cexpdiag) I receive the below output in the Serial Monitor and I believe the LCD backlight turns on.

I have attempted to check continuity from appropriate connections and so far haven't found an issue.

Does anyone have any suggestion of what can be the issue?

Thanks,
Jay B.


Serial Initialized

I2CexpDiag - i2c LCD i/o expander backpack diagnostic tool

hd44780 lib version: 1.2.0

Reported Arduino Revision: 1.8.12
CPU ARCH: AVR - F_CPU: 16000000

SDA digital pin: 18 A4
SCL digital pin: 19 A5

Checking for required external I2C pull-up on SDA - YES
Checking for required external I2C pull-up on SCL - YES
Checking for I2C pins shorted together - Not Shorted

Scanning i2c bus for devices..
i2c device found at address 0x20
Total I2C devices found: 1

Scanning i2c bus for all lcd displays (4 max)
No working LCD devices

Did you try and make the change to this address in your sketch ?

i2c device found at address 0x20 <———<<<<

Which Arduino board are you using?

I did make that change in the sketch to see if code would work (it doesn't), but I think it's irrelevant at this point because the diagnostic says:

"Scanning i2c bus for all lcd displays (4 max)"
"No working LCD devices"

I'm not big a fan of the Adafruit #292 backack.
While it works, it seems to have an identity crisis.
It has a shift register on it (that isn't SPI), and a MCP23008 i/o expander
to offer shift register or i2c control.
The MCP23008 takes more bytes over the i2c bus to control the lcd than a PCF8574 chip.
The #292 backpack also didn't hook up the r/w pin to the MCP23008, so you can't do reads from the LCD.
Normally that isn't an issue but it means there is no way to test the internal RAM.
So while it works for an i2c solution, it is a bit slower than the common inexpensive pcf8574 based backpacks at a much higher price point.

Looking at your photos the soldering looks really good.
The i2c chip is showing up.
I'm not sure what is happening. From what I can see, it should be working.
I'd like you to modify the I2CexpDiag sketch so we can see just a bit more about why it couldn't initialize the LCD.

In the diag sketch find the code that looks for the lcds. It starts on line 381
Replace that code with this:

 /*
 * Locate all the displays by attempting to intialize each one
 */
 for(NumLcd = 0; NumLcd < (int) (sizeof(lcd)/sizeof(hd44780_I2Cexp)); NumLcd++)
 {
 char buf[16];
 int status;
 // set custom exectution times if configured
#if defined(LCD_CHEXECTIME) && defined(LCD_INSEXECTIME)
 lcd[NumLcd].setExecTimes(LCD_CHEXECTIME, LCD_INSEXECTIME);
#endif

 // If begin fails, then assume we have no more displays
 if((status = lcd[NumLcd].begin(LCD_ROWS, LCD_COLS)) != 0)
 {
 if(NumLcd == 0)
 {
 Serial.print("LCD 0 begin() failed: ");
 Serial.println(status);
 }
 break;
 }

 setWorkingLCD(NumLcd); // mark LCD as "working"

Then run the diag again so we can see the failure code.

If you want/need, I can email or PM you the full .ino file.

--- bill

jbolyard:
I think it's irrelevant at this point because the diagnostic says:

"Scanning i2c bus for all lcd displays (4 max)"
"No working LCD devices"

Correct.
The diag sketch manages the i2c addresses itself so there is no way to set an i2c address in that sketch as there is no need.

--- bill

With the modified code - the output is... (seems only the second to last line is different)


Serial Initialized

I2CexpDiag - i2c LCD i/o expander backpack diagnostic tool

hd44780 lib version: 1.2.0

Reported Arduino Revision: 1.8.12
CPU ARCH: AVR - F_CPU: 16000000

SDA digital pin: 18 A4
SCL digital pin: 19 A5

Checking for required external I2C pull-up on SDA - YES
Checking for required external I2C pull-up on SCL - YES
Checking for I2C pins shorted together - Not Shorted

Scanning i2c bus for devices..
i2c device found at address 0x20
Total I2C devices found: 1

Scanning i2c bus for all lcd displays (4 max)
LCD 0 begin() failed: -3
No working LCD devices

pert:
Which Arduino board are you using?

An uno style board. Actually at present I'm using my "educato" which I built at the former techshop. I should have noted that prior to connecting this 20x4 LCD I had a 16x2 running just fine using I2C.

I'm confident the issue isn't in the Uno since I can go back to the 16x2 with a PCF8574 backpack and all works fine.

The hd44780_I2Cexp auto configuration is failing to detect the #292 board.
Two things to try.
First lets make sure it works when the backpack type is hard coded.
In the hd44780_I2Cexp helloworld change line 36 from this:

hd44780_I2Cexp lcd; // declare lcd object: auto locate & auto config expander chip

to this:

hd44780_I2Cexp lcd(I2Cexp_MCP23008,1,0xff,2,3,4,5,6,7,HIGH);

Note:
You should have been able to use this:

hd44780_I2Cexp lcd(I2Cexp_BOARD_ADAFRUIT292);

But there is a bug in the code that I'll have fixed in the next release.

If that works,
I'd like to see why the auto configuration is failing.
For that I need you to modify the i/o class header file: hd44780_I2Cexp.h
At line 1151 change this:

// could not identify board
 return(hd44780::RV_ENOTSUP);

to this:

// could not identify board
 Serial.print("MCP23008 data: ");
 Serial.print(data, HEX);
 return(hd44780::RV_ENOTSUP)

Then run the diag sketch again so we can see the data byte read from the MCP23008 chip
note: you don't want to leave that serial print in there, it is just so I can see why the auto config is failing.

--- bill

bperrybap:
First lets make sure it works when the backpack type is hard coded.
In the hd44780_I2Cexp helloworld change line 36 from this:

hd44780_I2Cexp lcd; // declare lcd object: auto locate & auto config expander chip

to this:

hd44780_I2Cexp lcd(I2Cexp_MCP23008,1,0xff,2,3,4,5,6,7,HIGH);

Good Morning Bill - Changing that line of code in hd44780_I2Cexp "helloworld" results in backlight on, but no text on the screen.

Perhaps it is notable also that using the "Adafruit_LiquidCrystal.h" and using that library included "helloworld_I2C" - results in a blinking backlit screen with no text as well.

Because this hardcoding did not work - I'm thinking you don't need/want me to do the rest of your checks?

You should be seeing some pixels on the display. Maybe not the text you expect but at least some pixels/blocks.
If not turn the contrast pot on the backpack until you see something.
If you turn it too far one way, nothing will show up, turn it too far the other way and you should see all the pixels on (blocks on all lines).
If the LCD is not initialized you should see blocks on two rows. row 0, and row 2.

I'm still curious about the auto configuration, so if you have time, I'd like to see what the library is reading from the i/o port to know why it is failing.

--- bill

bperrybap:
You should be seeing some pixels on the display. Maybe not the text you expect but at least some pixels/blocks.
If not turn the contrast pot on the backpack until you see something.

Oh my goodness I'm sorry - yes - the contrast was incorrect and I should have tried that on my own. With the "hard coded" line I am now seeing "Hello, World!" in line 1.

I changed the code you requested and the output provided was:

Scanning i2c bus for all lcd displays (4 max)
MCP23008 data: FF No working LCD devices

We are making some progress! Thank you.

Auto configuration is difficult and a bit problematic on the MCP23008 like it is with the PCF8574.
The issue is that the MCP23008 has high drive and sink pins.
On that chip you can't probe around as much as you can with the PCF8574 since with the high drive pins it can potentially damage the chip or the LCD. Because of this, I'm limited on what I can safely do.

For some reason, that LCD backlight is not biasing the transistor base signal low enough to show up as a low so the auto detection fails.
Lets try turning off the pullup resistor on that MCP pin to see if that will be enough to make it work.

hd44780_I2Cexp.h file line 1096
Change this:

Wire.write(0xff); // turn on pullups

to this:

 Wire.write(0x7f); // turn on pullups, except for D7

If it still fails I need to see the byte read.

--- bill

Even more progress:

The LCD showed:

LCD:0
0x20,M1234567H

Then blinked backlight off, and back on, then the uptime counter runs.

Serial Port shows:

Scanning i2c bus for devices..
i2c device found at address 0x20
Total I2C devices found: 1

Scanning i2c bus for all lcd displays (4 max)
LCD at address: 0x20 | config: M1234567H | R/W control: No
Total LCD devices found: 1

LCD Display Memory Test
Display: 0
(R/W control not supported)

Each working display should have its backlight on
and be displaying its #, address, and config information
If all pixels are on, or no pixels are showing, but backlight is on, try adjusting contrast pot
If backlight is off, wait for next test

Blinking backlight test: to verify BL level autodetection
If backlight is mostly off but
you briefly see "BL Off" on display with backlight on,
then the library autodetected incorrect BL level
and the library cannot autoconfigure the device

Displaying 'uptime' on all displays

Sounds like it is working correctly now.
Could you do a bit of testing to makes sure it works for other various conditions?

Try a few other examples and make sure that they are all working as well.
Make sure to try different ones without powering down between the uploads.
Then try power cycling a couple after uploading to make sure that it works from a fresh power up.
Then also try pressing the Arduino reset button after uploading to make sure a warm start works.

If all that works, I'll consider this a reasonable "fix" and I'll update the code to not enable the pullup on bit 7 during the probing since for some reason that LCD backlight doesn't have the same load characteristics as the ones I've tested and causes auto-configuration to break.
The pullup on that pin shouldn't be needed anyway.
It will be in the next release of the library.

I do thank you for your help getting these issues resolved.

BTW, I'm curious why you went with the Adafruit #292 backpack vs one of the PCF8574 based ones?

--- bill

bperrybap:
Could you do a bit of testing to makes sure it works for other various conditions?

Try a few other examples and make sure that they are all working as well.
Make sure to try different ones without powering down between the uploads.
Then try power cycling a couple after uploading to make sure that it works from a fresh power up.
Then also try pressing the Arduino reset button after uploading to make sure a warm start works.

If all that works, I'll consider this a reasonable "fix" and I'll update the code to not enable the pullup on bit 7 during the probing since for some reason that LCD backlight doesn't have the same load characteristics as the ones I've tested and causes auto-configuration to break.
The pullup on that pin shouldn't be needed anyway.
It will be in the next release of the library.

I do thank you for your help getting these issues resolved.

BTW, I'm curious why you went with the Adafruit #292 backpack vs one of the PCF8574 based ones?

I've now run several other sketches from your examples as well as gone back to my own code. I've hot/cold started with USB power and using 9v wall-wart power, and uploaded many times as I dialed in the display for the 20x4 layout. I believe it is operating correctly now once we have changed that single code line to not pull up D7.

The help I've given you is far less than you've provided for me. I would never have gotten this working without your guidance, so I thank you!

The reason I chose the AF#292 was not really through purposeful intention. I needed a 20x4 screen and was already placing an order at Digi-Key. The only thing I could find there was this Adafruit board and this backpack. I liked this backpack initially because it had screw terminals to connect to rather than the other style with male pins. Eventually this goes into a "permanent" setup and I'm not sure how to make "permanent" connections to male pins... thus screw terminal was nice. If the 2.54mm pitch screw terminals weren't so (relatively) expensive, I'd be buying a bunch of them for all the boards that will connect in this complicated project. (All advice welcome always)

I'm curious - how do you let the world know when you do a new release of your library?

Again - Thank you for your terrific support and assistance.

Jay

jbolyard:
I believe it is operating correctly now once we have changed that single code line to not pull up D7.

Very good news.
I'll push out a new version of the library later today.

The help I've given you is far less than you've provided for me.

My goal is to have a library that "just works" and every little bit helps.

Eventually this goes into a "permanent" setup and I'm not sure how to make "permanent" connections to male pins... thus screw terminal was nice.

Use a 4 pin header cable.
You can get them with female headers on both ends or female on one end and wires with male pins on the other.

I'm curious - how do you let the world know when you do a new release of your library?

The short answer is you don't, as there is no way to do that, But the IDE knows the a new version of the library is available.

the long answer
The Arduino servers maintain a list of all the IDE library manager supported libraries.
They also know where each those libraries "live" on github.
Each hour or so, they check the github repository for each known library and will notice when a new version of the library is released based on seeing a new tag in semver format on its master branch.

When the IDE starts up it downloads a GIANT file that contains all the information about all the known libraries.
The IDE can be configured to automatically install library updates (which I think is the default), or they can be done manually.
I NEVER EVER use automated updates on anything, so I disable the automatic updates in the Arduino IDE.

For typical Arduino users automatic updates is probably ok, but I think that it is not ok for anyone doing library development.
There are some issues with the way the IDE and arduino.cc developers have decided to do core installations and handle updates for the bundled IDE libraries that can break things. IMO, the way the arduino.cc team has decided to do and support bundled updates is really broken and is problematic for several reasons.
One of the main issues is that will break things if you have multiple versions of the IDE installed or use network based home directories. It can also stomp on and clobber libraries in your personal sketchbook library working area.
I have MANY versions of the IDE installed, like 30+ as well as dozens of different processor cores, all for testing so there is no way I'm going to use automatic updates given its issues with multiple IDEs installed and its potential to clobber libraries in your sketchbook working directory.

--- bill

bperrybap:
Use a 4 pin header cable.
You can get them with female headers on both ends or female on one end and wires with male pins on the other.

I wish I understood how finding such a thing is done without hours of searching different websites... or is it really just like that for this hobby. So many small specialized bits needed and finding exactly what is needed at any given time is like needle in a haystack? Maybe I just don't know the right way to search. I type "4 pin header cable 2.54mm pitch" and I don't get anything that looks like it's what I would need.

jbolyard:
Maybe I just don't know the right way to search. I type "4 pin header cable 2.54mm pitch" and I don't get anything that looks like it's what I would need.

It is tough. I also had a tough time finding them a few years back.

"Dupont" is the magic word you are looking for.
You can search for 4 pin dupont header, or 4 pin cable, or 4p dupont cable etc...

Tons of them out there as long as you know the magic word.

--- bill

Sometimes it’s best to Google what you want then select images.

Example

Google 4 pin header cable

https://www.google.com/search?q=4+pin+header+cable&tbm=isch&ved=2ahUKEwib9MzFs4TqAhVTmp4KHT9PCwsQ2-cCegQIABAC&oq=4+pin+header+cable&gs_lcp=ChJtb2JpbGUtZ3dzLXdpei1pbWcQAzICCAA6BAgAEENQoJgBWOCrAWC_rwFoAHAAeACAAVaIAdIDkgEBNpgBAKABAQ&sclient=mobile-gws-wiz-img&ei=kLfnXpvsCNO0-gS_nq1Y&bih=719&biw=1112&prmd=isvn&rlz=1C9BKJA_enCA902CA902&hl=en-US