A recipe object moves values only between tags of the same type, so passing whole numbers from a float tag to a 16-bit register needs the conversion done in PLC logic: round, clamp to 0 to 65535, latch a fault outside that range, and never map a float tag onto a single register, where 100.0 reads as 17096.
A recipe object on an HMI panel moves values only between tags of the same data type. When your process values live in 32-bit float tags in the PLC and the recipe fields on the panel are 16-bit unsigned integer words, the panel will not cast between the two formats. Pointing a float tag at a single integer register produces garbage instead of a number. The conversion belongs in PLC logic: round, clamp to the unsigned 16-bit range of 0 to 65535, latch a fault outside it, and bind the recipe to the 16-bit word. This article walks the failure modes, the ladder-side fix, a worked example at 100 seconds, the edge tests, and the two data paths that remove the conversion altogether.
Why can't the recipe object move a float into a 16-bit register?
A recipe object copies values between tags of the same type and performs no arithmetic. A 32-bit float and an unsigned 16-bit word share no bit-level relationship. Your PLC logic must supply the round, range-check and write.
A recipe field binds to one tag and copies that tag's value out and back. The two formats store numbers differently. An unsigned 16-bit word is a plain binary magnitude from 0 to 65535. A single-precision float packs a sign bit, an 8-bit exponent and a 23-bit fraction into 32 bits. No bit in one pattern stands for a digit in the other, so a transfer needs real arithmetic: round or truncate, range-check, then write.
Two limits shape that arithmetic. Range: the word holds nothing negative and nothing above 65535, so the PLC must clamp or flag those cases. Precision: a float32 holds every whole number exactly up to 16,777,216, because its 23 stored fraction bits carry 24 bits of precision, so whole-number process values inside that span lose nothing as float.
Build the PLC-side cast now and check the release notes of your installed panel software later for a built-in type conversion. A feature request does not put a line back in production.
What happens if I map a float tag onto a single 16-bit register?
You get half of the two-word IEEE 754 bit pattern, never the number. 100.0 is stored as 0x42C80000, so a single-word read returns 17096 from the high word or 0 from the low word while the float changes underneath.
A single-precision float occupies two adjacent 16-bit registers. A panel that reads one of them gets a slice of the encoding, and the slice shifts with the mantissa bits as the process value drifts. Overlaying an integer tag on the float's address reinterprets the same bits, so the displayed number swings across the word range while the float moves by a fraction of a unit.
Use a known value to confirm any two-register link before trusting it. 1.0 encodes as 0x3F800000, so the high word reads 16256 and the low word reads 0. If your panel or gateway shows that pair, you are looking at raw halves of the float. The layout is covered step by step in how to display a PLC float stored in two word registers on an HMI.
Which symptom points to which data-type fault?
Each failure mode names its own cause. 17096 for a value near 100 means a half-word read. A value that goes negative above 32767 means signed interpretation of an unsigned word. Values that swing as the float moves mean two tags overlaying one address.
- 17096 for a value near 100, or 16256 for 1.0. The panel is reading one word of the float's two-register encoding. Repair the mapping; the whole number was never in the word.
- Correct up to 32767, negative above it. The tag is being read as signed. A word holding 40000 displays as 40000 - 65536 = -25536; set the number format to unsigned or convert in the PLC.
- A large positive number that matches no scaling. The tag's number format does not match the data behind it; set the signed decimal data format covers that case in detail.
- A value that swings wildly while the float drifts slightly. An integer tag overlays the float's address and reinterprets its bits.
- A register that stays untouched after a conversion run. The convert instruction never executed; check the enable condition first, the same first check used when a real-to-BCD conversion writes nothing.
How do I convert a recipe float to a 16-bit word in PLC logic?
Round the float first, clamp it to the unsigned 16-bit range of 0 to 65535, latch a fault outside that range, hold the last valid word, and write only the clamped result to the word the recipe object binds to.
You need a float working tag in the PLC, a 16-bit unsigned recipe word, a fault bit, and the panel recipe bound to that word alone.
- Download, word to float. Convert the unsigned word to a real with the PLC's integer-to-real instruction, treating the word as unsigned. A signed conversion turns any value above 32767 negative.
- Upload, float to word. Add 0.5 before converting if a fractional part can appear, convert to integer, then range-check: below 0 or above 65535 sets the fault and leaves the last valid word in place.
- Latch and show the fault. Wire the fault bit to a panel alarm or indicator so a rejected recipe value is visible and the operator reloads. A wrapped or truncated value must never reach the machine as a setpoint; holding the last valid word and raising the alarm is the safe behavior.
- Check the rounding. Confirm in the PLC manual whether the real-to-integer instruction rounds or truncates. Adding 0.5 before a truncating convert gives round-to-nearest; skip the add when the instruction already rounds.
- Bound the typed values too. The same clamp-in-ladder pattern for panel numeric entry is set out in clamping numeric entry limits in PLC ladder logic.
Worked example: what does 100.0 become on each data path?
Mapped raw, 100.0 sits in two words as 0x42C80000 and its high word alone reads 17096, which is 16384 + 512 + 192 + 8. Converted in the PLC, 100.0 + 0.5 = 100.5 truncates to 100, and the word reads exactly 100.
A baking line stores a mix time of 100 seconds as a float tag, and the panel recipe field is one unsigned 16-bit word.
| Path | What happens | Result |
|---|---|---|
| Float tag mapped to one register | 100.0 encodes as 0x42C80000; high word = 0x42C8 = 16384 + 512 + 192 + 8 | 17096, garbage |
| Integer tag overlaying the float address | the same bits are reinterpreted while the float drifts between 99.9 and 100.1 seconds | the display swings across the word range |
| PLC conversion, upload | 100.0 + 0.5 = 100.5, truncate = 100; 100 is within 0 to 65535, so the word is written | word reads 100, fault off |
| PLC conversion, download | integer-to-real on the word 100 | float tag reads 100.0 |
The same run at the edges: 0 converts to word 0; 65535 stays 65535; 65536 fails the range check, so the fault latches and the word holds its last valid value; -1.0 seconds fails below zero the same way. A field typed as 12.5 becomes 12.5 + 0.5 = 13.0, truncate = 13.
Which tests check the conversion before the line runs?
Write each edge value from the panel and read the PLC tag, the recipe word and the fault bit back: 0 returns 0, 100 returns 100, 65535 returns 65535, while 65536 and -1 latch the fault and hold the last valid word.
| Panel write | Recipe word | Fault bit |
|---|---|---|
| 0 | 0 | off |
| 1 | 1 | off |
| 100 | 100; 17096 here means the half-word read is back | off |
| 65535 | 65535 | off |
| 65536 | last valid value | on |
| -1 | last valid value | on |
| 12.5 | 13 | off |
Then round-trip a full recipe: load it to the PLC, upload it back, and compare every field with the source. A field that returns shifted by a fixed offset points to word order in a two-register type. A large odd number points to signedness. Both are mapping faults, and both are caught here, before production.
When is a 32-bit integer or a fixed-point scale the better path?
Move the whole path to 32-bit integers when values exceed 65535 and the tag list offers the type; a float32 holds every whole number up to 16,777,216 exactly. Scale by 10 when one decimal matters, resolution 0.1 units, and a span of 0 to 6553.5 covers your largest value.
Pick the data path before editing the panel:
| Path | Use when | Cost |
|---|---|---|
| 32-bit integer end to end | values are whole numbers above 65535 and the tag list offers a 32-bit type | match the word order of the two-register type |
| Float in the PLC, 16-bit word in the recipe, PLC converts | values fit 0 to 65535 and the panel accepts integer tags only | conversion and clamp logic in both directions |
| Fixed point, scaled by 10, in one word | one decimal matters and the span stays within 0 to 6553.5 | resolution locked at 0.1 units |
| High and low words split across two registers | values exceed 65535 with no 32-bit tag type available | the panel shows two tags and the PLC recombines them |
Verify any two-register link with the known value 1.0, which encodes as 0x3F800000. A high word of 16256 confirms the order you assumed, and a low word of 16256 means the registers are swapped. Converting a CODESYS REAL into two Modbus WORD registers walks that word-order check step by step. For the screen side of these panels, the shop-floor screens category collects the other register and display fixes.
Recommendation: Keep the recipe on the 16-bit unsigned word with the conversion in PLC logic when your values are whole numbers that fit 0 to 65535. Move the whole path to 32-bit integers when any value exceeds 65535 and the tag list offers the type. Use a scale factor of 10 when a field needs one decimal place, resolution 0.1 units, and 6553.5 covers its largest value.
Questions
Does a 32-bit float hold whole numbers above 65535 exactly?
Yes. Single precision stores 23 fraction bits, which carry 24 bits of precision, so every whole number up to 16,777,216 is exact. That is why a 32-bit integer tag is a lossless substitute for whole-number recipe values, provided the panel tag list and the PLC both offer a 32-bit type and you verify the word order with a known value such as 1.0.
What does 40000 look like if the word is read as signed?
A signed 16-bit interpretation maps 32768 to 65535 onto negative numbers: 40000 reads as 40000 - 65536 = -25536. Set the tag's number format to unsigned where the panel offers the choice, or convert in the PLC with the word treated as unsigned, so values between 32768 and 65535 keep their magnitude.
How much range does a scale factor of 10 or 100 leave in one word?
A factor of 10 keeps one decimal place, resolution 0.1 units, with a span of 0 to 6553.5. A factor of 100 keeps two places, resolution 0.01 units, with a span of 0 to 655.35. Choose the factor from the largest value any recipe field can take, because the scaled integer must stay within 0 to 65535.
What if the tag type the recipe needs is not in the list?
That is a software capability question for the panel maker. Check the release notes and user manual for the installed software version first; if the type is still absent, contact the maker's support with the software version, the panel model and the PLC driver in use, and run the PLC-side conversion in the meantime so the project is not blocked.
Planning information, not legal or engineering advice. Rules differ by place: check codes and permits with your local authority and your licensed trades.