Read a Modbus RTU float from a temperature controller

5 min read · Published November 14, 2026

One function-03 request for two registers, 40360 and 40361, returns the 32-bit IEEE-754 process value. Decode it high word first, compare it against the controller's own display, and swap the word order if the number is absurd. The fields, the arithmetic and the checks are below.

Read a floating-point process value from a Modbus RTU temperature controller with one function-03 request for two holding registers, 40360 and 40361, and decode the two 16-bit words as a single 32-bit IEEE-754 number. Modbus defines no floating-point type, so word order inside the pair is the one thing the wire leaves open. Prove it against the controller's own display and the read is finished. Below are the fields to program, the decode arithmetic with real numbers, and the checks that tell a wrong register from a wrong word order.

What you need

  • The controller's Modbus register map for the exact model. In the map used here, the process input is register 360, a 32-bit float, and the master reaches it at holding register 40360.
  • A PLC serial port you can configure as a Modbus RTU master, plus a two-wire RS-485 link wired A to A and B to B, shield landed at one end only.
  • The controller's communication settings as configured: slave address, baud rate, parity, stop bits. Read them from its menu and write them down before touching the PLC.
  • Two consecutive words in PLC memory reserved for this value alone, and one more word for the transaction status.

Work on the link with the process idle, because a wrong value reaching control logic can drive an output the wrong way.

The controller's slave address must sit between 1 and 247; address 0 is broadcast and answers nobody. The Modbus over-serial specification default is 19200 baud, 8 data bits, even parity, 1 stop bit, and many controllers ship at 9600 baud with no parity instead, so the controller's menu wins over any default. Only one master polls an RS-485 bus; two Modbus RTU masters on one RS-485 bus describes what happens when a second one appears.

Program the read

  1. Configure the PLC port as a Modbus RTU master and enter the four serial settings you copied from the controller.
  2. Enter the controller's slave address.
  3. Program one read: function code 03, Read Holding Registers, start address 40360, quantity 2. Both words come back in one response, from one controller scan, as a matched pair.
  4. Point the destination at your two reserved words. Two elements fill them exactly.
  5. Give this transaction its own status word, so a second instruction never overwrites its exception response.
  6. Poll once per second. A temperature loop moves slowly, and faster polling only fills the error log when the link is marginal.

The 4 in 40360 marks the holding-register table. It is not a function code; why a 4xxxx register is not Modbus function code 04 explains that numbering convention.

Decode the two words

Modbus defines no floating-point type. The accepted convention packs an IEEE-754 single-precision number into two consecutive registers: 32 bits split into two 16-bit words, sent as four bytes, high byte of each word first. What the convention leaves open is placement: some controllers put the high word in the lower register, some the reverse. Your master or PLC has a word-swap or float-assembly instruction for exactly this. The swap lives in the reader; a byte-order setting changes the screen, not the wire, and the same holds for your PLC decode. Writing a float back, a setpoint for instance, packs the same two registers in the opposite direction, and converting a CODESYS REAL into two Modbus WORD registers shows that packing.

Example: 425.0 °C from two words

The controller face reads 425.0 °C. The master returns 17364 in register 40360 and 32768 in register 40361.

  • 17364 decimal is 0x43D4, and 32768 decimal is 0x8000.
  • High word first, the pair forms 0x43D48000. Sign bit 0. Exponent field 10000111 binary is 135, minus the 127 bias leaves 2^8. Fraction 1.10101001 binary is 1.66015625. Then 1.66015625 x 256 = 425.0. The decode matches the face.
  • Swapped, 0x800043D4 has sign bit 1 and exponent 0, and decodes to about -2.4E-41. No temperature face prints that, so this controller sends the high word in the lower register. Write the setting on the commissioning sheet.

One read gave the answer because the two candidate orders produce wildly different numbers. That is the whole test.

How to check it worked

When the read fails, the response names its layer. The Modbus application protocol defines the frames, so compare your captured bytes against that specification:

  • No response at all: slave address, baud rate, parity, wiring, or A and B swapped at one end. Fix one thing, read again.
  • Exception response 131, which is 0x83, function 03 with its high bit set, carrying code 02, illegal data address: the controller says that number sits outside its map. Wrong map for the model, or a master that counts the first holding register as 0, in which case the map's 360 is entered as 359.
  • Exception code 01, illegal function: the value lives in a table function 03 cannot reach. Check the map for an input-register listing, served by function 04, or for a communication option that differs on this model.
  • Clean reads, absurd number: word order. Back to the example section.

The decision for each case

  • Link answers and the decode matches at two points 100 °C apart: accept it, record the word order, done.
  • Link answers with exception 02: move the start address by one register, then question the map. One change per test.
  • Link answers with a nonsense value: swap the word order in the decode, test once, record the result.
  • Link silent: stop at the serial layer and work address, settings, wiring, in that order. A word-order change cannot repair a request the controller never receives.

Recommendation: Program one function-03 read of registers 40360 and 40361 in a single request, decode high word first, and accept the link when the PLC value equals the controller face at two points at least 100 °C apart with zero exceptions over 60 reads. If your controller's map prints a different register for the process input, keep every step and change only the start address.

Questions

Can I read registers 40360 and 40361 with two separate requests?

You can, but send one request for two registers instead. Two single-register reads can straddle the controller's update, so one word comes from one scan and the other from the next, and the pair decodes to nonsense. One function-03 read of two registers returns a matched pair from a single scan. The Modbus application protocol allows up to 125 registers per function-03 request, so several floats can ride in the same read.

The response is exception 0x83 with code 02. What is wrong?

Code 02 is illegal data address: the controller says that register number sits outside its map. Three usual causes: the map belongs to another model, the value lives at a different register, or your master counts the first holding register as 0, so the map's 360 must be entered as 359. Change the start address by one, read again, and only then go back to the map.

Does byte order inside each register matter too?

No. Modbus RTU always sends the high byte of each 16-bit register first, on every device, and no setting changes that. The only variation between controllers is which of the two registers holds the high word of the float, and your decode's swap setting handles that. Fix the word order and leave byte order alone.

Planning information, not legal or engineering advice. Rules differ by place: check codes and permits with your local authority and your licensed trades.

Keep reading

Build your signAsk for a quote