initializing LCD library within setup() ?

The reason I'm asking this is that sometimes I need to recycle power on just the LCD module because it gets a glitch and garbles. I've tried adding robustness to its power source, cutting down on noise issues, etc .. (and will continue on that front) but in the meantime I need to hard boot the LCD without resetting the Arduino.

The way the LCD library works is that initialization of the module happens before setup(); I need to re-initialize the LCD module, by cycling its power (using a digital pin), from inside setup() or perhaps even loop();

So, instead of this:

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
// RS, E, D4, D5, D6, D7
LiquidCrystal lcd(53, 51, 41, 37, 39, 35);

setup() {
 // stuff...
 lcd.begin(24, 2);
 lcd.print("  Hello ");
}

loop() {
 // stuff..
 lcd.print (" Looping ");
}

I need to "prolong" initializing of LCD hardware, and re-use it. I'd like to do something like this:

// include the library code:
#include <LiquidCrystal.h>

setup() {
 // stuff...

 digitalWrite (LCDpower, HIGH);
 delay(2000);
 LiquidCrystal lcd(53, 51, 41, 37, 39, 35);  

 lcd.begin(24, 2);
 lcd.print("  Hello ");
}

loop() {
 // stuff..
 lcd.print (millis());
}

But when I try this, I get compiler scope issues with lcd.print in the loop().

Is there a way to declare the lcd commands in loop() as "extern" or something?

Thanks!

I don't have the library/code in front of me (and I haven't used the library either), so I am just speculating here...

Doesn't the constructor just do pin assignments; it isn't until the lcd.begin() call that anything happens (turn on of the LCD)?

Could you do this:

// include the library code:
#include <LiquidCrystal.h>

LiquidCrystal lcd(53, 51, 41, 37, 39, 35);

setup() {
 // stuff...
 digitalWrite (LCDpower, HIGH);
 delay(2000);

 lcd.begin(24, 2);
 lcd.print("  Hello ");
}

loop() {
 // stuff..
 lcd.print (millis());
}

???

If I had the code to the library in front of me, I could see what the constructor and begin() method does...

[edit]Found it:

http://code.google.com/p/arduino/source/browse/trunk/libraries/LiquidCrystal/LiquidCrystal.cpp

Looking at this, it seems to raise the enable pin high...? So what I wrote wouldn't work. Maybe in some manner with the library (maybe with a second call to init()?) disable the LCD, then re-enable it...? Again, this is just speculation...
[/edit]

It's this line that executes (initializes the LCD to 4bit):

LiquidCrystal lcd(53, 51, 41, 37, 39, 35);

And it happens before setup().

I WISH lcd.begin() was the first thing that talked to the LCD.
You'd think that would be a more normal way to go.... alas, it's not.

Although this code compiles:

// include the library code:
#include <LiquidCrystal.h>

setup() {
 // stuff...

 LiquidCrystal lcd(53, 51, 41, 37, 39, 35);

 lcd.begin(24, 2);
 lcd.print("  Hello ");
}

loop() {
}

I'm not really sure if the LiquidCrystal lcd(53, 51, 41, 37, 39, 35) is actually inserted in that spot, inline with the code, or if it inserts before setup().

The real problem is one of scope. If I put LiquidCrystal lcd(53, 51, 41, 37, 39, 35) in the body of loop() I speculate I can use lcd commands from inside loop() too! But when I call a function and it uses lcd commands, the compiler will again complain about scope.

I think the real fix here is to make lcd.begin() be the thing that does the initialization, not LiquidCrystal lcd(53, 51, 41, 37, 39, 35);

This way, we leave the global declaration of the liquidCrystal and just use lcd.begin() again in whatever routine feels like it needs to re-initialize the LCD.

So, I guess I'm looking for a workaround until this can be fixed, something that will trick the scope gods in the compiler. Or expose an access point into the LiquidCrystal lcd(53, 51, 41, 37, 39, 35) routine so I can call it from wherever it resides, and return from it.

I don't want to have to write my own init routine, that wheel has been invented already in the library, I just want to use it more than once per boot cycle of the Arduino!

But what if you put it (the constructor call) outside the setup (like you had originally), then inside setup() call lcd.init() to disable (with the pins set like the constructor calls things - look in the .cpp source file I linked to see how it is doing this) the LCD, toggle your power, then call lcd.init() again to re-enable the LCD...?

That way you could keep the lcd variable global in scope so it could be used in setup() and loop()...

Does this make sense? I am not even sure it would work, but it could be a direction to experiment in...

:slight_smile:

[edit]I took another look at the .cpp file - it appears that all my speculation above is for nought; none of what I wrote above will likely work. I still think there is a way to do this, though (I am just being stubborn, I guess)!

;D[/edit]

I like stubborn. I also like the idea of try in both places.

Maybe the trick is to "over-declare" the lcd stuff... like this.
This code compiles, but I wonder if it works "as expected" (not near my project to try it out now).

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
// RS, E, D4, D5, D6, D7
LiquidCrystal lcd(53, 51, 41, 37, 39, 35);

void reinitializeLCD() {
  LiquidCrystal lcd(53, 51, 41, 37, 39, 35);
  lcd.begin(24, 2);
  lcd.setCursor(0, 0);
  lcd.print("reinitialized");
}
  
void padprint ( int num) {
  lcd.print(" ");
  lcd.print(num);
  lcd.print(" ");
}

void setup() {
   // set up the LCD's number of columns and rows: 
  lcd.begin(24, 2);
  lcd.setCursor(0, 0);
  lcd.print("Hello voild");
  padprint(200);
}

void loop() {
  delay(4000);
  reinitializeLCD(); 
  lcd.print(millis());
}

If that actually works, I'm sad that I had to "work the system" to make it happen... . But I'd still be happy if this will allow normal lcd prints and I can re-boot the LCD without having to bring the Arduino down to do it.

That might just work...

Hmm - what is the "nature" of the glitch anyhow, that is causing you to need to reset things? I understand that you had noise and stuff you are combatting, but have you seen this glitch on a scope or analyser that you could tell us more about?

This "hack" could work in the meantime (and might be useful to keep no matter what if it works), but I am wondering if we could figure out what the real cause is...

LiquidCrystal lcd(53, 51, 41, 37, 39, 35);

void reinitializeLCD() {
  LiquidCrystal lcd(53, 51, 41, 37, 39, 35);

With this code, you have a global variable named lcd that was created by the LiquidCrystal constructor.

You also have a local variable named lcd that was created by the LiquidCrystal constructor.

They are not the same variable, and are not interchangeable.

Whether creating a local variable performs some hardware initialization or not, I don't know. Since there is only one piece of hardware, if there is any hardware initialization going on, it is going to affect that piece of hardware.

cr0sh is right, though. You need to fix the real problem, not mask it this way.

The real problem is I have a long unshielded ribbon cable connection between Arduino board and LCD module in an automotive environment. The LCD module was REALLY flaky until I added some cap's on the LCD end of that ribbon. And using PWM to control its 12V sourced LED backlight driven at 150mA also made for some nice inductive coupling with the data lines in the same ribbon, causing jitters that showed up regularly as double printing of some characters on the LCD.. I could change "brightness" (duty cycle) and drive out the problem more dramatically, or scale it back. Near full dim, or full brightness the problem is less severe. Anything that is near square wave could make it go wonkers much more predictably. So I changed out the LED resistors for ones more friendly with 5V and send 5V up the line instead of 12V, still using PWM near those data lines but much better now. Every once in a while it seems a glitch on the power line hits the LCD hard and it goes into goo-goo land (splatter all over the screen and subsequent prints show in alien patterns).

Yes, rebooting the LCD is software patch that will get me by until I make and prove out a better connection between the two.

Things I need to do in the hardware area of the problem:

  • make a low pass filter by adding a resistor, not just add caps at the LCD, maybe a couple hundred Ohms or so current limiting resistor in series with the power line going to LCD.

  • get a better cable that shields the data lines from the LCD backlight power running up the same cable, and the environment.

It's interesting to note that the Arduino Mega board (providing my power for all LCD needs) keeps on running fine through all these events, so if there's a glitch on the Vcc 5 on the board, it's hitting the ATmega just the same but it survives. ... so I'm pretty sure the problem is introduced between the Arduino and the LCD by virtue of that cable and the environment.

The concept of having an ability to reboot or control LCD power, and regenerate its display without having to reboot Arduino should not be foreign. Somewhere in here is bad software modularity / design in the library.

Whether creating a local variable performs some hardware initialization or not, I don't know. Since there is only one piece of hardware, if there is any hardware initialization going on, it is going to affect that piece of hardware.

Yes, the creation of the variable is what sends an initialization string to the LCD.

I'm counting on the fact it's the same hardware and that it doesn't care which instance of a variable caused it to initialize... It just gets told stuff.

Like I said, this is working around some things, one is compiler scope, and the other is a questionable practice of having a variable declaration "side effect" of running code.

so I'm pretty sure the problem is introduced between the Arduino and the LCD by virtue of that cable and the environment.

Take the time to fix this, then - you're going to have to do so anyhow, it might as well be now.

My suggestion: flexible metal conduit. You might also look into woven metal braid tubing, which is used to sheild hoses in an automobile from heat. With either solution, ground both ends to the frame of the vehicle.

You already mentioned you did noise reduction things - what were those things?

This can be considered heresy...

But why not make a copy of the library, move the code from within the constructor to the start of the begin method, and giving begin the constructor parameters aswell?...
This would leave you with a empty constructor, meaning that no communication will occur untill begin is called.
Its a simple copy-paste operation.. though it sounds like the init messages being sent before setup aren't your problem.

But why not make a copy of the library, move the code from within the constructor to the start of the begin method, and giving begin the constructor parameters as well?

That's what I'd do. With one addition: I'd contact the author and ask that they incorporate the changes.

The real problem is I have a long unshielded ribbon cable connection between Arduino board and LCD module in an automotive environment.

You should consider using one of the serial LCD modules.

Don

To close this thread, I just found out from another friendly forum member that lcd.begin() also initializes the LCD. And I just tried it, no scope issues, etc... Push a button and my garbled screen comes back to life the way it should. Yeeaahhh!!

Thanks all

So, pardon me if this seems a dumb question, but why can't you just choose when to initialize the object whenever you like? I see nothing special about the library that would prevent you from first declaring a global variable of the type you specify, and then later initializing it as you see fit...

#include <LiquidCrystal.h>

  // declare an un-initialized global variable
LiquidCrystal lcd;

void setup() 
{

    // call the constructor, initialize the variable...
  lcd = LiquidCrystal(53, 51, 41, 37, 39, 35);

}

Perhaps the problem here is that the "easy way" shown to you in the docs has led you to believe it's somehow different than any other object.

!c