Print decimals with itoa function on LCD display

Hola a todos, Hello to all, Olá todo mundo, comment ca va,

I am a new member. After looking the FAQ files, and trying a lot, I cannot print decimal numbers on my LCD4bits display, using the itoa function.

Please, see example:

lcd.cursorTo(1, 0); // Prints value of pot on first line
lcd.printIn("Pot=");
lcd.cursorTo(1, 8); //line=1, pos 8.

char v_str[8] = " "; //reserve the string space first
itoa(v, v_str, 6);
lcd.printIn(v_str);

I always obtain integers as results.
The input is a pot, and the assigned value is divided by 3.3 in order to obtain decimal values. :frowning: :frowning:

Any help?

Tks a lot,

Oldbeaver, from Chile.

The i in itoa() implies an integral value being converted to ASCII. You can't use it to convert a floating point value to a string equivalent.

I posted a routine a while back that one can use to convert a double/real to a string, called fmtDouble(). See
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1207226548/11#11

and I just posted code in that thread what can print directly to the LCD.
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1207226548/13#13

note that if you are not using the latest lcd library you need to change print to printIn

Thank you for your help.

Will try this afternoon.

Best,

José de la Maza
:slight_smile:

Hi José, please do report your results (the code should work but I have not had a chance to run it yet)

Have fun!

Dear Mem,

Unfortunately, didn't work for my LCD display.

I am trying to adapt some commands to my GMD1602K LCD display, no success so far.

:-[

Regards,

José

Perhaps if you posted your sketch it will be possible to suggest something that will get it going. If you are still using the old lcd4bit library, why not try the latest code relased with arduino version 0012, Its much better in many ways.

Tks for replying. Of course I will use the new library, if I can get it.

This is my sketch:

#include <LCD4Bit.h>

LCD4Bit lcd = LCD4Bit(2); //2 imprime en 2 lineas

//create object to control an LCD.
void setup()
{
pinMode(1,INPUT);
lcd.init();
lcd.clear();
}

void loop()
{
int delayVal(1000);

float val = 0000.0000 ; //
float z = 0000.0000 ;

do
{
val = analogRead(1); // read pot value
val = val/3.3;
z = z + val; // acumula valores en z

lcd.cursorTo(1, 0); // Imprime valor del pot en 1ra linea
lcd.printIn("Pot=");
lcd.cursorTo(1,8); //line=1, pos 8.

void lcdPrintDouble( double val, byte precision);
{
// prints val on a ver 0012 text lcd with number of decimal places determine by precision
// precision is a number from 0 to 6 indicating the desired decimial places
// example: printDouble( 3.1415, 2); // prints 3.14 (two decimal places)

//if(val < 0.0);
// lcd.printIn('-');
// val = -val;

lcd.printIn (int(val)); //prints the int part
if( precision > 0) {
lcd.printIn("."); // print the decimal point
unsigned long frac;
unsigned long mult = 1;
// byte padding = precision -1;
byte padding = precision - 1;
while(precision--)
mult *=10;

if(val >= 0)
frac = (val - int(val)) * mult;
else
frac = (int(val)- val ) * mult;
unsigned long frac1 = frac;
while( frac1 /= 10 )
padding--;
while( padding--)
lcd.printIn("0");
lcd.printIn(frac,DEC) ;
}
}
//char v_str[8] = " "; //reserve the string space first
// itoa(v, v_str, 10);
// lcd.printIn(v_str);

delay (500);

lcd.cursorTo(2, 0); // Imprime valor acumulado en line=2, x=0.
lcd.printIn("Acum=");
lcd.cursorTo(2,8);
char z_str[8] = " "; //reserve the string space first
itoa(z, z_str, 10);
lcd.printIn(z_str);

digitalWrite(13, LOW); //13 enciende led amarillo por 1/2 segundo
delay (1000);

digitalWrite(13, HIGH);
}
while (v > 0);
}

Feel free to improve it.

Greetings,

Jose

You can use the following update to your sketch to help you get going with the version 0012 liquidcrystal library. You need to ensure the pins in the sketch match your wiring

#include <LiquidCrystal.h>

/* replace the following with your pins !!! */


// LiquidCrystal display with:
// rs on pin 7        (LCD pin 4 ) aka DI
// rw on pin 6        (LCD pin 5)
// enable on pin 5 (LCD pin 6)
// d4, d5, d6, d7 on pins 9, 10, 11, 12  (LCD pins 11-14)

//create object to control an LCD.  
LiquidCrystal lcd(7, 6, 5, 9, 10, 11, 12);

void setup(){
  // you don't need pinmode for analog inputs, yr old code actually sets digital pin 1 as an input -> pinMode(1,INPUT);
}

void loop() {
  float val;  // no nead to initialize, the values are set in the first lines of code
  float z;

  val = analogRead(1);          // read pot value
  val = val/3.3;
  z = z + val;                // acumula valores en z

  lcd.clear();
  // note that the new library has 0,0 as the upper left hand position in x y (column row) order
  lcd.setCursor(0, 0);          // Imprime valor del pot en 1ra linea
  lcd.print("Pot=");
  lcd.setCursor(6,0);       // 6 is the column (starting from 0), 0 is the line starting from 0
  lcdPrintFloat(val,1);  // print val to one decimal place

  delay (500); 

  lcd.setCursor(0,1);      // Imprime valor acumulado en line=2, x=0.
  lcd.print("Acum= ");
  lcd.setCursor(6,1);
  lcdPrintFloat(z,4);  // print z with four decimal places

  digitalWrite(13, LOW);  //13 enciende led amarillo por 1/2 segundo
  delay (2000);
  digitalWrite(13, HIGH);
  if( val <= 0)
    while(true);  // stop displaying values if val goes negative (this replaces the do loop you had)

}

void lcdPrintFloat( float val, byte precision){
  // prints val on a ver 0012 text lcd with number of decimal places determine by precision
  // precision is a number from 0 to 6 indicating the desired decimial places
  // example: lcdPrintFloat( 3.1415, 2); // prints 3.14 (two decimal places)

  if(val < 0.0){
    lcd.print('-');
    val = -val;
  }

  lcd.print ((long)val);  //prints the integral part
  if( precision > 0) {
    lcd.print("."); // print the decimal point
    unsigned long frac;
    unsigned long mult = 1;
    byte padding = precision -1;
    while(precision--)
      mult *=10;

    if(val >= 0)
      frac = (val - int(val)) * mult;
    else
      frac = (int(val)- val ) * mult;
    unsigned long frac1 = frac;
    while( frac1 /= 10 )
      padding--;
    while(  padding--)
      lcd.print("0");
    lcd.print(frac,DEC) ;
  }
}

Thanks a lot! I will try it late this morning.

At the same time, tell me where can I get the new LCD library. Are you sure it will work with my LCD display?

How many wires need to be connected for data sending? Is there a connections diagram available?

Tks again,

Jose
:slight_smile:

The library is part of the Arduino 0012 download, you can get it from here: http://www.arduino.cc/en/Main/Software

I have not seen a connection diagram for this library but the picture below is how the pins are connected in the sketch I posted above.

¡¡ Perfect !!

I will try this afternoon.

:sunglasses:

Dear Mem,

The diagram & pins of my Surduino differs. The one of my LCD also differs.

However, almost all function pins are identifiable. Almost.

I will try to attach the images of my boards...

Couldn't ..... How do you do that?

I sent you a pm that I hope will help

Dear Mem,

Wow !!! The sketch code you sent is working fine, displaying decimals on my LCD (GMD1602K

Besides changing the sketch lines and load the new library, I did nothing. I didn´t change a single wire, resistance, nothing.

Contrast is OK too. Backlit is working fine.

Thank you a lot for your patience and help.

Greetings,

José
;D [smiley=thumbup.gif] [smiley=thumbup.gif]

Good to hear you have it going. Please do post some more about your project when you have it finished.

Sure I will do. It is an automobile application.

Dear Mem:

Here is the final code, for the sketch:

#include <LiquidCrystal.h>

//create object to control an GMD1602K LCD.
LiquidCrystal lcd(12, 11, 2, 7, 8, 9, 10);

void setup(){
// don't need pinmode for analog inputs
}

void loop() {
float val; // no nead to initialize, the values are set in the first lines of code

static float acum; // states acum as cummulative
float x; // aux variable for calling subroutine void
val = analogRead(1); // read pot value
val = val/3.3; // generate decimals
acum = acum +val; // Defines acum as sum of pot values
lcd.clear(); // Cleans display

/* Prints pot value and title in first line */

lcd.setCursor(0, 0);
lcd.print("Pot=");
lcd.setCursor(6,0); // 6 is the column (starting from 0), 0 is the line starting from 0
x = val; // assigns val to x before calling void
lcdPrintFloat(x,1); // print val to one decimal place

delay (500);

/* Prints accumulated pot values and title in second line */

lcd.setCursor(0,1); // set LCD to print acum on line=2, pos=0.
lcd.print("Acum= ");
lcd.setCursor(6,1);
x = acum; // assigns acum to x, before calling void
lcdPrintFloat(x,2); // should print sum of pot values

digitalWrite(13, LOW); // blinks yellow led for delay seconds
delay (2000);
digitalWrite(13, HIGH);
if( x <= 0)
while(true); // stop displaying values if val goes negative

}

void lcdPrintFloat( float x, byte precision){
// prints val on a ver 0012 text lcd with number of decimal places determine by precision
// precision is a number from 0 to 6 indicating the desired decimal places

if(x < 0.0){
lcd.print('-');
x = -x;
}

lcd.print ((long)x); //prints the integer part
if( precision > 0) {
lcd.print("."); //prints decimal point
unsigned long frac;
unsigned long mult = 1;
byte padding = precision -1;
while(precision--)
mult *=10; //"amplifies" decimal values

if(x >= 0)
frac = (x - int(x)) * mult;
else
frac = (int(x)- x) * mult;
unsigned long frac1 = frac;
while( frac1 /= 10 )
padding--; // ¿?
while( padding--)
lcd.print("0");
lcd.print(frac,DEC) ;
}
}

I made a few comment changes, and made the function void on an aux variable "x" to make it more general to be called several times. :slight_smile: :slight_smile:

Thank you very much for your valuable help.
[smiley=thumbsup.gif] [smiley=thumbsup.gif]

Looks good.

I noticed you had added a comment with a question mark at the line padding— this line and the one above it calculates how many zeros (if any) to add between the decimal point and the fractional value.

I hope you have fun adding your functionality to this and please do post again when its done.

Is the fundamentals of the code applicable also to a serial LCD, ie Nokia 3310? If so I will try to amend it.

Thanks
Frans