This may not be quite as straightforward as you had hoped.
How much do you know about the floating point format? I've never worked with PLC5 or ControlLogix, only MicroLogix and SLC among Allen Bradley hardware. They use the IEEE 754 single-precision floating point format. The conversion between floating point and decimal formats is not trivial, and is summarized here:
1) Convert the number, including the fractional portion, to binary. In the example given here (0.0000002004145), we get:
0.0000000000000000000000110101110011000110000101
2) "Normalize" this result by shifting the "decimal" point so that it is to the right of the most significant "1":
1.
1010 1110 0110 0011 0000 101x2^
-23The
red digits become the mantissa portion of the floating point number while the
blue number is the exponent. Note that there is an odd number of bits for the mantissa and that the exponent is negative. The most significant "1" is understood to be present, and is therefore not included in the mantissa that is stored.
3) Add 127 to the exponent and convert it to binary. Adding 127 (called "excess 127") saves us from having to designate a sign for the power, allowing all 8 bits to be significant.
exponent becomes -23 + 127 = 104 = 0110 1000
4) If the original number is negative, the first bit of the floating point number will be a 1, otherwise it's a 0.
The final layout is:
S
EEEE EEEE MMMM MMMM MMMM MMMM MMMM MMMSo, for your number, decimal 0.0000002004145, we get this bit pattern:
0
0110 1000 1010 1110 0110 0011 0000 101
Now, in a SLC, it is possible to work with this, but, as mentioned before, it won't be trivial.
I just did a little testing in a SLC 5/04 on the bench. A COP instruction will get the 32 bits into 2 integer elements:
CODE
COP #F8:0 #N7:1 2
In this example, the most significant 16 bits will be in the first element (N7:1) while the least significant bits will be in N7:2.
If you know you will always have positive numbers, you can ignore the most significant bit (N7:1/15). The next 8 bits are the exponent portion while the remaining bits form the normalized mantissa. I found a pretty good converter app here:
http://www.h-schmidt.net/FloatApplet/IEEE754.htmlIt is not difficult to extract the exponent portion, using a MVM instruction on the most significant integer element:
CODE
MVM N7:1 7F80h N7:10
The address N7:10 now contains the exponent, but it needs to be shifted to the right 7 places. This can be done using BSR instructions, or, more simply, using a DIV instruction:
CODE
DIV N7:10 128 N7:11
To get the actual exponent, we need to subtract 127:
CODE
SUB N7:11 127 N7:12
At this point, these are the values in memory:
F8:0 = 2.004145E-007
N7:1 = 0011 0100 0101 0111b = 13399d (most significant 16 bits)
N7:2 = 0011 0001 1000 0101b = 12677d (least significant 16 bits)
N7:10 = 0011 0100 0000 0000b = 13312d (result of MVM, the exponent portion)
N7:11 = 0000 0000 0110 1000b = 104d (actual binary exponent in excess-127 format)
N7:12 = -23d (actual binary exponent after normalizing the original decimal number)
We now have the binary exponent. Unfortunately, the mantissa uses 23 bits, which is too much information for a single 16-bit integer element. Depending on how we handled the data, we could use AT MOST only the most significant 16 bits of the mantissa, but we would lose precision without it necessarily being apparent. If we change the least significant 7 bits of the mantissa to 0, the original number becomes 2.0041443E-7. If this is accurate enough, we can proceed, using only one integer element for the mantissa:
We need bits 6 thru 0 of N7:1 and bits 15 thru 7 of N7:2 combined into a single element. Here goes:
CODE
MVM N7:1 007Fh N7:13
We'll want to shift this to the left 9 places so they are the most significant bits of our final element. If we just multiply by 2^9, we will cause overflow, so multiply by 2^8 and use a BSL:
CODE
MUL N7:13 256 N7:14
OTU R6:0/EN
BSL #N7:14 R6:0 B3:0/0 1
Now, we need to extract the next 9 bits of the original mantissa, which are bits 15 thru 7 of N7:2:
CODE
MVM N7:2 FE80h N7:15
This needs to be shifted to the right 7 places, so divide by 2^7:
CODE
DIV N7:15 128 N7:16
Gather the appropriate portions of N7;14 and N7:16 into our final mantissa:
CODE
MVM N7:14 FF80h N7:17
MVM N7:16 007Fh N7:17
N7:17 now contains the most significant 16 bits from the mantissa of the original floating point number.
Keep in mind, that this integer CANNOT be used "raw!" It must be interpreted using the IEEE standard and the exponent above. Remember that there is another "1" in front of these 16 bits AND that, if the first bit is a 1, the integer file will show a negative number that is NOT the same magnitude as its positive counterpart. SLCs store integers in 2's complement format, which uses the most significant bit as a sign bit. 2's complement is a bit involved to discuss here, but it's explained in Appendix F of Publication 1747-RM001E-EN-P. As a quick experiment, store "400" in an integer element using the datafile or a CDM. Change the radix to binary and set the sign bit. Change back to decimal, and it is -32368.
To make the final data simpler to handle, we can drop 2 bits, using only the 14 most significant bits of the mantissa. We will lose more precision, with our original number now 2.0040898E-7
If this is OK, modify the above code thus:
CODE
MVM N7:1 007Fh N7:13
MUL N7:13 128 N7:14
MVM N7:2 FE00h N7:15
DIV N7:15 512 N7:16
MVM N7:14 FF80h N7:17
MVM N7:16 007Fh N7:17
OTE N7:17/14
The last line of code sets bit 14. Recall that there is a one preceeding the "decimal" point that's implied in the IEEE format. The bit pattern in N7:17 is now the most significant 14 bits of the mantissa with the bit before the "decimal" point set. The sign bit is still not evaluated here.
I'm not sure how useful all of this is, though (not at all, yet). Now, we have a 15-bit mantissa that we may or may not be able to do anything with. Because of the complexity of the IEEE conversion, going back and forth between binary and decimal, I don't know that we can accomplish what you're asking easily. The exponent portion of the floating point number is the binary exponent, not the "-007" in our example, and there doesn't seem to be a simple way to extract it.
If you know where the decimal point will always be, in other words, if the number will always be x.xxE-7, you can simply:
CODE
MUL F8:0 10000000 F8:2
...and then do the string parsing from there.
BTW, the code here is a bit longer and uses more memory locations than really necessary, but I think it's clearer.
Bottom line: it may be "easier" to display the information on an HMI, maybe have the HMI do the printing. Is that an option?
Sorry for the disjointed post. I've run out of time for now, so I'll have to revisit this later. Or, someone else with better ideas may post. I've never really tried this, so it's been a learning experience for me, too!