Searching \ for '[PIC] Floating Point to ASCII Conversion' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/devices.htm?key=pic
Search entire site for: 'Floating Point to ASCII Conversion'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] Floating Point to ASCII Conversion'
2011\11\15@173900 by rchadwic

picon face
part 1 1960 bytes content-type:text/plain; charset="us-ascii" (decoded quoted-printable)

I am using MPLab C18 Compiler V3.38 to program an 18C4550; presently trying to use the ADC to convert voltage on a potentiometer and send it on a serial UART) interface to be displayed on Hyperterminal.
I am using the code suggested in http://support2.microchip....aspx?ID=SQ6UJ9A003PQX<http://support2.microchip.com/KBSearch/KB_StdProb.aspx?ID=SQ6UJ9A003PQX> to convert a floating point number (ADC voltage), using printf to send the result to the serial output.  Code is reproduced below.
I find that the code does not reproduce the ASCII value correctly if the floating point number leads with a zero behind the decimal point.
Example:
Floating point number   2.9984          ASCII   2.99    (good)
                       3.0018          ASCII   3.18    (bad)
                       3.095           ASCII   3.95    (bad)
                       3.104           ASCII   3.10    (good)
It looks like the code somehow is dropping leading zeros, but I can not see how or see a way to make it stop doing this.
Does anyone have any suggestions?  Thank you.

CODE:  (copied from Microchip note)
float fInput=344.9876; // Pick a number
long lWhole=0; // Stores digits left of decimal
unsigned long ulPart=0; // Stores digits right of decimal

#define MULTIPLIER 100 //(use 1 for no decimals, 10 for 1 place,
// 100 for 2 places, etc)

#include<stdio.h>
#include<p18f242.h> // choose your device as needed

void main(void)
{
// Set up the USART for output (not required, but since printf sends to the USART, it makes the output readable in the output window)
SPBRG=15;
TXSTA=0x24;
RCSTA=0x90;


//Convert number from float to fixed point for display.
//The number is converted to two parts.
lWhole=(long)((float)fInput);
ulPart=(long)((float)fInput*MULTIPLIER)-lWhole*MULTIPLIER;

printf((far char *)"The floating point number is: %li.%li\n",lWhole,ulPart);
while(1); // wait forever
}




part 2 181 bytes content-type:text/plain; name="ATT00001.txt"
(decoded base64)

--
http://www.piclist.com PIC/SX FAQ & list archive
View/change your membership options at
mailman.mit.edu/mailman/listinfo/piclist

2011\11\15@175803 by Joe Wronski

flavicon
face
Look at a reference for printf() and play with the justify flags, and width, precision, and length parameters of your printf() statement.
Joe W


On 11/15/2011 5:38 PM, rchadwic wrote:
{Quote hidden}

>

2011\11\15@180345 by Jan-Erik Soderholm

face picon face
> Does anyone have any suggestions?

Skip floating point. Use an integer instead.

Why do you need the value in HyperTerm ? Is it for
test or debugging ? Is it important that the value
is a correct interpretation of the actual voltage ?
Would not the raw value from the ADC do ?

Take "3.0018" as an example. Ad say MULTIPLIER = 4.

lWhole=(long)((float)fInput); will give an integer with value 3, not ?

ulPart=(long)((float)fInput*MULTIPLIER)-lWhole*MULTIPLIER;
That will give the part after the ".", that is "0018", still
as an integer. So 30018 - 3000 = 18.

You do now that leading zeros are realy of "no value", right ?

So "0018" is equal to "18".

Can not printf() take a float and do the conversion on the fly ?

You probably need to use strings if you are going to split
the float that way to preserve the leading zero.

Or if printf has some params to specify a fixed length equal
to MULTIPLIER and with zero fill to the left...

Jan-Erik.



rchadwic wrote 2011-11-15 23:38:
{Quote hidden}

2011\11\15@180711 by Isaac Marino Bavaresco

flavicon
face
Use:

lWhole = fInput;
ulPart = ( fInput - lWhole ) * MULTIPLIER;
printf( "The floating point number is: %li.%02li\n",lWhole, ulPart );

instead.


The "(far char *)" part and some of that typecasts are not strictly
necessary.


Isaac



Em 15/11/2011 20:38, rchadwic escreveu:
{Quote hidden}

>

2011\11\15@182541 by Isaac Marino Bavaresco

flavicon
face
Em 15/11/2011 21:03, Jan-Erik Soderholm escreveu:
> Can not printf() take a float and do the conversion on the fly ?


The printf in MPLAB C18 library doesn't support floating point (it
didn't some time ago).


> You probably need to use strings if you are going to split
> the float that way to preserve the leading zero.
>
> Or if printf has some params to specify a fixed length equal
> to MULTIPLIER and with zero fill to the left...


Yes it does, see my previous post.


Isaac

2011\11\15@191438 by Jan-Erik Soderholm

face picon face


Isaac Marino Bavaresco wrote 2011-11-16 00:25:
> Em 15/11/2011 21:03, Jan-Erik Soderholm escreveu:
>> Can not printf() take a float and do the conversion on the fly ?
>
>
> The printf in MPLAB C18 library doesn't support floating point (it
> didn't some time ago).
>
>
>> You probably need to use strings if you are going to split
>> the float that way to preserve the leading zero.
>>
>> Or if printf has some params to specify a fixed length equal
>> to MULTIPLIER and with zero fill to the left...
>
>
> Yes it does, see my previous post.
>

Which arriveed to me *after* I made my post above.
Yes, I have seen your other post... :-)

Jan-Erik.


>
> Isaac

2011\11\16@020634 by cdb

flavicon
face
Just an option (I rarely use Printf on small uC's) here is some code that I've modified from someone better than I at these things.

I then have a tailor made function of my own for displaying the result.

Colin

#define NDIG 4
#define B0 3  //Little Endian

#include <pic.h>


BYTE ftoa(BYTE *strg, float fnum);

union f_space
{
 float         fl;
 unsigned long ul;
 BYTE          uc[4]; };



BYTE ftoa(BYTE *strg, float fnum)
{
 int dexpon =0;                        //decimal exponent
 f_space Unum;
 BYTE loop,bpoint,d,test;                //bpoint = decimal point has been placed = 1 after placement
 
       bpoint = test =0;
       Unum.fl = fnum;
       
       if (Unum.uc[B0] & 0x80)
       {
               Unum.uc[B0] ^=0x80; //convert to absolute value
               *strg ='-';
               strg++;
       }
       
       //while (Unum.fl<1e-6)   {Unum.fl *= 1e6; dexpon-=6;} // optimisation cycle code
       while (Unum.fl < 1.0)
       {        
               if (Unum.fl == 0)
               break;
               Unum.fl *= 10.0;
               --dexpon;
               test++;
               
               
               
       }

       //while (Unum.fl>=1e6)   {Unum.fl /= 1e6; dexpon+=6;} // optimisation cycle code
       while (Unum.fl >= 10.0)
       {
               Unum.fl /= 10.0;
               ++dexpon;
       }
       
       Unum.ul <<=1;
       d = Unum.uc[B0] - 127;

       Unum.uc[B0] = 1;                //inserts 'hidden' 1 bit in floating point representation
       Unum.ul <<= d;

       if (test){*strg = '0'; strg++;*strg = '.';bpoint=1;dexpon=1;strg++;if(test==2)strg++;}
       *strg = '0' + Unum.uc[B0];
       strg++;
       

       if ((dexpon < 1) || (dexpon > 3))
       {
               
               *strg = '.';
               strg++;
               bpoint = 1;
       }

       for (loop = (NDIG-1);loop;loop--)
       {
               Unum.uc[B0] = 0;
               Unum.ul += (Unum.ul <<2);
               Unum.ul <<= 1;

               *strg = '0' + Unum.uc[B0];
               strg++;
               

               if (bpoint==0)
               {        
                       --dexpon;
                       if (dexpon == 0)
                       {        
                               
                               *strg = '.';
                               strg++;
                               bpoint = 1;
                       }
               }
       }
/*
       while (strg[-1] == '0')
       {
               strg--;
       }
*/
       if (strg[-1] == '.')
       {
               strg--;
       }

       *strg = 0;
       
       return 0;
}


--
cdb, spam_OUTcolinTakeThisOuTspambtech-online.co.uk on 16/11/2011
Web presence: http://www.btech-online.co.uk   Hosted by:  http://www.justhost.com.au
 This email is to be considered private if addressed to a named  individual or Personnel Department, and public if addressed to a blog,  forum or news article.

More... (looser matching)
- Last day of these posts
- In 2011 , 2012 only
- Today
- New search...