LCD menu flicker

groundfungus:
Instead of trying to keep track of where I need spaces I have a function that I call before writing.

void lcdClearLine( byte line) {
lcd.setCursor(0,line);
lcd.print(" "); //number of spaces as chars wide
lcd.setCursor(0,line);
}

I call this then print my stuff.

While that will clear the line and ensure that the display line starts clean,
it will not eliminate the flicker.
The end result of that method will still produce visible flicker.
Again, the flicker is caused by the eye seeing characters being erased (replaced by )
and then being replaced/restored.
When the interface is not particularly fast, as in the case of i2c,
the timing for erasing the characters, and replacing them is longer
and so the "flicker" is even more obvious.

The flicker using that clear line method would be noticeable even if exactly the same characters
were being re-written.

The only way to eliminate the flicker is as I described above:
never use lcd.clear() (or write spaces - which is the same thing - only sometimes can be slightly faster/better)
and then ensure that your updates overwrite
the old data so as not to leave "trash" from previous updates.

Pedro147:
But as you all suggested if I take clear out from other areas of the code I get text printing where I do not want it. All your help has certainly helped me to understand LCD’s a little more.

It isn't so much LCD's but how the eye and human brain perceive the updates.
It is the of timing sequence of events not a speed or rate of updates.
Imagine s-l-o-w-i-n-g everything down.
It is good exercise for visualizing the updates.
Imaging you are updating the LCD with exactly what is already being displayed.
And also imagine that there is a huge delay between the update of each character.
(imagine 1 second)
As you clear the screen, you would see a character disappear each second.
At the end of 16 seconds (32 if you clear the full display) all the characters have
been replaced with .
Now update the display, again, a character shows up each second and at the end
of up to 32 seconds you have updated the full display back to what was previously there.
With this process there are lots of seconds where the display is incomplete.

Now change that to a process that simply overwrites the display with the new information.
If the information is the same as the previous information, you will see no changes during
the update process. Yes it may still take 16-32 seconds to update the full display
but there is never a time when characters are missing.

That is what is actually happening in real time.
The "flicker" you see is because the characters are being erased and then be replaced.
The time between them being gone and being replace is what you are perceiving as
"flicker". Since ic2 is not particularly fast, the time that characters are erased
is longer and so the perceived flicker is worse than on faster interfaces.

My recommendation is to eliminate lcd.clear() completely if you want to get rid of flicker.
If you can afford the 2k of code space, I'd recommend taking a look at using sprintf()
to create your output strings and then slam out full lines which will overwrite the previous data cleanly.

It is much easier to get your print formatting aligned and consistent when using sprintf()
vs the wimpy Arduino print() routines directly.

You could even define a common format for line1 and line2 and then call a routine
to build the buffer for printing.
Like you pass in "on"/"off" and the time values and then the formatting routine takes
the values and formats up full line buffer.

Here is a sample sprintf format string example:

char linebuf[17]; // extra character for null terminator.
sprintf(linebuf, "On%02d%02dhNow:%02d%02dh", , alarmh, alarmm, hour, minute);
lcd.print(linebuf);

or

// format routine
formatl1(char *buf, char*s1, int ah, int am, char *s2, int h, int m)
{
    sprintf(buf, "%2s%02d%02dh%4s%02d%02dh", s1, ah, am, s2, h, m);
}

char linebuf[17]; // declare buffer somewhere in code

// call formatting routine and use it
    formatl1(linebuf, "on", alarmh, alarmm, "Now:", hour, minute);
    lcd.print(linebuf);

etc...

--- bill