Program help LCD 16x2

Hi

I am kinda new on this but i work my way on with building a real interessting project. I am having some issues with making the program functions correct and I hope to get some answers here.

Hardware: Arduino UNO & LCD screen 16x2 (which comes with the starter kit).

I am using a potentiometer on an analog input. The value of the input is stored in a variable and then mapped to show the value from 0 to 54000. I have succeeded in making the display print the correct value using the “long” command.

On the same row after the value that is printed the display will print “RPM”. The RPM print is fixed to character (6,1) to make room for the potentiometer value.

The Problem!
When the value reaches above 10000 and the potentiometer is turned to a lower value going under 10000 the last zero is still there on the display.

Is there any code that makes a specific value to always print with the exact amount of characters?

I have no problem with the display showing 00100 instead of 100 but the perfect goal was to have the display clear any character that isn´t actually printed in realtime.

Please help me!?

This is the code:

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int potInput = A0; //Potentiometer input
int potValue; //Stores pot value
int rpmValue; //Stores the value from scale 0-540
long trueRpm; //Converts the value to scale 0-54000

void setup(){
  lcd.begin(16,2);
  lcd.setCursor(0,0);
}

void loop(){
  potValue = analogRead(potInput);
  rpmValue = map(potValue, 0, 1023, 0, 540);
  trueRpm = map(rpmValue, 0,540,0,54000);
  lcd.setCursor(0,0);
  lcd.print("Speed :");
  lcd.setCursor(6,1);
  lcd.print("RPM");
  lcd.setCursor(0,1);
  lcd.print(trueRpm);
}

i'm not good at this but i just wanted to help.. why don't you try to put lcd.clear() inside the loop before printing the value of the Pot.. i'm not sure if it will work.. hehe..

void loop(){
  potValue = analogRead(potInput);
  rpmValue = map(potValue, 0, 1023, 0, 540);
  trueRpm = map(rpmValue, 0,540,0,54000);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Speed :");
  lcd.setCursor(6,1);
  lcd.print("RPM");
  lcd.setCursor(0,1);
  lcd.print(trueRpm);
  delay(50);
}

With a number that big, this is a long way from handling a leading blank in a digital clock and I think the simplest way is to print "Speed RPM" on the top line, and do it in the setup, thereby only having to print it once. The lower line has the rpm figure followed by " " thereby clearing any junk from the previous reading. There are more sophisticated ways of doing this, with case dependent on variable length, but I doubt they are worth the effort.

I don't think clearing the LCD every loop cycle is a good idea at all, particularly one this short. It will probably drive you crazy, and is likely to make a significant change to the time of the cycle.

The problem is that you print 10000 which is 5 characters and then if you print 9999 it's only four so you don't print over the last one. The trick is to either clear the whole display each time you update or to print some extra spaces after or before your number. How many is a matter of simple math. If there's nothing behind it on the display, then you can possibly just print a few spaces after each number. It all depends on what else is on that display. But at all times you have to not only think about what you want to print but also what is already on the display.

Thanks for all of the suggestions! They realy got me thinking and I actually found a way of solving this problem.

I added some “if” statements and set up a few rules regarding the actuall value from the potentiometer which prints one or more blankspaces after moving the cursor to the right postition.

Works perfect now! Thanks everyone and I hope this can be of help to others as well.

void loop(){
  potValue = analogRead(potInput);
  rpmValue = map(potValue, 0, 1023, 0, 540);
  trueRpm = map(rpmValue, 0,540,0,54000);
  lcd.setCursor(0,0);
  lcd.print("Speed :");
  lcd.setCursor(6,1);
  lcd.print("RPM");
  lcd.setCursor(0,1);
  lcd.print(trueRpm);
    if (trueRpm < 10){
      lcd.setCursor(1,1);
      lcd.print("    "); //inserts 4 blankspaces
    }
    if (trueRpm < 100){
      lcd.setCursor(2,1);
      lcd.print("   "); //inserts 3 blankspaces
    }
    if (trueRpm < 1000){
      lcd.setCursor(3,1);
      lcd.print("  "); //inserts 2 blankspaces
    }
    if (trueRpm < 10000){
      lcd.setCursor(4,1);
      lcd.print(" "); //inserts 1 blankspace
    }
}

I didn’t think it was worth the effort! But it’s neat enough…
I submit you should still consider printing “speed” and “RPM” once, particularly now that you have right justification.

You can make your code slightly more efficient using a cascading if statement block. That is, if the first if test is true, why continue to test for the other values? Also, your code uses more memory for the spaces than it needs to. Something along these lines in loop() might help (untested):

 int col;
 int pad;
 char spaces[] = "     ";	// 5 spaces, may need room for null

 lcd.print(trueRpm);
    if (trueRpm < 10){
	  pad = 4;
	  col = 1;
   } else {
    if (trueRpm < 100){
	  pad = 3;
	  col = 2;
    } else {
    if (trueRpm < 1000){
	  pad = 2;
	  col = 3;
   } else {
	  pad = 1;
	  col = 4;
   }
   lcd.setCursor(col,1);
   spaces[pad] = '\0';		// Make a new string
   lcd.print(spaces);

Since the code is in loop(), the spaces[] array is reset on each pass, so you start with a fresh set of spaces and the previous null is overwritten.

Or you could imply use "sprintf"

econjack:
You can make your code slightly more efficient using a cascading if statement block.

I was wondering if the "case" method was neater.......

@AWOL: I'm not a big fan of sprintf(). My experience is that, unless you make a lot of calls to sprintf() in your program, it can bloat the code size quite a bit.

@Nick: I always prefer a switch/case statement block to a cascading if statement block. In this instance, however, setting up the switch value would likely take more code than the if would. (I haven't tested it...just a gut feeling.)

The most obvious way to get your RPM to print the way you want is to use sprintf:

char s[6];
sprintf(s, "%5d", rpm);
lcd.setCursor(1, 0);
lcd.print(s);

It will ALWAYS be exactly 5 characters long, with leading zeroes replaced with spaces.

Alternatively:

lcd.setCursor(1, 0);
lcd.print(" ");
lcd.setCursor(1, 0);
lcd.print(rpm);

Though this will have the RPM value left-justified in the field, so it will move right as more digits are needed to display the value, which is visually unappealing.

Regards,
Ray L.

I just ran Ray's sprintf() version, but just using the Serial object and one value for the RPMs. The sprintf() version used 3662 bytes. Using the cascading if block I mentioned earlier the code size is 2574 bytes. The reader has to decide if the 1K savings is worth it or not.

Just for the sake of variety. Here’s yet another method.

void loop(){
  potValue = analogRead(potInput);
  rpmValue = map(potValue, 0, 1023, 0, 540);
  trueRpm = map(rpmValue, 0,540,0,54000);
  lcd.setCursor(0,0);
  lcd.print("Speed :");
  lcd.setCursor(6,1);
  lcd.print("RPM");
  lcd.setCursor(0,1);
  lcd.print(trueRpm);
  while(trueRpm < 10000)
    {
     lcd.print(" ");
     trueRpm *= 10;
    }
}