Man, lcd.print is big, but sprintf is bigger!

Just my observation. I compiled the helloWorld of liquidcrystals library

Original code 2616bytes!!
Comment the line lcd.print(number) 2034bytes ookye
Used Sprintf to generate string for number and comment the lcd.print(number) 3974bytes!!!
Add a lcd.print(string) with the above sprintf thing 4008bytes!!!!

So it seems that the lcd.print(number) costs 600bytes, while the lcd.print(string) only costs 35bytes. (include the function and one call)

The sprintf though, costs 1900bytes (include the function and one call)

If I want to output to lcd, the best way is to just output a string. The lcd.print(number) sucks anyway if you want to control on exact length.

But if you want exact say 4digits dot 2 digits, you need to use the sprintf, 1900 bytes, ouch!

Any light weight library that can take format string for just integers? Thanks.

By the way, I made this simple program that does one positive integer within 140 bytes of code. Maybe someone else has a better code that I can use. Here it is for sharing:

You provide your own buffer (6 bytes) and wipe it with empty space characters. Pass the end of the buffer-1 and the number, the program fills the buffer with a string representing the number.

int a[5]={7168, 4857, 8425, 4857, 138};

void setup()
{
  Serial.begin(115200);
}

void loop()
{
  char buffer[6];
  for (byte j=0;j<5;j++)
  {
    for (byte i=0;i<5;i++)
    {
      buffer[i]=32;
    }
    buffer[5]=0;
    
    toString(buffer+4, a[j]);
    Serial.println(buffer);
    delay(1000);
  }
}

int toString(char* buf, int num)
{
  int mynum=num;
  if (num>=10)
  {
    
    *buf=mynum-toString(buf-1,num/10)+48;
  }
  else
  {
    *buf=num+48;
  }
  return(num*10);
}

sprintf is big because it's very rich in functionality. I wouldn't bother trying to reimplement itoa() which is what your toString() seems to be doing. The avr-libc implementation is written in hand-optimized assembly language and as such is probably as good as it can be.

I do something like this:

#define STRING_BUFFER_SIZE 200
char buffer[STRING_BUFFER_SIZE];

void BufferPrint(unsigned long reading,unsigned long i) {
//reading is the value to print, i is the total padded size to print
unsigned long temp;
while (i>0){
temp = reading/i;
reading -= temp * i;
buffer[bufindex++] = 48+temp;
i/=10;
}

}

buffer[bufindex++] = '[';
buffer[bufindex++] = 'K';
buffer[bufindex++] = '0';
buffer[bufindex++] = ']';

BufferPrint(counter,1000000);

buffer[bufindex++] = '[';
buffer[bufindex++] = 'P';
buffer[bufindex++] = 'A';
buffer[bufindex++] = ']';

BufferPrint(pyramometerTotal/count,1000);

buffer[bufindex++] = '[';
buffer[bufindex++] = 'R';
buffer[bufindex++] = 'A';
buffer[bufindex++] = ']';

BufferPrint(rainDetectorTotal/count,1000);

So may output is padded and looks like:

[K0]00000020[PA]0934[RA]0010

Andy,

Where did you get that itoa()? It's not listed in the extended Arduino language reference. If it's only in avr library, can I call it from arduino?

What header file to use? If you're not aware, most folks here only deal with arduino IDE, so could you be more helpful with what we mostly don't know?

Plus, how much bigger is my program going to get if include this thing?

pantonvich, my program is essentially the same as yours. Thanks for sharing.

The prototype can be found in <stdlib.h> but the IDE already includes that so you don't have do it yourself. The full documentation is here.

In any language discovering what's already been done so you don't have to do it again is one of the keys to being a successful developer ... and also one of the frustrating parts when you're starting out. :slight_smile:

    buffer[bufindex++] = 48+temp;

A month or less from now you are going to be scratching your head wondering that the heck that 48 is for. '0' has the same value, and is much easier to understand later.

good point on using the char '0' over ascii code 48

as bad points about writing char's over using itoa type fucntions- when you get numbers outside your range you can get nice things like "((*5" as you flow over and under your 0 to 9 values... like when you assign a long to an unsigned int.

In my case I was thinking I might have an issue with program size so I went without the itoa and sprintf to write my strings.

Thanks guys. I've got where itoa is now and will likely rewrite my program if I need to shrink some size. Yeah 48 is '0', one of the advantages of ASCII over some other encodings that didn't survive. You can simply use (number | 48) in the old days when "or" is faster than add. Now I don't know if it makes any difference. The program strictly takes cares of unsigned integers so long is not a problem. It's only for my limited use so it won't become big and complex like a sprintf. My code compiles to 18KB now and I'm almost done. I wish I could shrink it to 14KB and test it with a 168. A good thing for 168 is, I use about 1KB for data storage. If I can use say just 8 bytes for data and test my code on a 168 and make it work without stack tripping over hash, I should be good with 328 automatically.