Lcd.init() fails SOMETIMES (Solved)

I have a sketch that is used in an Uno for controlling 90 LEDs' brightness based

on ambient light. The LEDs are in a hutch behind a 1/2-inch-thick glass shelf with a
curved, crescent-moon-shaped leading edge which glows green due to the LEDs
shining through from the back edge. When more ambient light is present, the LEDs
glow brighter. When less ambient light is available, they reduce brightness, thereby
keeping the leading edge of the glass pleasantly illuminated in all ambient light
conditions.

My project also has an LCD which is used to display a menu of choices to alter 

the minimum and maximum LED brightness limits. The LCD goes to sleep (power is
removed via a relay) when the menu is not being presented. The menu is invoked
by pressing a momentary-type tactile button. Everything in the project works,
except...

About a third of the time, during the invocation of the menu, the sketch hangs 

while trying to INITIALIZE the LCD unit. Here is the code where the sketch turns the
LCD to its ON state:

buttonPressed = (!(digitalRead(pin_Button_D02)));
if (buttonPressed) {
if (!theLCDisON) {
wdt_reset();
sub_reconnectTheLCD(); // <<<= This subroutine sometimes hangs.
wdt_reset();
}
while (buttonPressed) { ...

void sub_reconnectTheLCD() {
digitalWrite(pinRelayLCDOnOffD12, HIGH); // Relay provides power to LCD
delay(750); // Thought this might help with INIT, but it doesn't.
//Serial.println(F("Reconnect is going into INIT..."));
wdt_reset();
lcd.init(); // This hangs SOMETIMES. Tried another LCD. No difference.
//Serial.println(F("Reconnect Going into BEGIN..."));
lcd.begin(16, 2);
theLCDisON = true;
//Serial.println(F("Reconnect End of Reconnect"));
}

I've tracked the error to the "lcd.init()" statement. The sub_reconnectTheLCD() is also called from SETUP, and never fails in the SETUP calls. This only seems to fail when the program is running and the menu is invoked -- but again, most of the time, it works fine. I've introduced watchdog logic so that, when the "lcd.init()" statement hangs, the Uno reboots. But that's not very elegant, and I'd like to know how I can find out what's going wrong in the library code where "lcd.init()" is being executed. Here are my #include statements:

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2);
#include <EEPROM.h>
#include <avr/wdt.h> // For WatchdogTimer. A sad fix for the occasional
// LCD.INIT() Hanging problem.

I use these same #include statements in half a dozen currently-running projects, with the same "wake up the LCD" code. None of those has ever failed. I tried another LCD unit, but the same thing happens. How can I figure this out? I don't know how to debug a library, and I'm not extremely good with the C language.

Post complete schematics of your setup! Links to the used hardware may help too.

I guess an unstable I2C bus in the hardware. If you switch the LCD by a relay the I2C pullups must not be on the LCD board!

Most probably this isn't a software problem, although we may find a software workaround if we know exactly what hardware you're using.

Using the autoformat function, Ctrl + T, in the IDE, before copying and the code tags, </>, when pasting gives a much more readable presentation here.

Pylon,
Your statement about an unstable I2C bus caused me to rethink my choice of microprocessor. The one I'm using had been used successfully for 2 years as the controller for our solar water heating system on the house. No problems with that, but enhanced code required a Mega. So I used the "used" Uno for the hutch light dimmer controller. I switched that one out for a brand new, never-out-of-the-package Uno, and after about 15 trips into and out of the lcd.init() command, no problems. Apparently it was the Uno causing the problem.
Thanks for nudging me into swapping the UNOs!

Railroader,
I always use Ctrl + T. The problem was that I put the code from the IDE into MS Word since I was taking small parts out of the whole sketch, and (as we all know) Word did some stuff to the selections in the background. Sorry. Also, as you pointed out, I failed to use the </> code tags. My bad.

Without any evil thoughts I tell You that snippets are never appreciated. Why?
Know that every helper is a newbie to Your code. Getting to know the system "from above" the entire code is really valuable, sometimes even necessary.
Cutting out pieces is waisted time.

You have been unlucky. I've bought, tested and used some 20 UNOs and everyone was fit for fight.

I doubt that really fixed the problem unfortunately. But I'm happy if it works for you at the moment. I would expect the failures to restart soon if you didn't change anything else in the setup.

Pylon,
Either you're a prophet, or your timing is astounding. Within a few minutes of your last post, the menu started acting funny again... WITH the new Uno. I decided to build a full schematic for you (and I was going to post the ENTIRE sketch) when I noticed that my pullup resistors for the SDA and SCL pins were 47kΩ instead of 4.7kΩ.
I'm reserving my victory celebration for an hour or so, but I suspect that too much pullup resistance would occasionally cause the problem I was experiencing. With the correct resistance, it should work better. Do you agree? (Plus, I'm going to reinstate the old UNO because it's too young to retire!)

The 47kΩ is probably smaller than the internal pullups so this work for very short wires but if the setup is on a breadboard I would expect unstable behavior.

Since I made the change from the 47kOhm value to the 4.7kOhm value, I have had zero errors. I am using a breadboard, and several other i2c projects I've made (that are currently running and have been running for years) also use breadboards, and use 4.7kOhm pullups. Again, never a problem. I simply plucked the pullups I used at first out of the wrong bin in my resistor box and didn't notice the mistake until I started constructing the schematic based on the components' values. Thanks for the response, Pylon!

47 kOhm are clearly too much as a pull-up on the I2C bus, no matter how short the wires are! The problem lies in the fact that the timing runs at the limit with such large pull-up resistances, since capacities have to be reloaded with each switching process. Since I2C works with 'open collector' or 'open drain', this is done with the transition from L to H by means of the PullUP resistors. If these are too large, enough current can no longer flow for this to happen quickly enough. so the first thing to do is to reduce the transmission speed. But at some point there is the end, and there are TimeOut errors because a status arrives too late for this to be recognized. The i2C bus doesn't wait forever for an answer, and there is a lower and an upper limit frequency within which the I2C works. Everything that is now outside of these limits results in a mis-communication. With 47 kOhm you were so hard at the lower limit (or even a little below) that it just worked for a very short time. Since on the breadboard, but also in some of the somewhat wobbly sockets of the Arduino with these jumper cables, the contact resistances AND capacitances are constantly changing, this cannot work. However, even if everything is properly soldered in the shortest possible way, it cannot go well for long if you are so close to the specifications.

Deltaflyer,
I've been doing a bit of reading about this, and from what I've read, you're spot-on. Within limits, the pullup resistance affects speed of transmission. Too much isn't good, and too little isn't good, either. This has been an interesting thread for me. I've learned a lot.
But one thing I've learned stands out over all that has been contributed here by you good folks. That is, when I select resistors, I need to look more carefully at the color of the multiplier band. Had I been more observant, I'd not have had the problem to start with. But I've learned from this experience, and all of your comments, hints, and knowledge sharing, and that's a wonderful benefit for me (and for anyone else who reads this thread). Thanks!

It would be useful to see the full schematic of everything.
In many cases the use of a relay can cause issues, and we see issues quite often of i2c LCDs being affected.
Also, using a relay to yank the power to the LCD and the i2c backpack is concerning to me as depending on how it is done it can backfeed current into parts since the i2c bus can still have voltage on it.
Also there are timing considerations involved that may need to be considered when turning the power back on especially if using a relay as they are relatively slow devices.

I'm curious why you want to power off the LCD.
You can turn off the display and the backlight which does the same thing visually and also lowers power draw.

Can you post a schematic of your setup so we can see how everything is wired up?
And your full sketch code?

--- bill

@bperrybap
With 47kOhm pullups on the I2C bus it is no longer a question of the relay whether the I2C bus communication fails, just a question of how quickly this happens, since 47kOhm pullups are outside of any specifications of the I2C bus! Even a circuit diagram is of no use, it simply CANNOT work.

I believe that the relay and how it is being used is likely causing the problem.

Keep in mind that while there may be external 47k pullups on the i2c bus signals,
most PCF8574 based i2c backpacks have pullups on the backpack PCB.
Some don't but the vast majority do.
And those pullups are usually 4.7k which is plenty adequate to provide stable i2c signals for short wires at the default 100kHz clock rate.

I still think seeing a schematic, a photo of how everything is wired up, and the full sketch would be useful to resolve the issue.

For example, without seeing the code, it is not possible to see if there may be a timing issue in the sketch from attempting to initialize the lcd too soon after the pin was set to engage the relay to turn on the power to the lcd backpack.

Again, using a relay to cut power to the LCD is not a good thing and IMO, is not necessary for this application.
I'm guessing that this was done by simply wiring the relay to interrupt the 5v supply voltage to the i2c backpack and leaving ground and i2c signals still connected.
This is problematic since the i2c signals will still have voltage on them from the internal pullups from the AVR i2c pins and the external 47k pullups.
While not much current will come from that, it is never a good thing to put voltage on a chips i/o pins when it is not powered.
Also, if there are pullups on the i2c backpack, the voltage on the i2c signals will backfeed through the pullups over to the backpack vcc and provide a small amount of power to the LCD.
It may also back feed power into the LCD pins as well from the other PCF8574 pins.

IMO, I would drop the relay and use the library API functions to turn off the display & pixels and the backlight for the same effect.

I would also switch to the hd44780 library since the LiquidCrystal_I2C library is no longer maintained.
The hd44780 has some additional capabilities and is also quite a bit faster that LiquidCrystal_I2C which frees up some CPU to do other things.

--- bill