How to Convert 64-Bit Modbus Floating-Point Totalizers to 32-Bit REAL in STEP 7 and PCS 7
In SIMATIC STEP 7 and PCS 7, the CPU architecture natively supports only 32-bit single-precision floating-point numbers (IEEE 754 REAL). When field totalizers or power meters transmit 64-bit double-precision floating-point values over Modbus (four 16-bit registers, mapped into two 32-bit DWORDs), the controller cannot process them directly. To handle this, create a custom conversion function in Statement List (STL) or Structured Control Language (SCL) that unpacks the 64-bit IEEE 754 format (1 sign bit, 11 exponent bits, and 52 mantissa bits), re-biases the exponent, truncates the lower mantissa, and reassembles a standard 32-bit REAL value.
Table of Contents
- IEEE 754 Floating-Point Formats: 64-Bit Double vs 32-Bit Single Precision
- Bit-Level Conversion Architecture: Mapping 64-Bit to 32-Bit REAL
- STL and SCL Implementation of the Conversion Function
- Testing and Debugging Functions in SIMATIC Manager and CFC
- Locating Modbus Mapping Tables and Register Boundaries
- Comparison of IEEE 754 Floating-Point Bit Allocation
- Verification
- Limitations and Operational Precautions
- Engineer FAQ
- Technical References
- Related Articles
- Related Tags
IEEE 754 Floating-Point Formats: 64-Bit Double vs 32-Bit Single Precision
Process flowmeters, energy totalizers, and batch weighing transmitters frequently report totalized cumulative values as 64-bit IEEE 754 double-precision floating-point numbers. This ensures high precision over decades of cumulative accumulation without rounding errors.
However, classic SIMATIC S7-400 and CPU 410-5H controllers operate with 32-bit accumulator registers:
* In standard STEP 7, the data type REAL is strictly a 32-bit single-precision floating-point value conforming to IEEE 754.
* If a 64-bit Modbus value is read across four 16-bit registers (two 32-bit DWORDs: High and Low) and an engineer naively treats the upper DWORD as a 32-bit REAL, the resulting number will be completely corrupted.
* The upper 32 bits contain the 1-bit sign, an 11-bit exponent (biased by 1023), and only the upper 20 bits of the mantissa. In contrast, a 32-bit REAL expects a 1-bit sign, an 8-bit exponent (biased by 127), and 23 bits of mantissa.
Bit-Level Conversion Architecture: Mapping 64-Bit to 32-Bit REAL
To convert a 64-bit double to a 32-bit float without external hardware converters:
- Extract Sign Bit:
* The sign bit is located at bit 63 (bit 31 of the High DWORD). Mask withDW#16#80000000and store. - Extract and Re-bias Exponent:
* In 64-bit: Exponent occupies bits 62 to 52 (11 bits) with bias 1023.
* Mask High DWORD withDW#16#7FF00000, shift right by 20 bits.
* Re-bias: Subtract(1023 - 127) = 896.
* Check range: If the exponent is<= 0, underflow occurs (result is zero). If the exponent> 255, overflow occurs (result is Infinity or maximum REAL3.402823e+38).
* Shift re-biased 8-bit exponent left by 23 bits into the standard 32-bit REAL exponent position. - Assemble Mantissa:
* Extract upper 20 mantissa bits from the High DWORD (High AND 16#000FFFFF), shift left by 3 bits.
* Extract top 3 mantissa bits from the Low DWORD (Low AND 16#E0000000), shift right by 29 bits.
* Bitwise OR the sign, exponent, and mantissa components together to produce the final 32-bit REAL.
STL and SCL Implementation of the Conversion Function
Below is the optimized Statement List (STL) implementation of function FC1500 ("R64_to_32"):
FUNCTION "R64_to_32" : VOID
TITLE = 'Convert IEEE 754 64-bit Double to 32-bit REAL'
VERSION : 0.1
VAR_INPUT
arg_High : DWORD ; // Upper 32 bits (Sign + 11-bit Exponent + 20-bit Mantissa)
arg_Low : DWORD ; // Lower 32 bits (Lower 32 bits of Mantissa)
END_VAR
VAR_OUTPUT
res : REAL ; // Converted 32-bit IEEE 754 Float
END_VAR
BEGIN
NETWORK
TITLE = Bit-level conversion algorithm
L #arg_High;
L DW#16#80000000; // Mask Sign Bit
AD ;
T #res;
L #arg_High;
L DW#16#7FF00000; // Mask 11-bit Exponent
AD ;
SRD 20;
L 896; // Exponent bias correction (1023 - 127)
-I ;
L 0;
<=I ; // Underflow check
JC zero;
TAK ;
SLD 23;
L #res;
OD ;
T #res;
L #arg_High;
L DW#16#000FFFFF; // Mask Upper 20-bit Mantissa
AD ;
SLD 3;
L #res;
OD ;
T #res;
L #arg_Low;
SRD 29; // Top 3 bits from Low Mantissa
L #res;
OD ;
T #res;
BEU ;
zero: L 0.0;
T #res;
END_FUNCTION
In SCL, a user-defined type (UDT) with AT overlays can achieve the same mathematical conversion.
Testing and Debugging Functions in SIMATIC Manager and CFC
To test and validate the conversion block before applying it to live plant instrumentation:
- Create a Variable Table (VAT):
* In SIMATIC Manager, selectBlocks > Insert New Object > Variable Table.
* Add memory test addresses:MD100(Hex format, test input High),MD104(Hex format, test input Low), andMD108(Floating-Point format, test output). - Execute Test Cases:
* Test Value1.0: In 64-bit IEEE 754,1.0is represented asHigh = 16#3FF00000,Low = 16#00000000. Writing these values toMD100andMD104must return1.0inMD108.
* Test Value123456.78:High = 16#40FE240C,Low = 16#4EC4EC4F. The output must read123456.78(with slight 32-bit mantissa precision truncation). - CFC Test Mode:
* InsertFC1500into a test CFC chart.
* Switch CFC to Test Mode (Debug > Test Mode) and enable Watch mode on the block outputs to verify live conversions in real time.
Locating Modbus Mapping Tables and Register Boundaries
When inheriting an unfamiliar PCS 7 project communicating via Modbus RTU (CP 341, CP 441) or Modbus TCP (CP 443-1, integrated PN port):
* Identify the Communication Block: Open the CFC charts and locate the active Modbus driver blocks: MODB_400 (Modbus Master/Slave for CP 441), MB_REDCL (Redundant Modbus TCP), or MODBUS_PN.
* Inspect Data Block Pointers: Look at the block parameters DB_NO (Data Block Number) and START_ADDR (Starting register address).
* Open the Target Data Block: In SIMATIC Manager, open the DB specified by DB_NO. The Modbus register map is laid out in sequence: each Modbus holding register (40001 series) occupies 1 WORD (2 bytes). A 64-bit float occupies 4 consecutive words (8 bytes).
* Word Swapping (Endianness): Modbus devices differ in register order (Big-Endian vs Little-Endian word swapping). If converted values appear erratic, swap the order of the High and Low words.
Comparison of IEEE 754 Floating-Point Bit Allocation
The table below outlines the architectural differences between 64-bit double-precision and 32-bit single-precision floating-point formats.
1023127+R, -R, *R)Verification
To confirm proper conversion and integration of Modbus totalizers:
1. Compare the live totalizer value displayed on the physical flowmeter LCD with the converted 32-bit REAL output in the PCS 7 CFC chart.
2. Confirm that as the physical flowmeter accumulates volume, the converted 32-bit REAL increments monotonically without sudden numeric rollover or sign flips.
3. Test zero and negative flow scenarios to verify sign bit handling.
4. Verify that the converted REAL feeds cleanly into APL totalizer blocks (TotalL) or analog monitoring blocks (MonAnL) with valid quality status.
Limitations and Operational Precautions
- Converting 64-bit floating-point numbers to 32-bit REAL inherently truncates mantissa precision from 53 bits (~16 decimal digits) down to 24 bits (~7 decimal digits); extremely large cumulative totals will experience rounding of small fractional additions.
- Values exceeding
3.402823e+38will overflow 32-bit REAL limits, causing mathematical faults in the CPU. - Always verify Modbus byte-swapping (endianness) settings; mismatched word order within the 64-bit register block will produce invalid calculations.
- Do not call complex conversion functions in high-frequency cyclic OBs (such as OB38 @ 10ms) if dealing with dozens of Modbus devices; execute them in slower cyclic tasks (e.g., OB32 @ 1s).
Engineer FAQ
Why does STEP 7 not support 64-bit LREAL natively on S7-400?
The classic SIMATIC S7-300 and S7-400 processor architectures feature 32-bit accumulator registers (ACCU1 and ACCU2). Native 64-bit floating-point arithmetic (LREAL) was only introduced in modern S7-1500 CPUs. S7-400 and CPU 410 systems must use custom 32-bit conversion routines or integer scaling.
What happens when an accumulator totalizer exceeds 7 significant digits in 32-bit REAL?
Once a 32-bit REAL number grows very large (e.g., above 16,777,216.0), the least significant bits of the mantissa represent increments larger than 1.0. Adding small flow increments will no longer change the totalized sum. In such cases, totalizers should be split into High and Low integer counters or reset cyclically.
How do I identify whether a Modbus device uses Big-Endian or Little-Endian word order?
Check the manufacturer documentation for the term 'Modbus Byte Order' or 'Word Swap'. Alternatively, read a known constant (such as 1.0) from the device and observe the raw hex bytes in a Variable Table. If 16#3FF00000 appears in the second DWORD instead of the first, enable word swapping.
Technical References
- SIMATIC S7-300/400 Statement List (STL) for S7-300 and S7-400 Programming Manual
- Siemens Industry Online Support FAQ: Modbus Communication and Data Conversions in PCS 7
Related Articles
- Integrating Third-Party Modbus RTU and TCP Devices into SIMATIC PCS 7
- Handling Floating-Point Precision Loss in High-Volume Totalizers
- Debugging STEP 7 Statement List (STL) Blocks with Variable Tables
Related Tags
- Modbus
- IEEE 754
- STEP 7
- STL Programming
- Totalizer