LCD 16x2 + sensor = problem at indicating distance

I'm currently working at a project which involves 2 ultrasonic sensors and one lcd.

However i have encounter a problem.

the system works like this.

I have 2 sensors. One of them is indicating distance on a horizontal position and the other on a vertical position. So my lcd shows the followint measurements:

1: Distance cm:100 row 1 only for distance
2: Height cm:100 row 2 only for height

I've implemented some errors and mesages within the code so it shows out of range stuff... After ever out o range message i used a lcd.clear() command.

This works well if i want to refresh the entire lcd. But sometimes I don't... like in the next case...

For instance if it measeures 9cm (or one digit value) and it rewriting anther one digit value it's ok
If i measure 25cm and the next value is 7, it shows 75.

So if the distance decreases, the las digit won't dissapear.

In this case I either want for that las digit to disappear if it measures from 3 digits to 2,
or refresh only that line, or show more decimals after the number (ex: 9.23 or event 9.00)

Here is the code:

// Start distance measurement for ground
  long duration2, distance2;
  digitalWrite(trig2Pin, LOW);
  delayMicroseconds(2);
  digitalWrite(trig2Pin, HIGH);
  delayMicroseconds(0.50);
  digitalWrite(trig2Pin, LOW);
  duration2 = pulseIn(echo2Pin, HIGH);
  distance2 = ((duration2 / 2) / 28.7);// * 10;
  if (distance2 < 10) {
    digitalWrite(laserPin, LOW);
    lcd.setCursor(0, 1);
    lcd.print(" LASER INACTIVE ");
    delay(700);
    lcd.clear();

  }    else    {
    lcd.setCursor(0, 1);
    lcd.print("Height   cm:");
    lcd.setCursor(12, 1);
    lcd.print(distance2);
    delay(700);

  }
}

Any suggestions?

I don't think i can.

That's because I've alocated the las 4 digits of a row to measurement values.

so it lookx like this:

XXXXXXXXXXXX1234

let's say we make a measurement:

XXXXXXXXXXXX12XX = 12cm
XXXXXXXXXXXX100X = 100cm
XXXXXXXXXXXX120X = 12cm again!

So that's th part of the variable value that changes from 4 to 2 or 1 to 3 digits.

If there is no other way... i'll just use the float :frowning:

I don't think you are writing 4 digits. You always have to be sure that you write the correct amount of characters to mantain the position.

Here some code I wrote to do that in my RF Power meter. In my program the numbers can change a lot in character length. So every time I write somthing I keep track of how many charcters are written and I use a function to specify the exact amount of characters a number has to occupy.

/*

  • Display the maximum power
    */
    void displayMaxPower ()
    {
    lcd.home();
    if (power_notconnected)
    {
    lcd.print("Maximum power: ");
    lcd.setCursor(0, 1); // goto next line
    lcd.print("INPUT TOO LOW/NC");
    }
    else
    {
    lcd.print("Maximum power: ");
    lcd.setCursor(0, 1); // goto next line
    byte chars = printFormattedNumber(max_dbm + currentAttenuation(), 1, 1, true, true);
    chars += lcd.print("dBm ");
    chars += printPowerWatts(convertDbmToMilliWatt(max_dbm + currentAttenuation()));
    filloutLine(chars);
    }
    }

/*

  • Print power in uW, mW or W.
    */
    byte printPowerWatts(float mw)
    {
    byte chars = 0;
    if (mw < 1.0) // If less then 1mW diaplay in uW
    {
    chars = printFormattedNumber(mw * 1000.0, 1, 0, false, false);
    chars += lcd.print("uW");
    }
    else if (mw >= 1000.0) // If more than 1000mW display in W
    {
    chars = printFormattedNumber(mw / 1000.0, 1, 1, false, false);
    chars += lcd.print("W");
    }
    else
    {
    chars = printFormattedNumber(mw, 1, 1, false, false);
    chars += lcd.print("mW");
    }
    return chars;
    }

/*

  • Fillout a complete display line with spaces.
    */
    void filloutLine(byte charsWritten)
    {
    for (byte i=0; i < 16 - charsWritten;i++)
    lcd.print(" ");
    }

/*

  • Print a number with a specific amount of digits and decimals on the display.
  • It is also possible to print a space when there is no negative sign.
  • number: Number to display
  • minAmountDigits: The minimum amount of digits to display. If number is shorter then '0's will be printed before the number.
  • amountDecimals: The amount of decimals to display.
  • fillout: If the amount of decimals is shorter then the desired amount, spaces will be used to get the same string length.
    */
    byte printFormattedNumber(float number, byte minAmountDigits, byte amountDecimals, bool reserveMinus, bool fillout)
    {
    byte chars = 0; // Number of chars written.

// If no minus sign, write a space
if (reserveMinus && number >= 0)
chars += lcd.print(" ");
else if (number < 0)
chars += lcd.print("-");

//Print integer part. When current value has less digits then wanted add extra zero's
int digitPart = (int)number;
byte digitCount = getAmountDigits(digitPart);
if (digitCount < minAmountDigits)
{
for (byte i=0; i < minAmountDigits - digitCount; i++)
chars += lcd.print("0");
}
// Display digit part
chars += lcd.print(abs((int)number));
// Display decimal part
if (amountDecimals > 0)
{
chars += lcd.print(".");
chars += lcd.print(getDecimalPart(number, amountDecimals));
}

if (fillout)
{
// Fill missing chars according to desired length
byte totalCharsWanted = minAmountDigits + amountDecimals;
if (reserveMinus)
totalCharsWanted++;
for (byte i=0; i < totalCharsWanted - chars; i++)
chars += lcd.print(" ");
}
return chars; // return the amount of chars written to the display
}

/*

  • Get the decimal part of a number.
  • 123.56 returns 56
    */
    unsigned int getDecimalPart(float number, int amountDecimals)
    {
    if (number < 0)
    number = -number;

float fract = number - floor(number);
return (unsigned int)(fract * pow(10, amountDecimals));

}

/*

  • Get amount of digits of an integer.
  • Simple but fast
    */
    byte getAmountDigits(int n)
    {
    n = abs(n);
    if (n < 10) return 1;
    if (n < 100) return 2;
    if (n < 1000) return 3;
    }

you have to pad the printed value with spaces before the value:

  1cm
 10cm
100cm

look into sprintf() and its associated format specifiers to produce a front padded printable value.

or, do the math in a function and pad it with spaces

Adding leading spaces for formatting. I have done the same for floats. Simple.
I also did a version for negative numbest. Season to taste.

int counter = 0;              // setup for example. Variable to print.

void loop()  {      

lcd.setCursor(12, 0);         // set cursor position
intSpaceLCD(counter);         // pass integer to print, routine adds leading spaces
lcd.print(counter);           // or put print in function. see below

counter=abs(counter*2+1);     // change number to demonstrate different size numbers
delay(500);                 
}

void intSpaceLCD (int aNumber) {

if ((aNumber >=10000) && (aNumber <100000)) { lcd.print(" ");}
if ((aNumber >=1000) && (aNumber <10000))  { lcd.print("  ");}
if ((aNumber >=100) && (aNumber < 1000))  { lcd.print("   ");}
if ((aNumber >=10) && (aNumber < 100))  { lcd.print("    ");}
if ((aNumber >= 0 ) && (aNumber < 10)) { lcd.print("     ");}

// lcd.print(aNumber);         // optional place for print. Prints number passed to function.
}