LCD Printing changing values (single and double digits)

I'm brand new to the Arduino world, so I jumped right in and started making something probably above my skill set. I think I exhausted my googling skills to find an answer or I'm just really bad at it, but I think it has to do with "padding" my value so it overwrites the previous value, but I'm just not sure.

Situation:
Analog reading FSR sensors to integer values.
Printing them to a LCD 1602

Issue:
Unless I use "lcd.clear()" at the end of my loop, my double-digit values will overlap the single-digit values with an extra number at the end. I just noticed how noticeable the clearing was, that I thought maybe there was a better way?

Also, my literacy for coding is really low, so feel free to tell me the right way to do things.

  //LCD print
  lcd.setCursor(0,0);
  lcd.print(array1);
  lcd.setCursor(0,1);
  lcd.print(FSR1val);

  lcd.setCursor(6,0);
  lcd.print(array2);
  lcd.setCursor(6,1);
  lcd.print(FSR2val);

  lcd.setCursor(12,0);
  lcd.print(array3);
  lcd.setCursor(12,1);
  lcd.print(potVal);

  //reset 
  delay(timer);
  **lcd.clear();  THIS WORKS, BUT NOT SURE IF ITS CORRECT**

How do you know how many digits are printed for each variable?
If in doubt then fill each output field with spaces before printing a value to it.

Use it at the begin of the loop to get virgin output fields for all values.

Thanks for the advice to move the "lcd.clear()" to the front.

As for how many digits, I forgot to mention that I used "map()" to give me numbers from 0 to 100. I included the full loop below to help understand, I wasn't sure if that was too much info. I'm trying to learn BT communication as well with App Inventor, another project to learn.

I used 900 instead of 1024 because that's where the FSRs were maxing out at. The picture below shows FSR2 at "02" when it should be "0", this is because the value exceeded 10 and then came back down and I didn't use "lcd.clear()"

void loop() {
  //read sensors
  FSR1val = analogRead(FSR1);
  FSR1val = map(FSR1val, 0, 900, 0, 100);
  FSR2val = analogRead(FSR2);
  FSR2val = map(FSR2val, 0, 900, 0, 100);
  potVal = analogRead(POT);
  
  //send via BT
  BTserial.print(FSR1val);
  BTserial.print(";");
  BTserial.print(FSR2val);
  BTserial.println(";");

  //serial print
  Serial.print("Pot reading = ");
  Serial.println(potVal);

  //LCD print
  lcd.clear();  THIS WORKS, BUT NOT SURE IF ITS CORRECT

  lcd.setCursor(0,0);
  lcd.print(array1);
  lcd.setCursor(0,1);
  lcd.print(FSR1val);

  lcd.setCursor(6,0);
  lcd.print(array2);
  lcd.setCursor(6,1);
  lcd.print(FSR2val);

  lcd.setCursor(12,0);
  lcd.print(array3);
  lcd.setCursor(12,1);
  lcd.print(potVal);

  //reset 
  delay(timer);
}

Using lcd.clear( ) is not the best way to go. It is a slow command, and often leads to flickering of the display. There is very little reason to ever use that command.

Use cursor management, and printing of spaces to clear the old data before repositioning the cursor and printing the new data. It is significantly faster than using lcd.clear( ) and printing the data. You may also only want to print data only when a value has changed.

The unchanging words of the display("FSR1:" "FSR2:" "Pot:") should be printed in setup. Printing them repeatedly in loop also slows the code down. In your simple application it may not matter, but you should learn best practices.

1 Like

Thanks! Learned a ton there and it was so simple!
The below worked out perfectly after I moved the titles to the setup()

  //LCD print
  lcd.setCursor(0,1);
  lcd.print("    ");
  lcd.setCursor(0,1);
  lcd.print(FSR1val);

  lcd.setCursor(6,1);
  lcd.print("    ");
  lcd.setCursor(6,1);
  lcd.print(FSR2val);

  lcd.setCursor(12,1);
  lcd.print("    ");
  lcd.setCursor(12,1);
  lcd.print(potVal);
//LCD print
  char buffer[17];
  sprintf(buffer, "%4d  %4d  %4d", FSR1val, FSR2val, potVal); 
  lcd.setCursor(0,1);
  lcd.print(buffer);
2 Likes

That worked too and is really efficient!
Did some googling to learn about sprintf(), and learned something new again.

I think I understand how it works, but still a little confused about the char length of 17, is that just 16 columns plus 1 for the string termination character?

Then when it gets lcd.print(), how does it decide the spacing between values? I'm guessing that has something to do with the "4" used because I didn't see that explained in my googling.

Also, when declaring the "char buffer[17]", does it have to be in the loop or can it be defined earlier? I'm still fuzzy on the appropriate times to declare things, before setup(), during setup(), during the loop(), etc...

Thanks!

1 Like

Yes.

It doesn't. There are spaces in the format string. It's printing those. This does mean printing 4 extra characters (spaces) that never change, but it's probably as quick or quicker than sending commands to move the cursor.

The "4" is the field width for the value to be printed. If the value needs less than 4 characters, it will be padded with extra spaces on the left to make it at least 4 characters.

It can be either. If you make it global by declaring it outside any function, you can re-use it anywhere you need to.

1 Like

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