TI505 two U16's to F32.

GRadford

Member
Join Date
Feb 2021
Location
VA
Posts
4
I am trying to figure out the math with two U16 values that are converted to a Float(F32) in the TI so as to duplicate in a Siemens S7-1500. Seems like it should be straight but I'm missing something.

In the TI505 we have:
V600 = 17017 U16
V601 = 8360 U16
V603. = 62.2819 F32

In the S7-1500 we have
MW100 = 17017 UInt
MW102 = 8360 UInt
MD104 = 1.115234E+09 Real

I have tried ByteSwap, WordSwap etc.
//Byte Swap
#TmpWord0.%B0 := #UInt0.%B0;
#TmpWord0.%B1 := #UInt0.%B1;
#TmpWord1.%B0 := #UInt1.%B0;
#TmpWord1.%B1 := #UInt1.%B1;
//Word Swap
#TmpDWord0.%W0 := #TmpWord1;
#TmpDWord0.%W1 := #TmpWord0;
//Out
#RealOut := DINT_TO_REAL(DWORD_TO_DINT(#TmpDWord0));
Thanks for responses
 
That is because the two values in the units are effectively 1115234472 so the Dint to real (float) sees it as 1.115234e+09 in other words it is converting what is a long integer to a real.
The two uints you have are probably a real split across two words as this is how older PLC's worked so in fact they were neve two uints but a double word representing a floating point value. using DINT to real (float) will not work, in actual fact there is no conversion as far as I know.
Just reference MW100 as a real (float),
Mitsubishi do this for example, D100 is a 16 bit word, as a tag this is MD100 that contains D100 & D101 ( %MD0.100)
Cannot remember if it is the same in siemens but if you configure the tag as a real but force those values into the two MW words it will give you the correct value.
See how a float is stored in a 32 bit word (single precision) here:
http://plccenter.cn/Siemens_Step7/Format_des_Datentyps_REAL_Gleitpunktzahlen.htm
 
From https://www.plctalk.net/qanda/showthread.php?p=7110#post7110:


the [...] and TI-505 are both BIG ENDIAN. Look at the CPU on your favorite TI505 and tell me it isn't a Motorola CPU....





Using python and the struct module pack and unpack methods cf. here
>>> '{0:04x}'.format(8360)
'20a8'
>>> '{0:04x}'.format(17017)
'4279'

>>> '{0:08x}'.format(*struct.unpack('i',struct.pack('f',62.281890869140625)))
'427920a8'
So the 8360 has to be in the 4 low (Least-Signficant) Bytes (LSBs) bytes, and the 17017 has to be in the 4 high (Most-Significant) Bytes (MSBs).

On my LSByte-first Linux system (Intel), that means the 8360 is first (0xa8 LSB then 0x20 MSB), and the 17017 follows last (0x79 LSB then 0x42 MSB). Applying this via struct.pack and struct.unpack on my LSB-first system:
>>> struct.unpack('f',struct.pack('hh',8360,17017))
(62.281890869140625,)
So, on the TI505, it appears that the 17017 is first (V600) and the 8360 is second (V601), which is consistent with @PeterN's declaration that the TI505 is MSByte-first.

QED.

I don't know what the byte order is on S7-1500, but once that is known, then this will be able to be sorted out.
 
Last edited:
Thx, Yes I have tried it all, even complete 32bit invert, it has something to do with the Siemens DINT_TO_REAL() function or the fact that it only interprets the conversions as the DInt to Real. I thought it would

This is the result just before conversion in the 1500:
2#0100_0010_0111_1001_0010_0000_1010_1000 (16#4279_20A8)

This is the result:
2#0100_1110_1000_0100_1111_0010_0100_0001 (Float 1.115234E+09)
This is what I need:
2#0100_0010_0111_1001_0010_0000_1010_1000 (Float 62.28189)
 
it has something to do with the Siemens DINT_TO_REAL() function or the fact that it only interprets the conversions as the DInt to Real.




Yes, DINT_TO_REAL is a conversion of the value of the DINT to the value of a REAL; you want to code to to copy the bits of the

two UINTs to the bits of the real instead.



@parky referred to using %MW100 and %MW102 notation to write the 16-bit integers to memory, and then use the notation %M?100 to look at the same memory (and bits), but as a REAL (I don't know what ? should be; this seems to suggest %MD100).



In A-B-land one would use the COP or CPS or CPW instruction.


I think in S7 a tag-based approach uses the AT instruction to lay the F32 over the two 16-bit integers.


This is the same as a Fortran EQUIVALENCE statement.


Best regards,


Brian T. Carcich
 
Last edited:
Try MR100.


Also https://support.industry.siemens.com/tf/ww/en/postattachments/image/?attachmentId=91186


Another way to do it, without overlays, from the UINT values 17017 and 8360 (excluding sign):

>>> f=(( (((17017 & 0x7f)*65536.) + 8360) / 8388608.0) + 1.0) * ( 2.0 ** (int((17017 & 0x7f80) / 128) - 127) )
>>> f
62.281890869140625


>>> struct.unpack('f',struct.pack('hh',8360,17017))[0]
62.281890869140625


### Test:


>>> struct.unpack('f',struct.pack('hh',8360,17017))[0]-f
0.0
 
Last edited:
The two Uints are actually one real, I have just tested it in Mitsubishi the DINT to real will not work as it sees the double word as an integer so for example
17017 & 8360 is 1115234 decimal, so conversion to a real gives the same value i.e. 1115234.0 or 1115234e+9.
Se actual pic, so I suggest you make MW100 a real which I believe is MD100
(If Siemens is the same as the older S7 then the addresses are in bytes so word is MB100 & MB101 i.e. MW100, so make a tag of a real My_Real = MD100
or what ever the declaration is now and use it directly, I suspect that this is either some communication stored as uints or as in the older Mitsubishi registers i.e. D0 if passed to a function that requires a uint takes just D0, however, if D0 is passed as a Real then it takes D0 & D1.

Real.png
 
This is the same thing in the older GXDeveloper ladder, note the two words D0 & D1 are reversed, forgot to mention that so it will depend on how the processor uses double words.
So this proves that the values you have in those two words are actually a real value so cannot be treated as two integers.

Real Ladder.png
 
OMG! It is right in my face! All I have to do is declare the First Word of the two Words as a Real...I need a vacation...
THANK YOU ALL FOR YOUR HELP.
I can see the Trees now...

This is the result just before conversion in the 1500:
2#0100_0010_0111_1001_0010_0000_1010_1000 (16#4279_20A8)
This is what I need:
2#0100_0010_0111_1001_0010_0000_1010_1000 (Float 62.28189)
 
Floating point is totally different to integer format what with Mantissa's Exponent & sign it becomes a little complicated. to be honest it's only because in the older models (and some later ones that still use existing byte/word variables) that it becomes clear.
 

Similar Topics

Hi. I have 2 files where I would like to see the ladder logic differences (similar to the Rockwell compare function). I am using TISoft Siemens...
Replies
1
Views
1,264
Hello everyone, this is a noob speaking. I have no idea about plc's, just some basic things. So, I work at a factory in greece and we have a...
Replies
4
Views
1,148
Stick a fork in it? Circa 1995 control system on a critical machine. Less than 100 Digital IO, less than 10 analog IO. I believe we can remove...
Replies
4
Views
1,631
Hi, I'm in an plant that uses TI505's. They have started upgrading to compactlogix but have reached the stage that they need PLC to PLC coms. TI...
Replies
3
Views
2,337
I'd like to start by saying that my background in engineering is mostly mechanical, and I have a tiny bit of experience with AB and RSLogix (to...
Replies
10
Views
2,651
Back
Top Bottom