How to Read Holding Registers (FC03): Step-by-Step
Holding registers are the read/write data locations in a Modbus slave — setpoints, configuration values, measured values you need to check. Function code 03 (FC03) is how a Modbus master reads them. This guide walks you through reading holding registers in QModMaster, register by register.
What QModMaster Needs to Read Holding Registers
QModMaster acts as the Modbus master (client). Before you can read anything, four fields in the main window have to match your slave device:
- Slave ID — the Modbus address of your device (1–247). Must match the device’s configured address.
- Function Code — set to 03: Read Holding Registers.
- Start Address — the first register you want to read. QModMaster uses 0-based addressing, so a device manual that says “register 40001” is entered as 0 here.
- Number of Points — how many consecutive registers to read in one request.
If the physical link isn’t up yet (RTU serial port or TCP connection), see our no-response timeout fix guide first.
Step-by-Step: Read 10 Holding Registers
Here is the complete walkthrough. It assumes your connection already works and your slave ID is 1.
- Select the interface. Serial (RTU) — choose the COM port, baud rate, parity, stop bits exactly as the device is configured. TCP — enter the device IP and port 502.
- Set Slave ID to 1 (or your device’s Modbus address).
- Set Function Code to 03: Read Holding Registers.
- Set Start Address to 0. This reads device register 40001 (first holding register) in 1-based notation.
- Set Number of Points to 10. QModMaster will request registers 0–9 (40001–40010 in 1-based notation).
- Click Connect / read — the values appear in the result grid, one row per register.
- Watch Bus Monitor if you want to see the actual request/response frames on the wire (Bus Monitor guide).
Interpreting the Values: Data Formats
Raw register values are 16-bit integers, but your device may be sending temperatures, floats, or bit fields. QModMaster lets you switch how the grid displays each value — hex, signed/unsigned int, float — so change the display format before assuming the data is wrong. A “weird” reading of 17223 might be a perfectly good value shown in the wrong format.
Troubleshooting: When the Read Fails
1. Values are shifted by one register
The most common FC03 issue. Device manuals usually number holding registers from 40001 (1-based), while QModMaster takes the 0-based offset. If your manual’s “40005” returns data for the wrong point, subtract 1: enter 4 in QModMaster. Full explanation in our register address offset guide.
2. Wrong Slave ID
No response at all — or a response to a different device on the bus — usually means the Slave ID field doesn’t match the device’s configured address. Double-check the device’s address setting (DIP switches, config menu, or manual).
3. Exception code 02 (Illegal Data Address)
The slave answered but refused the address — your Start Address / Number of Points range extends beyond the registers the device actually has. Shorten the range or move the start address. See our exception codes guide for the other codes you may see.
Frequently Asked Questions
Can I read holding registers while another program is using the port?
No — a serial port can only be opened by one program at a time on Windows. Close the other tool (or disconnect QModMaster) before retrying. On Linux, the same rule applies to the /dev/tty* device node.
Why do I get the same value in every register?
Often the device genuinely mirrors one value across a range, but first check the display format: a value shown in the wrong format can look “stuck.” Re-read with a different format selected before concluding the device is misbehaving.
How many registers can I read in one FC03 request?
Modbus limits an FC03 request to 125 registers. In practice, keep reads short (10–50) while debugging — large reads multiply the chance of crossing into an unmapped address and getting exception 02.
