HOW TO send FLOAT value through SCI and display out in hyperterminal

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

HOW TO send FLOAT value through SCI and display out in hyperterminal

6,852 Views
popup
Contributor I
I need the MCU to calculate some float(or double) value then send this value to PC through SCI.
e.g.   float val0=13.2592;
I want to SEE 13.2592 on PC in windows hyperterminal screen.
There are many such float values need to send to PC one bye one quickly.
 
The problem is I don't know how to write a program to send such float number to PC and display them as numbers not the hex like 0x3h 0x2a 0x43 0x11.
 
Anyone knows how to work it out please help me.
Regards,
popup

 

 

Regards,
popup
Labels (1)
0 Kudos
11 Replies

1,291 Views
ThaManJD
Contributor III

Regarding single precision floating point format, wikipedia has god a really good page explaining it for anyone reading the thread wanting a decent explanation.

http://en.wikipedia.org/wiki/Single_precision" rel="nofollow" target="_blank

http://en.wikipedia.org/wiki/Single_precision

 

This same issue arose recently at work and i think i talked a colleague around to just doing it the way celsoken described.

 

JD

0 Kudos

1,291 Views
bigmac
Specialist III
Hello popup,
 
To display a floating point value on hyperterminal, you will need to convert the float value to an ASCII string, and then send the string, character by character, using the SCI module.  If you have the RAM and flash resources available, the sprintf() function is capable of providing the conversion, to the particular output format that you require.  But its use does require a lot of resources that you may or may not have available.
 
Regards,
Mac
 
0 Kudos

1,291 Views
popup
Contributor I
Hi, Mac
 
I forgot to say, you are right, I don't want to use the sprintf() because it wastes lots of resource.
So I want to write a tiny sub-function routine to work this out.
 
Regards,
popup 


Message Edited by popup on 2007-12-15 07:11 AM
0 Kudos

1,291 Views
celsoken
Contributor V
Dear popup,

When I come to situations like this, I usually convert in to int or long int and use divisions by powers of ten to perform the conversion.

Your example was something like 12.3456.
Multiply by 10000, you get 123456.
dividing by 100000 div will provide 1, convert to ascii and send, mod will give you 23456,
dividing by 10000, div will provide you 2, convert to ascii and send, mod will give you 3456, and so on.

I hope it helps,

Cheers,

Celso
0 Kudos

1,291 Views
popup
Contributor I
Hi,Celso
 
I got your point, this method sounds very similiar to sending a number to a 7-segment LED.
 
Thanks a lot.
 
Regards,
popup


Message Edited by popup on 2007-12-18 04:38 AM
0 Kudos

1,291 Views
hypocrisy
Contributor I
Try this conversion mode: 
 
xtt  = (long int)(temp_val.f*1000);// convierte el dato flotante de temperatura a un intero largo
     
     te[0]=(xtt/10000)+48;// en el arreglo de temperatura (char) llamado te almacenar el dato ascii
     xtt%=10000;
     te[1]=(xtt/1000)+48;
     xtt%=1000;
     te[2]=(xtt/100)+48;
     xtt%=100;
     te[3]=(xtt/10)+48;
     te[4]=(xtt%10)+48;// asi mismo se puede proceder para la humedad
 
This code is very useful, and do the conversion.
0 Kudos

1,291 Views
J2MEJediMaster
Specialist I

You might also want to check out FAQ-27705, which shows how to convert a binary value into a string using a simple C function. Its algorithm is similar to some of those shown here.

 

---Tom

0 Kudos

1,291 Views
Ashkan
Contributor I

Here is an implementation of float to message,the total size in bytes is: reverse 102+ itoa 108+ ftoaMsg 165 + strcpy 41. Much less than sprintf("5f)  which is around 2500byte. However, there is a fixed predetermined amount of decimal positions.

 

you can call the functions as such:

 

  ftoaMsg(senderBufferPtr, "vrms=", 1234.123 ,  2);


 
 /* reverse:  reverse string s in place */
 void reverse(char s[])
 {
     int i, j;
     char c;
 
     for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
         c = s[i];
         s[i] = s[j];
         s[j] = c;
     }
 }

/*
itoa = 143 byte
reverse = 102 byte

*/

void itoa(long int n, char s[])
{
   long int i, sign;

   if ((sign = n) < 0)  /* record sign */
       n = -n;          /* make n positive */
   i = 0;
   do {       /* generate digits in reverse order */
       s[i++] = n % 10 + '0';   /* get next digit */
   } while ((n /= 10) > 0);     /* delete it */
   if (sign < 0)
       s[i++] = '-';
   s[i] = '\0';
   reverse(s);
}



void ftoaMsg(char *Buffer, char *Msg, float Number, unsigned char decimalPrecision)
 {
 
 long int numf;
 unsigned char dp,strSize;
 char * ptr;

   Number = Number * 100;
 
  numf =  (long int) Number;
 
  (void) strcpy(Buffer, Msg);
  itoa ( numf, &Buffer[strlen(Msg)] );
 
 
  strSize=  strlen(Buffer)+1;
  ptr = &Buffer[strSize];
 
  for (dp=0;dp<decimalPrecision+1; dp++)     //decimal previsions + 1 null termination;
  {
    *ptr = *(ptr-1);
    ptr--;
  }
 
 
  *ptr =  '.';

 
 return;
}

0 Kudos

1,291 Views
Ashkan
Contributor I

Hi,

My previous implementation had some bugs in it... please use this implementation:

Here is how you can call the functions:

 

unsigned char senderBufferPtr[100];

ftoaMsg(senderBufferPtr,  "thenumberis=" , 125.123123 ,  2);

 

the code:

 

 

 

      void ftoaMsg(char *Buffer, char *Msg, float Number, unsigned char decimalPrecision)
       {
       
       long int numf;
       unsigned char strSize;
       char * ptr;

       
       (void) strcpy(Buffer, Msg);
      
       strSize=  strlen(Buffer);
       ptr = &Buffer[strSize];

       ftoa( Number, decimalPrecision , ptr);
       
       return;
      }

 

 

 

const float ROUND[6]={0.49,0.05,0.005,0.0005,0.00005,0.000005};


void ftoa(float fnum, unsigned char decimals, unsigned char *str)
{
  float scale;
  unsigned char u1,u2;
  if (fnum<0.0)
  {
    fnum=-fnum;
    *str++='-';
  }
 
  if (decimals>5)
    decimals=5;
 
  fnum += ROUND[decimals];
  u1=0;
  scale=1.0;
 
  while (fnum>=scale)
  {
    scale *= 10.0;
    ++u1;
  }
 
  if (u1==0)
    *str++='0';
  else
  while (u1--)
  {
    scale=floor(0.5+scale/10.0);
    u2=(unsigned char)(fnum/scale);
    *str++=u2+'0';
    fnum -= scale*u2;
  }
  if (decimals==0)
  {
    *str=0;
    return;
  }
 
  *str++='.';
  while (decimals--)
  {
    fnum *= 10.0;
    u2=(unsigned char) fnum;
    *str++ = u2+'0';
    fnum -= u2;
  }
  *str=0;
}

0 Kudos

1,291 Views
bigmac
Specialist III
Hello popup,
 
The suggestion by Celso is a good one - to let the compiler do some of the work for you.  Use the forum search for "BCD conversion" or "ASCII conversion" for integer conversion methods (BCD is very closely related to ASCII output).  In your case, you would probably need to convert a long int.
 
If you need to minimize resources, I might question whether it actually be necessary to use floating point numbers.  In many instances it is possible to use suitably scaled, fixed point integer calculations, depending on the type of processing involved.  However, if you require to use any non-linear functions, you will probably need to stick with floating point, and the resources it requires.
 
Regards,
Mac
 
0 Kudos

1,291 Views
popup
Contributor I
Hi, mac
 
matter is I don't know how to convert a float to a ascii string. Do you have some related routines?
 
the floating point number takes 4 bytes in storage and converting it byte to byte is useless(I think).
 
I scratched my head about this and had no idea.
 
Regards,
popup
0 Kudos