Solved

HART Protocol Floating point handling

Posted on 2010-09-21
12
1,456 Views
Last Modified: 2013-11-17
I am working with HART protocol to send data to a device over serial com port.  The HART protocol requires that floats use IEEE-754 format.  For example to send the float 4.025 to the device I have to convert it to IEEE-754 format which is 0x40 80 CC CD and send this to the device.
Receiving data is the reverse--the device sends a float to me such as 0x40 80 CC CD and I have to convert it to decimal 4.025.
Are there any suggestions as to how to convert both ways: 1. decimal to binary and 2. binary to decimal?
I use C++ Borland
0
Comment
Question by:farcuri
  • 6
  • 5
12 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 33726460
The C/C++ data type 'float' (or 'double' for double3 precision) is already what IEEE-754 describes, so no additional modifications are necessary. See also http://en.wikipedia.org/wiki/IEEE_754-1985
0
 

Author Comment

by:farcuri
ID: 33726618
Ok,
I think I follow what you are saying but could you clarify maybe with my example.  For instance, if I declare
float value= 4.025 and I want to send this to my HART device I need to put it in a 32 bit word let's call it TXData.  How would I do that?  TXData is binary where the sign is the highest bit.  The next eight bits are the exponent, and the mantissa is the next 23 bits.
Thanks,
Fabio
0
 
LVL 86

Expert Comment

by:jkr
ID: 33726764
Well, like
#include <memory.h>

float f = 4.025;
unsigned int TXData; // four bytes

memcpy(&TXData,&f,sizeof(float));

// alternatively, just use the address of 'f' to send four bytes

Open in new window

0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
LVL 53

Expert Comment

by:Infinity08
ID: 33726859
>> The C/C++ data type 'float' (or 'double' for double3 precision) is already what IEEE-754 describes

Just as a side note, although this is generally true, there are some implementations that don't conform to that floating point standard. C Implementations that do, define __STDC_IEC_559__, so you can check for that.

No points for this post, please. Just mentioning it for completeness' sake.
0
 

Author Comment

by:farcuri
ID: 33727096
Hi JKR,
I like your answer.  I am going to test it.  I have a follow-up.  How do I do the reverse? Convert binary back to decimal.  Would it be a memcpy?  I would appreciate an example to if you don't mind.
Thanks,
Fabio
0
 
LVL 86

Expert Comment

by:jkr
ID: 33727128
Just the same way
float f;;
unsigned int TXData; // read four bytes from device

memcpy(&f,&TXData,sizeof(float));

printf("Value read is %f\n", f);

Open in new window

0
 

Author Comment

by:farcuri
ID: 33728503
Hi JKR,
Thanks to your help I am getting very close to doing what I need to do, however I have hit a mental block.
What I need is to convert the float into the IEEE-754 format (and the method you described above does that perfectly) however I need to put the 4 byte hex value into an array of unsigned char.  Could you please redo your  float to binary example above to go from float 4.025 to unsigned char 0x40 80 CC CD?
Thanks,
Fabio
0
 
LVL 86

Expert Comment

by:jkr
ID: 33728541
You need the string 0x40 80 CC CD? Or just the binary representation?
0
 

Author Comment

by:farcuri
ID: 33728628
Maybe the code below can answer the question.  I can send the representation below to my HART device OK.  I'd like to emulate that.

static unsigned char    m_ucTxBuffer[255];
memcpy(&m_ucTxBuffer[0], "\xff\xff\xff\xff\xff\x02\x80\x00\x00\x82",10);
0
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 33728715
Ah, OK, so you need it as a string. Then try
#include <memory.h>

float f = 4.025;
unsigned char buf[4]; // four bytes
unsigned int i0,i1,i2,i3;

memcpy(buf,&f,sizeof(float));

i0 = (unsigned int) buf[0];
i1 = (unsigned int) buf[1];
i2 = (unsigned int) buf[2];
i3 = (unsigned int) buf[3];

sprintf(m_ucTxBuffer,"\xff\xff\xff\xff\xff\x%2.2x\x%2.2x\x%2.2x\x%2.2x\x%2.2x",i0,i1,i2,i3);

Open in new window

0
 

Author Comment

by:farcuri
ID: 33728953
Ok,
Thanks,
I will try it.
0
 

Author Closing Comment

by:farcuri
ID: 33738393
Hi jkr,
I tested the decimal to IEEE754 HEX representation in my program and it worked!  You  get the points.
If you have a minute though could you explain what the line memcpy(buf,&f,sizeof(f)) does exactly? I also noticed that the order of the HEX bytes get reversed.  To represent them in the order MSB to LSB I need to load m_ucTxBuffer[0]= i3
m_ucTxBuffer[1]= i2
m_ucTxBuffer[2]= i1
m_ucTxBuffer[3]= i0
Could you briefly explain that too?  My next test is to do the IEEE-754 to decimal conversion.
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.

821 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question