printDouble (lcdPrintDouble) problem

I download the latest lcdPrintDouble from the forum and it did not work at all. with some debugging I found that the mult was wierd numbers. mult is supposed to be powers of ten but it was equalling 79345... and other strange things. so i modified the code a little bit and it mostly works but I am still having some trouble with pow() and mult.

#include <LiquidCrystal.h>

// LiquidCrystal display with:

LiquidCrystal lcd(2, 11, 3, 4, 5, 6, 7);

void setup()
{
  Serial.begin(9600);
  // Print a message to the LCD.
  lcd.print("float test!");
  delay(2000);
  lcd.clear();
}
void loop()
{
   lcd.setCursor(0,0) ;
   lcdPrintFloat(-1.1 ,3);
   lcd.setCursor(0,1) ;
   lcdPrintFloat(2.012, 5); 
   lcd.setCursor(20,0) ;
   lcdPrintFloat(-3.1234, 5);
   lcd.setCursor(20,1) ;
   lcdPrintFloat(2.004, 6);
   delay(5000);
}

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)
  long toPrint = val*10000;
  long frac;
  long mult = 0;
  int padding = precision - 1;

  Serial.print("\n\n");
  Serial.println(toPrint, DEC); 
  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
    mult = (long) pow(10,precision);
    
    Serial.print("padding = ");
    Serial.println(padding, DEC);
    Serial.print("precision = ");
    Serial.println(precision, DEC);
    Serial.print("mult = ");
    Serial.println(mult, DEC);
    
    frac = (val - int(val)) * mult;

    Serial.print("frac = ");
    Serial.println(frac, DEC);

    long frac1 = frac;
    while( frac1 /= 10 ) { padding--;}
    
    while(  padding--) { lcd.print("0"); }
    lcd.print(frac,DEC) ;
  }
}

returns

-11000
padding = 2
precision = 3
mult = 999
frac = 99

20120
padding = 4
precision = 5
mult = 99999
frac = 1199


-31234
padding = 4
precision = 5
mult = 99999
frac = 12339

20040
padding = 5
precision = 6
mult = 999999
frac = 3999

the mult is calculated using pow(10,x) so I do not see how I am ending up with 99 or 999.
any help would be thankful

The latest version of that code is here: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1207226548/13#13

I don't get the odd results you refer to. Here is a test sketch :

// uses print routines from here: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1207226548/13#13
#include <LiquidCrystal.h>

// LiquidCrystal display with:

//LiquidCrystal lcd(2, 11, 3, 4, 5, 6, 7);
LiquidCrystal lcd(7,6,5, 9,10,11,12); // my lcd wiring

void setup()
{
  Serial.begin(9600);
  // Print a message to the LCD.
  lcd.print("float test!");
 Serial.println("float test!");
  delay(2000);
  lcd.clear();
}
void loop()
{
   lcd.setCursor(0,0) ;
   lcdPrintDouble(-1.1 ,3);
   lcd.setCursor(0,1) ;
   lcdPrintDouble(2.012, 5);
   lcd.setCursor(20,0) ;
   lcdPrintDouble(-3.1234, 5);
   lcd.setCursor(20,1) ;
   lcdPrintDouble(2.004, 6);
   
   printDouble(-1.1 ,3);
   Serial.println();
   printDouble(2.012, 5);
   Serial.println();
   printDouble(-3.1234, 5);
   Serial.println();
   printDouble(2.004, 6);
   Serial.println();
   delay(5000);
}

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

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

  Serial.print (int(val));  //prints the int part
  if( precision > 0) {
    Serial.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--)
 Serial.print("0");
    Serial.print(frac,DEC) ;
  }
}

 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.print('-');
    val = -val;
  }

  lcd.print (int(val));  //prints the int 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) ;
  }
}

The output to the LCD is the same as the serial output:
float test!
-1.100
2.01200
-3.12339
2.003999

I note your version uses the pow function - this links in lots of code that makes the sketch over 1k bigger than the version here

Someone posted a revised version about a week ago that does the rounding (so 2.003999 prints as 2.004) Not sure where it is but I search should turn it up if you need it.

when I use your code (only changed lcdcystal line) I get different results

float test!
-1.000
2.00001
-3.00014
2.000002

and the lcd is filled with random zeros
I am running ubuntu 8.10 and arduino 12 alpha. could it be something to do with ubuntu or with the alpha version of arduino?

Try it without your LCD library - run this sketch:

// uses print routines from here: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1207226548/13#13

void setup()
{
  Serial.begin(9600);
  // Print a message to the LCD.
  Serial.println("float test!");
  delay(2000);
}

void loop()
{

  printDouble(-1.1 ,3);
  Serial.println();
  printDouble(2.012, 5);
  Serial.println();
  printDouble(-3.1234, 5);
  Serial.println();
  printDouble(2.004, 6);
  Serial.println();
  delay(5000);
}

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

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

  Serial.print (int(val));  //prints the int part
  if( precision > 0) {
    Serial.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--)
      Serial.print("0");
    Serial.print(frac,DEC) ;
  }
}

If that gives the correct results the problem is in your LCD library.
My guess is that your sketch is running out of memory and that is causing the odd values. If that is caused by the LCD code then you need to fix whatever is consuming memory or use another library. If you have a big array in your LCD code, try moving that to progmem.

Good luck!

I do not believe my problem is space. I am only running the code you posted above (compiles to 5000b or so)

I have notice that a portion of my problem can be fixed if I declare mult as a "double" or "unsigned int"

If I use "unsigned int" the program works fine until I need a mult above
If I use "double" the mult problem disappears but my number are incorrectly rounded (ie 3.1234 becomes 3.12339)

In a previous post you said you were: " running under running ubuntu 8.10 and arduino 12 alpha. could it be something to do with ubuntu or with the alpha version of arduino?"

Not sure whats in the alpha version, can you try it with the standard 0012 distrubution ?