U8glib - How to display leading zeroes?

Hi,

I'm using the OLED display with the u8glib.

Let's say I have a variable defined as float
x = 3.52;

I want to display this number on the OLED display with 1 leading zero, how can I do that with u8glib?
I mean the display number should look like this: "03.52"

Can someone give me a hint, please?
Thank you!

if (val < 10) lcd.print('0');
lcd.print(val);

Yep, it has nothing to do with the lib... You can write a function for it :slight_smile:

Just made a quick one. Keep forgetting to make a nice library for it. And I never made a float version. Float is evel misused most of the time. Bigger fan of fixed point notation.

void printFixedWidth(Print &out,float in, int width, byte decimals){
  float temp = in;
  
  //do we need room for a minus?
  if(in < 0){
    width--;
  }
  
  //compensate for after the decimal and the decimal
  width -= decimals + 1;
  
  //no room left?
  if(width < 0){
    width = 0;
  }
  
  //let's check width of variable efore decimal
  while(temp > 10 && width){
    temp /= 10;
    width--;
  }
  
  //now let's print it
  //is it negative?
  if(in < 0){
    out.print('-');
  }
  
  //fill it up
  while(width){
    out.print('0');
    width--;
  }
  
  //now print the number
  out.print(abs(in), decimals);
}

Thank you septillion,
I initially though u8glib supports function like the printf :D, which makes thing easier.
But your suggestion is also great!

david_prentice:

if (val < 10) lcd.print('0');

lcd.print(val);

That's not the best approach. Feed it something like 9.998 to see why.

I came up a function that avoids that problem.

void showPaddedFloat (float num, int cells, int places=1) {
  if (places<0) places=0; // because lower values are not supported
  if (places>6) places=6; // because higher values are not supported
  boolean neg = false;
  long adj = (long)((num * pow(10.0, places)) + ((num>0.0)?0.5:(-0.5)));
  if (adj<0) {
    neg = true;    
    adj = -adj;
    cells--; // to leave room for the minus sign
  }
  if (places>0) {
    cells -= (places + 1);
  }
  long divisor = 1;
  for (int i=1; i<=places; i++) {
    divisor *= 10;
  }
  long frac = adj % divisor;
  adj /= divisor;
  if ((cells>9) && (adj<=999999999L)) lcd.print(" ");
  if ((cells>8) && (adj<=99999999L)) lcd.print(" ");
  if ((cells>7) && (adj<=9999999L)) lcd.print(" ");
  if ((cells>6) && (adj<=999999L)) lcd.print(" ");
  if ((cells>5) && (adj<=99999L)) lcd.print(" ");
  if ((cells>4) && (adj<=9999L)) lcd.print(" ");
  if ((cells>3) && (adj<=999L)) lcd.print(" ");
  if ((cells>2) && (adj<=99L)) lcd.print(" ");
  if ((cells>1) && (adj<=9L)) lcd.print(" ");
  if (neg) lcd.print("-");
  lcd.print(adj);
  if (places>0) {
    lcd.print(".");
    if ((places>5) && (frac<=99999L)) lcd.print("0");
    if ((places>4) && (frac<=9999L)) lcd.print("0");
    if ((places>3) && (frac<=999L)) lcd.print("0");
    if ((places>2) && (frac<=99L)) lcd.print("0");
    if ((places>1) && (frac<=9L)) lcd.print("0");
    lcd.print(frac);
  }
}

I would certainly agree that the Arduino Print formatting is a pain.
But the C++ stream approach is pretty horrible too.

Regular C printf() is considerably easier to use but is not set up for floats in the Arduino Build.

Yes, your helper function is useful.
My "simple" one-liner is probably sufficient in 99.5% of Arduino sketches. e,g. displaying fixed width value on a 16x2 LCD.

David.

@odometer, if you start doing things like:

((cells>9) && (adj<=999999999L)) lcd.print(" ");
  if ((cells>8) && (adj<=99999999L)) lcd.print(" ");
  if ((cells>7) && (adj<=9999999L)) lcd.print(" ");
  if ((cells>6) && (adj<=999999L)) lcd.print(" ");
  if ((cells>5) && (adj<=99999L)) lcd.print(" ");
  if ((cells>4) && (adj<=9999L)) lcd.print(" ");
  if ((cells>3) && (adj<=999L)) lcd.print(" ");
  if ((cells>2) && (adj<=99L)) lcd.print(" ");
  if ((cells>1) && (adj<=9L)) lcd.print(" ");

you ave to start things, mannnnn, this code sucks.... So much repetition. And all that float math!

But you're right, my code will give you an error if you try to print 9,9 without decimals. Here with fix.

void printFixedWidth(Print &out, float in, byte width, byte decimals){
  float temp = in;
  
  //compensate for rounding if we don't want decimals
  if(decimals == 0){
    temp += 0.5;
  }
 
  //do we need room for a minus?
  if(in < 0){
    width--;
  }
 
  //compensate for after the decimal and the decimal
  width -= decimals + 1;
 
  //no room left?
  if(width < 0){
    width = 0;
  }
 
  //let's check width of variable efore decimal
  while(temp > 10 && width){
    temp /= 10;
    width--;
  }
 
  //now let's print it
  //is it negative?
  if(in < 0){
    out.print('-');
  }
 
  //fill it up
  while(width){
    out.print('0');
    width--;
  }
 
  //now print the number
  out.print(abs(in), decimals);
}