Lcd.print question

Hi, everyone!

Working on a project and while it is working, I think I could make it better. I'll put in some fake code to help explain what is happening. Remember, this fake code is only for use as an example. And yes, the syntax is not correct here, being only used as an example. Here goes!

On my 20x4 LCD, I want to print to 0,0 and do so with:
set.cursor (0,0)
lcd.print" Generator is starting"

Now, a minute later, external sensor trips.

And now....
set.cursor (0,0)
lcd.print "over speed."

What happens in the real world is this:

"over speedis starting"

The line is not being cleared of the old text.

My solution has been to do this:

set.cursor(0,0)
lcd.print "overspeed (spaces here) "

and fill the trailing text with spaces. This erases the old text while inserting the new text.

Another issue is, once the generator has started, the text printed to the lcd needs to go.
So, once again I use:

set.cursor(0,0)
lcd.print " 20 spaces "

I print 20 characters of spaces to remove the text from the lcd.
And of course if I print to a different line,:

set.cursor(0,3)
lcd.print "Attention kmart shoppers."

I have to add a line or two to clear the text on the lcd at 0,3 because I want to get rid of that text.

There has to be a better way of doing this! I have used lcd.clear() and while that works, it caused the display to blink/flicker as the code loops through the sketch.

I'm open for comments and ideas, and I'm all ears...

There is no better way than something like you have done. Either put trailing spaces on text to ensure that previous messages are overwritten or write a fixed number of spaces at the required cursor position before printing the new text at the same position

As you have discovered, lcd.clear(), whilst it works, can cause the display to flicker unacceptably. One way to avoid this is to only clear() the screen when the data changes

Thanks.... I'm surprised I was able to come up with something that works, and is generally accepted as a fix.

I put a clear() statement within a IF statement and while it worked, the screen flickered way too much to be usable.

You menioned 'write a fixed number of spaces at the required cursor position.'

How is hat done?

snprintf() in a buffer before sending the info to the screen would let you format the line in a fixed way (mind floating point variables on small AVRs, printf does not support that)

lcd.setCursor(0, 0);
lcd.print("               ");   //as many spaces as needed
lcd.setCursor(0, 0);
lcd.print("new text");

It looks clumsy, but you can put the code in a function and call it with the parameters needed to position the cursor and the text or data to be printed. This would avoid having the same code in multiple places in the sketch

Do you want the leading space? Including the leading space there's 22 characters between the quotes.

That's 21 characters. Maybe you could drop the "is", and associated spaces from both.

I wrote a small example to show what I meant

the screen will show a couple random numbers and millis padded with 0 changing within a fixed width field.

the format string that describes how the line looks like is the printf() format as documented

click to see the code
/* ============================================
  code is placed under the MIT license
  Copyright (c) 2025 J-M-L
  For the Arduino Forum : https://forum.arduino.cc/u/j-m-l

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.
  ===============================================
*/


#include <Wire.h>
#include <hd44780.h>                        // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h>  // i2c expander i/o class header
const uint8_t nbCols = 20;
const uint8_t nbRows = 4;
hd44780_I2Cexp lcd;


void lcdPrintf(uint8_t x, uint8_t y, const char *format, ...) {
  char localBuffer[nbCols + 1]; // Buffer for formatted string (+1 for null terminator)
  va_list args;
  va_start(args, format);
  vsnprintf(localBuffer, sizeof localBuffer, format, args);
  va_end(args);
  lcd.setCursor(x, y);
  lcd.print(localBuffer);
}


void setup() {
  int result = lcd.begin(nbCols, nbRows);
  if (result) {
    Serial.print("LCD initialization failed: ");
    Serial.println(result);
    hd44780::fatalError(result);
  }
  lcd.clear();
}

void loop() {
  lcdPrintf(0, 0, "%4ld - %3ld - %07lu", random(10000), random(1000), millis());
  delay(500);
}

UKHeliBob,

Bare with me here, I'm a 70+ and trying to learn new tricks.

So, let's call this 'lcdfix."

Would I put in the main loop? Or where?

Then to call it, I would say 'lcdfix.'
Like this?

Loop()

do this code
Do that code
when I want to run lcdfix code**
lcdfix

do more code
do a bit more code

Is that correct?

Back in my Applesoft days, I'd say to gosub 5000, do the code, and return. Can't do that here.

That was only an example of fake code to demonstrate the problem of a fake sketch.\

1 Like

nope :slight_smile:

you would do

void overwriteLine(byte linePos, const char * newtText) {
  lcd.setCursor(0, linePos);
  lcd.print("               ");   //as many spaces as needed
  lcd.setCursor(0, linePos);
  lcd.print(newtText);
}

and you would call that with something that looks like that

overwriteLine(2, "Hello");

I gave you an example above that brings richer formatting if you want to have variables displayed in fixed width fields. Just make sure that the format you pass will always overwrite the line thanks to the padding.

Hey, thanks!
I'll give that a try.

Right now, my code is filled with:

lcd.print" lots of spaces" to erase the old text.

then when I add some feature, I have to go running around to find the 'lots of spaces' that keeps overwriting the new stuff I want to display.

As you see, you can, sort of, only better.

Be impressed, not surprised!

Nice. Slightly more compelling when you drop the leading zero in %07ul.

We'll bear with you for now, baring with you, we have to know you a little better. :expressionless:

a7

You write a function like this outside of any other function in the sketch

void lcdFix(char* text)
{
    lcd.setCursor(0, 0);
    lcd.print("            ");  //erase previous text
    lcd.setCursor(0, 0);
    lcd.print(text);
}

Then call it like this whenever you need to clear previous text on row 0 and print new text

lcdFix("some text");  //erase text on row 0 and print new text

You can make it more general purpose by passing the row and column values to the function

Call it like this

lcdFix("something", 0, 1);  //erase text on row 1 and print new text
void lcdFix(char* text, byte row, byte col)
{
    lcd.setCursor(col, row));
    lcd.print("            ");
    lcd.setCursor(col, row);
    lcd.print(text);
}

You could also pass the number of spaces to be printed if you want to but let's keep it simple for now

That was to show you can pad with spaces or 0s


LOL great catch and answer

Thanks to auto correct!!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.