SparkFun Forums 

Where electronics enthusiasts find answers.

Have questions about a SparkFun product or board? This is the place to be.
By kmycek
#100140
OK... I am pulling my hair out trying to display a simple float value on my SerialLCD screen...!
I'm using one of the SparkFunSerLCD libraries (downloaded from http://www.arduino.cc/playground/Code/SfLCD]). It has an "at" function which is overloaded with many types (besides float!)... It basically calls the "pos" function, and then immediately the "print" function from the SoftwareSerial library.

So I need to convert my float to a string (or array of chars, correct?). Here is my snippet.

float test = 123.45;
char temp[10];
snprintf(temp, 9, "%f", test);
lcd.at(1,1, temp);

It results in a question mark (?) in the first row, first character... I have tried several formatting strings, to no avail. Am I missing something? I wish there was a .ToString() function!!!

Keith
By OrlandoArias
#100172
The stdlib.h gives you itoa() and some variants for other integer types. It does not however give you an option for floats. See
http://www.cs.mun.ca/~paul/cs4723/mater ... e1dbf7a665 for details.

As for your question mark showing up in your character buffer... Try with
snprintf(temp, 9, "%.3f", test); //use 3 decimal points

and see if that works. This i think is caused by the signedness of your float. Including stdlib.h in your code may also help.
By whoismaha
#100195
I vote you simplify a bit, put your code into a C or C++ program and 'printf(temp);' to console.

Just to make sure it's not the LCD causing problems. Also, is it possible that your float, once converted to ascii, is more than 9 characters and there isn't enough space to \0 null-terminate the string? What number is snprintf returning?
By kmycek
#100239
float test = 123.45;
char temp[80];
snprintf(temp, 79, "%.3f", test);
lcd.at(3,1,temp);
Serial.println(temp);
Serial.println(snprintf(temp, 79, "%.3f", test));

Thanks, guys. I gave all your ideas a try. Still having issues. I get the same result on the serial port as I do on the LCD. The first serial line prints out a "?" (just the same as on the LCD). The second serial.print results in a "1" - which I assume is an implicit conversion from a boolean - meaning that the snprintf call was successful. It doesn't seem to matter what float value is in test.

BTW, Serial.println(test) results in "123.45". But I get a compilation error if I try lcd.at(3,1,test) since there is no overload that takes in the float - only char arrays, ints, longs, etc. A call to lcd.at(3,1,"123.45") results in "123.45", as expected. So I think if I can just successfully convert the float to a string, it would work.

There is an overload that takes in two params - a long and an int. The int is the base. So if I call Serial.println(temp, 10) - I get "123".


Keith
By OrlandoArias
#100241
I know this is a bit of overkill, and may be a bit harder to implement, but try this out:
http://www.nongnu.org/avr-libc/user-man ... out_malloc

The idea on that sample code is to set up things in such way that prinf() can be used. Note that using printf() will introduce (lots of) extra overhead on your final program. Basically, what you need to do is re-setup the function that prints to the LCD as a function capable of accepting a stream. This is a sample project that is close to what we are attempting to do

http://www.nongnu.org/avr-libc/user-man ... out_malloc

After you set up your stdout, you'll be able to call printf("%f", somefloat); and the data will automagically appear on the LCD. If you don't like this approach, there's always the option of writing your own ftoa() function :P.
By bigredsparks
#100723
Keith, if lcd.at(3,1,"123.45") works then the problem is in the conversion. A key thing to keep in mind with C/C++ is that strings are a convention and not an object or type like they are in Java or C#. Basically, a string is a char array that ends with a null or zero (0) character. The lcd.at() function takes a char[], but you should interpret this as requiring a string (or a char array the ends with a null).

So given your example, the string "123.45", in memory this looks like:
temp[0] = '1'
temp[1] = '2'
temp[2] = '3'
temp[3] = '.'
temp[4] = '4'
temp[5] = '5'
temp[6] = 0 - not the zero character ('0') but zero

The other thing to notice is that if you have a string that requires 10 characters, the variable in which is it stored needs be at least 11 character long.
There is no problem allocating more space than you need, you just have to be careful not to go over. Otherwise, you could stomp on other variables that are stored adjacent to it in memory.

You can use the snprintf() function because you can be safe with the sizes, however I don't think it is necessary. I think the sprintf() function will do just fine. Try this:

sprintf(temp, "%.f\0", test);

or:

snprintf(temp, sizeof(temp), "%.f\0", test);

The \0 puts at the end will force the string to end with a 0 or null character. This may not be necessary, but I have run into similar problems before and this fixed it.
I would also suggest doing the Serial.println(temp) before the call to lcd.at() just to verify that the conversion was done correctly prior to sending it to the LCD.

Finally, keep in mind that just declaring a char array, like:

char temp[10];

Does not affect the contents of the array. The contents could (and probably are) some random value. You could also try clearing the contents prior to setting them. This is done with the memset() function:

memset(temp, 0, sizeof(temp));

This will set all characters in the array to 0 (or null).

Good Luck
-BigRed