kcox1980

Converting REAL to DINT

8 posts in this topic

I have a somewhat interesting problem. I have a tag that stores a value that represents the total number if linear feet ran off our line for an entire shift. This value is stored as a REAL data type on the Winder PLC where it is primarily needed. However, we also pass this information both to the main line's PLC and to a Historian database, both of which store the value as a 32 bit integer.

Now here's where it gets interesting. Whenever the value of the REAL tag at the winder passes 32,768(which you may recognize as the maximum value of a 16 bit integer, I feel that has to be significant) the main PLC and the Historian database both show the value instantly double to 65,536 and then start counting backwards. There is no way possible for this machine to go backwards fyi. Again, keep in mind that on the Winder HMI it displays just fine, there is only an issue when it gets passed to one of the systems that stores it as a DINT. 

So what is going on here? I assume it has something to do with the conversion from REAL to DINT, but how exactly?

Share this post


Link to post
Share on other sites

Hello,

Floating point values (REAL) are not bit weighted. Floating point values are encoded. Normally, "moving" a float point value to an integer or double integer will fail. Viewing the bits, as an integer, will not give the correct value.

Most programming languages provide routines to convert the parts of an encoded floating point value to its parts.

For example, a TRUNC command would return the whole part of a floating point value. FRAC would return the fractional part of a floating point value. Some programming languages look at the data type of the destination and automatically convert the floating point value to the correct value based on the destination type.

Quote

there is only an issue when it gets passed to one of the systems that stores it as a DINT. 

Right, the value must be converted on one end or the other. For example, the four bytes, that represent the floating point value, could be moved into two MODBUS holding register. Now the program reading the MODBUS holding registers would convert the four bytes to a floating point value.

 

 

Edited by Mark-

Share this post


Link to post
Share on other sites

Wouldn't it be easier to change the original tag to be a DINT? Assuming no other conflicts of course. I'll double check before changing it but I believe this tag is only being used to display the Winder totals.

You've given an excellent explanation but I'm still not completely clear as to why it works up until the value crosses the 16 bit integer maximum value. Maybe just an odd quirk?

Share this post


Link to post
Share on other sites

I've never had an issue moving a REAL to a DINT within a PLC, as long as I understand and keep track of whether it rounds or truncates (and how it rounds...).  The PLC's MOV instruction handles the type casting with no issues.

I would try converting the REAL to a DINT within the PLC that's generating the count (making sure it's rounding the way you want), then transfer that DINT to the other stations.  You should be able to do that without disturbing anything in the Winder PLC just by MOVing the REAL tag to a DINT tag.

 

So, scraping out some old binary number stuff and thinking "out loud"....

A 16-bit signed integer register can contain values from -32768 to 32767.  If you add 1 to 32767 in an AB PLC (16-bit signed integers), it will wrap around to -32768. 

0111 1111 1111 1111 (32767) + 1 = 1000 0000 0000 0000 (-32768) (16 bit)

If you do it with 32-bit integers:

...0000 0111 1111 1111 1111 (32767) + 1 = ...0000 1000 0000 0000 0000 (32768) (32 bit)

An unsigned 16-bit integer register can contain values from 0 to 65535.  The bit pattern corresponding to 65535 (16 1s in a row) will be interpreted as "-1" if the PLC is expecting a signed integer instead of unsigned.

Unsigned: 1111 1111 1111 1111 = 65535

Signed: 1111 1111 1111 1111 = -1

A DINT is 32 bits, so a signed DINT can range from -2147483648 to 2147483647. 

The 32-bit pattern for 65536 is ...0001 0000 0000 0000 0000

Hmmmmm......

I wonder if you might have some byte swapping or word swapping happening when the information is transferred from one station to another.  Can you look at the bit patterns at the source and destination at the same time?  How are you getting the information from point a to point b?  What are the PLCs at each end of the transfer?  Does the historian database read the information out of the main PLC or directly from the winder?

Share this post


Link to post
Share on other sites

tHANKS tHAT eXPLAINS A lOT :)

 

Share this post


Link to post
Share on other sites

kcox1980: Can you post your code?

Share this post


Link to post
Share on other sites
15 hours ago, Joe E. said:

I wonder if you might have some byte swapping or word swapping happening when the information is transferred from one station to another.  Can you look at the bit patterns at the source and destination at the same time?  How are you getting the information from point a to point b?  What are the PLCs at each end of the transfer?  Does the historian database read the information out of the main PLC or directly from the winder?

Alright, so let me back up for a second here. To be honest I never actually checked the main PLC to confirm that the tag was a DINT, I assumed that it was since it was exhibiting the same behavior as the Historian database, which I did confirm as a DINT. Per your suggestion I pulled up both the Winder and Main PLC programs and looked at the tags at the same time when I think I found out what might be happening, though I'm still not sure why or how to fix it.

It turns out that the main PLC also stores the value as a REAL, although it will only display it as a whole number. The original tag on the Winder PLC is displaying the value with decimal precision down to the ten thousandths(i.e. 4710.6987 as of this post). The main PLC is displaying a value rounded off to the nearest whole number. Is this something that might cause this issue? 

8 hours ago, JRoss said:

kcox1980: Can you post your code?

While I'm not aware of any NDA policies that would prevent me from doing so, I probably shouldn't post the entire code. I can provide some screen shots if there's something particular you're looking for though.

Share this post


Link to post
Share on other sites

What models are the two PLCs, and how is the data getting transferred from one to the other?

It sounds like you're getting some conversion errors during the translation, probably due to some combination of signed/unsigned INT and DINT variables.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now