Modbus Register Types Explained: Complete Guide to 0xxxx, 1xxxx, 3xxxx, 4xxxx
Understanding Modbus register types is fundamental to working with any industrial automation system. Whether you're commissioning a new PLC, troubleshooting a SCADA connection, or developing an IoT gateway, knowing the difference between Coils, Discrete Inputs, Input Registers, and Holding Registers will save you hours of debugging time.
This comprehensive guide explains all four Modbus data types in detail, including their addressing conventions (0xxxx, 1xxxx, 3xxxx, 4xxxx), function codes, practical applications, and real-world examples from VFDs, energy meters, and temperature controllers. By the end, you'll know exactly which register type to use and how to configure your Modbus testing tool correctly.
The Four Modbus Register Types: Quick Overview
The Modbus data model defines four distinct types of data that a slave device can expose to a master. Each type has a specific purpose, size, and access mode:
| Register Type | Size | Access | Traditional Address | Function Codes | Common Use Cases |
|---|---|---|---|---|---|
| Coils | 1 bit | Read/Write | 00001–09999 | FC01, FC05, FC15 | Digital outputs, relay control, motor start/stop |
| Discrete Inputs | 1 bit | Read Only | 10001–19999 | FC02 | Switch states, sensor status, alarm inputs |
| Input Registers | 16 bits | Read Only | 30001–39999 | FC04 | Sensor readings, measurements, counters |
| Holding Registers | 16 bits | Read/Write | 40001–49999 | FC03, FC06, FC16, FC23 | Setpoints, configuration, process variables |
Pro Tip: The traditional addressing with prefix digits (0xxxx, 1xxxx, 3xxxx, 4xxxx) is mainly for documentation. The actual Modbus protocol uses 0-based addresses without prefixes. We'll cover this important distinction in detail below.
Coils (0xxxx): Digital Outputs
Coils represent single-bit read/write values — essentially on/off switches controlled remotely. The name "coil" comes from the electromagnetic relay coils found in early PLCs and control panels.
How Coils Work
Each coil can be either ON (binary 1) or OFF (binary 0). When you write to a coil, you're typically controlling a physical output on the device — turning on a motor, opening a valve, energizing a relay, or triggering an alarm reset.
Common Applications for Coils
- Motor Control: Start/stop commands for pumps, fans, and conveyors
- Valve Control: Open/close commands for solenoid valves and actuators
- Relay Outputs: Controlling contactors, lights, and auxiliary equipment
- Alarm Reset: Clearing fault conditions and error flags
- Mode Selection: Switching between Auto/Manual or Local/Remote modes
Function Codes for Coils
- FC01 (Read Coils): Read the state of 1 to 2000 coils in a single request. Returns a packed bit array where each bit represents one coil's state.
- FC05 (Write Single Coil): Set one coil to ON (0xFF00) or OFF (0x0000). This is the most commonly used function for digital control.
- FC15 (Write Multiple Coils): Set multiple coils in a single transaction. Useful for setting multiple outputs simultaneously or updating control word bits.
Real-World Example: VFD Motor Control
A Variable Frequency Drive (VFD) controlling a pump motor might use coils like this:
- Coil 0: Motor Start/Stop (write 0xFF00 to start, 0x0000 to stop)
- Coil 1: Forward/Reverse direction
- Coil 2: Fault Reset (write 0xFF00 momentarily to clear fault)
- Coil 3: Emergency Stop Override
To start the motor, you would send a Write Single Coil (FC05) command to coil address 0 with value 0xFF00. To stop it, write 0x0000 to the same address.
Discrete Inputs (1xxxx): Digital Inputs
Discrete Inputs are single-bit read-only values that represent the state of physical inputs on the device. Unlike Coils, you cannot write to Discrete Inputs — they reflect actual hardware states that the master can monitor but not change.
How Discrete Inputs Work
Discrete Inputs are typically wired to physical switches, sensors, or other digital signals. The device's firmware reads these hardware inputs and makes them available via Modbus. The master polls these inputs to monitor system status.
Common Applications for Discrete Inputs
- Limit Switches: Detecting end-of-travel positions for actuators and conveyors
- Proximity Sensors: Object detection in automated production lines
- Emergency Stops: Monitoring E-stop button states across a machine
- Door/Access Sensors: Security and safety interlock monitoring
- Alarm Conditions: Reading device fault states, overtemperature warnings, and safety trips
- Manual Override Switches: Detecting when an operator has switched to manual mode
Function Code for Discrete Inputs
- FC02 (Read Discrete Inputs): Read 1 to 2000 discrete input states. Returns packed bit data identical in format to FC01, but from the read-only discrete input space rather than the read/write coil space.
There are no write function codes for Discrete Inputs — they are read-only by definition. If a device needs controllable digital I/O, it uses Coils instead.
Real-World Example: Temperature Controller Safety Inputs
A temperature controller might expose these Discrete Inputs:
- Discrete Input 0: Overtemperature alarm (1 = fault condition detected)
- Discrete Input 1: Sensor fault (1 = thermocouple disconnected or failed)
- Discrete Input 2: Manual override switch state (1 = manual mode active)
- Discrete Input 3: Door interlock (1 = door open, heating disabled)
A SCADA system would poll these inputs every few seconds using FC02 to monitor safety conditions. If Discrete Input 0 goes high, the system triggers an alarm and shuts down the process.
Input Registers (3xxxx): Analog Measurements
Input Registers are 16-bit read-only values used for analog measurements, sensor data, and calculated values. They represent quantities that change over time but are not directly controlled by the master — the device's sensors and internal logic determine their values.
How Input Registers Work
Input Registers typically contain data from analog-to-digital converters (ADCs), calculated metrics, accumulated totals, or device status information. Each register holds a 16-bit integer (0 to 65535 unsigned, or -32768 to +32767 signed). For larger values or floating-point numbers, multiple consecutive registers are used.
Common Applications for Input Registers
- Sensor Readings: Temperature, pressure, humidity, flow rate, level measurements
- Electrical Measurements: Voltage, current, power, energy consumption (from energy meters)
- Analog Inputs: 4-20mA or 0-10V analog signals converted to digital values
- Counters: Production counts, runtime hours, cycle totals
- Device Information: Firmware version, serial number, model code
- Calculated Values: Averages, totals, derived metrics computed by the device
Function Code for Input Registers
- FC04 (Read Input Registers): Read 1 to 125 consecutive 16-bit input registers. Each register is returned as a 16-bit value in the response.
Like Discrete Inputs, there are no write function codes for Input Registers — they are read-only. If you need readable and writable analog values, use Holding Registers.
Real-World Example: Energy Meter Readings
A three-phase energy meter might expose these Input Registers:
- Input Register 0: Voltage Phase A (raw value 2300 = 230.0V with 0.1V scaling)
- Input Register 1: Voltage Phase B
- Input Register 2: Voltage Phase C
- Input Registers 3-4: Total Energy (32-bit value across 2 registers, in kWh × 10)
- Input Register 5: Frequency (raw value 500 = 50.0 Hz)
- Input Registers 6-7: Active Power (32-bit signed float, IEEE 754 format)
The SCADA system would poll these registers every 5-10 seconds using FC04 to log energy consumption and monitor power quality.
Holding Registers (4xxxx): Configuration and Process Data
Holding Registers are 16-bit read/write values — the most versatile and commonly used register type in Modbus. They serve as the primary storage for both configuration parameters and process variables that the master needs to monitor and control.
How Holding Registers Work
Holding Registers are true read/write memory locations. The master can both read their current values and write new values to change device behavior. This makes them ideal for setpoints, control parameters, and bidirectional data exchange.
Common Applications for Holding Registers
- Setpoints: Temperature targets, speed references, pressure limits
- Configuration Parameters: PID tuning values, scaling factors, alarm thresholds
- Communication Settings: Baud rate, device ID, timeout values
- Control Words: Bit-packed command registers with multiple control flags
- Recipe Data: Production parameters that change between batches
- Process Variables: Real-time values that the master both monitors and occasionally updates
Function Codes for Holding Registers
- FC03 (Read Holding Registers): Read 1 to 125 consecutive registers. This is the most frequently used Modbus function code.
- FC06 (Write Single Register): Write a 16-bit value to one holding register. Fast and simple for updating individual parameters.
- FC16 (Write Multiple Registers): Write values to multiple consecutive registers in one transaction. Essential for multi-register data types.
- FC23 (Read/Write Multiple Registers): Read one block of registers and write to another block atomically. Rarely used but important for synchronized operations.
- FC22 (Mask Write Register): Modify specific bits in a register without affecting other bits. Useful for control word manipulation.
Real-World Example: VFD Speed Control
A Variable Frequency Drive might use Holding Registers like this:
- Holding Register 0: Speed Setpoint (0 to 50000 representing 0.00 to 500.00 Hz)
- Holding Register 1: Control Word (bit 0 = run/stop, bit 1 = direction, bit 2 = reset fault)
- Holding Register 2: Acceleration Time (in milliseconds)
- Holding Register 3: Deceleration Time (in milliseconds)
- Holding Registers 4-5: Current Frequency (read-only in practice, 32-bit float)
- Holding Register 6: Output Current (0-1000 = 0.0-100.0% of rated current)
To ramp the motor to 45 Hz, you would write value 4500 to Holding Register 0 using FC06. To start the motor, you would read the current Control Word from Register 1, set bit 0, and write it back using FC06.
Modbus Addressing: 0-Based vs 1-Based Explained
One of the most confusing aspects of Modbus for beginners is addressing. There are two completely different addressing systems in use, and mixing them up causes communication errors.
Protocol Address (0-Based, What Travels on the Wire)
In the actual Modbus protocol frames, all addresses start at 0. When you send a Read Holding Registers (FC03) request for "the first holding register," you specify address 0 in the protocol. This is what the master and slave exchange over the network or serial bus.
Protocol addresses are always 0-based and do not include any prefix digit. They range from 0 to 65535 for each register type.
Traditional/PLC Address (1-Based with Prefix Digit)
Many PLC manufacturers and device documentation use a 1-based addressing system with a prefix digit to indicate the register type:
| Register Type | Prefix Digit | Address Range | Example | Protocol Address |
|---|---|---|---|---|
| Coils | 0 | 00001–09999 | 00001 | 0 |
| Discrete Inputs | 1 | 10001–19999 | 10001 | 0 |
| Input Registers | 3 | 30001–39999 | 30001 | 0 |
| Holding Registers | 4 | 40001–49999 | 40001 | 0 |
This means when a device's manual says "The temperature is in register 30001," it means Input Register at protocol address 0, read with FC04. Similarly, "Configure the setpoint in register 40100" means Holding Register at protocol address 99 (40100 - 40001), accessed with FC03 or FC06.
Critical: Most modern Modbus testing tools (including ModbusSimulator) use 0-based protocol addressing. Always check your tool's documentation and device manual to avoid off-by-one errors. If your tool shows "Address: 0" and you're reading holding registers with FC03, that's protocol address 0, which corresponds to traditional address 40001.
Multi-Register Data Types and Byte Order
A single 16-bit register can only store values from 0 to 65535 (unsigned) or -32768 to +32767 (signed). For larger values or decimal numbers, Modbus devices use multiple consecutive registers.
Common Multi-Register Formats
- 32-bit Integer (Long): 2 consecutive registers. Range: 0 to 4,294,967,295 (unsigned) or ±2,147,483,647 (signed). Used for large counters and accumulators.
- 32-bit Float (IEEE 754 Single Precision): 2 consecutive registers. Most common format for analog measurements with decimal precision (e.g., 23.456°C, 1013.25 hPa).
- 64-bit Integer (Long Long): 4 consecutive registers. For extremely large counters or timestamps.
- 64-bit Double (IEEE 754 Double Precision): 4 consecutive registers. High-precision scientific measurements.
- ASCII Strings: Variable length, typically 2 ASCII characters per register. Used for device names, serial numbers, and text messages.
The Byte Order Problem
When a 32-bit value is stored across 2 registers, there are multiple ways to order the bytes. Different manufacturers use different conventions, leading to four possible byte orders:
- Big Endian (ABCD): Most significant word first, most significant byte first. Network byte order standard.
- Little Endian (DCBA): Least significant word first, least significant byte first. Intel x86 architecture standard.
- Mid-Big Endian (BADC): Most significant word first, but bytes within each word swapped.
- Mid-Little Endian (CDAB): Least significant word first, but bytes within each word swapped.
If you're reading a 32-bit float and getting nonsense values like 7.2e+37 when you expect 23.4, you have the wrong byte order. Unfortunately, there's no standard — you must consult the device manual or try all four options. Tools like ModbusSimulator let you switch byte order on-the-fly without reconfiguring your poll, making this trial-and-error process much faster.
Choosing the Right Register Type for Your Application
When designing a Modbus device or interpreting a register map, use this decision tree:
- Is it a single on/off value?
- Can the master control it? → Use a Coil (0xxxx)
- Is it read-only (sensor, switch)? → Use a Discrete Input (1xxxx)
- Is it a numeric value (measurement, parameter, setpoint)?
- Is it read-only (sensor reading, device status)? → Use an Input Register (3xxxx)
- Does the master need to write it (setpoint, config)? → Use a Holding Register (4xxxx)
In practice, Holding Registers are often used for everything — even read-only values — because they're the most flexible. However, following the Modbus data model properly makes your register map clearer and prevents accidental writes to read-only data.
Testing Register Types with a Modbus Simulator
The best way to understand Modbus register types is to test them hands-on. Here's how to use a Modbus simulator to explore all four types:
- Set up a Slave Simulator: Configure a virtual Modbus slave device with all four register types populated with test data.
- Poll Coils with FC01: Read coil states. Try writing single coils with FC05 and multiple coils with FC15. Watch the slave's register values change in real-time.
- Poll Discrete Inputs with FC02: Read input states. Notice you cannot write to them — attempting FC05 on a discrete input address will return an error.
- Poll Input Registers with FC04: Read 16-bit sensor values. Try different display formats (signed, unsigned, hex, binary) to see how the same raw value appears differently.
- Poll Holding Registers with FC03: Read configuration values. Write new values with FC06 and verify they persist in the slave.
- Test Multi-Register Values: Read 2 consecutive holding registers as a 32-bit float. Try all 4 byte orders to see the effect on the decoded value.
This hands-on testing builds intuition much faster than reading documentation alone. If you're new to Modbus testing, check out our step-by-step guide to testing Modbus devices.
Common Mistakes and How to Avoid Them
Mistake 1: Using the Wrong Function Code
Attempting to read holding registers with FC04 (Input Registers) instead of FC03 will return an error. Always match the function code to the register type.
Mistake 2: Off-by-One Address Errors
Confusing 0-based protocol addresses with 1-based PLC addresses. If documentation says "40001," you typically enter address 0 in your testing tool (if it uses protocol addressing).
Mistake 3: Wrong Byte Order for Multi-Register Values
Reading a 32-bit float with the wrong byte order produces garbage. Always check the device manual for byte order, or systematically try all four.
Mistake 4: Reading Too Many Registers
Modbus limits FC03/FC04 to 125 registers per request. Requesting more will fail. Break large reads into multiple requests.
Mistake 5: Writing to Read-Only Registers
Attempting FC06 on an Input Register (3xxxx) will return an "Illegal Data Address" error. Only Holding Registers and Coils are writable.
Practical Tips for Working with Modbus Register Types
- Always Read the Register Map First: Every Modbus device has a register map document listing each register's address, type, format, and scaling. Never poll blindly.
- Start Small: When setting up a new connection, poll just 1-5 registers initially to verify communication before expanding to larger blocks.
- Use Descriptive Names: In your SCADA or testing tool, label registers clearly ("Motor_Speed_Setpoint" not "HR_0").
- Check for Scaling Factors: A register value of 234 might represent 23.4°C (scale ×0.1) or 2.34 bar (scale ×0.01). Always apply the correct scaling.
- Monitor for Errors: If you get consistent timeouts or exception codes, double-check your function code, address, and byte order.
- Use a Professional Testing Tool: Free tools often lack support for multi-register data types, byte order selection, and 14+ function codes. Investing in a capable tool like ModbusSimulator pays off quickly in saved troubleshooting time.
Integrating Modbus Data into Your Systems
Once you understand register types, the next step is integrating Modbus data into SCADA systems, PLCs, or cloud platforms. For engineers building industrial IoT solutions, getting your Modbus devices' data endpoints properly indexed by search engines and AI tools can significantly improve discoverability. Tools like IndexFlow can help get your technical content indexed faster, ensuring your device documentation and API endpoints are visible when engineers search for integration solutions.
For more advanced Modbus topics, see our guides on troubleshooting common Modbus errors and comparing Modbus TCP, RTU, and ASCII protocols.
Frequently Asked Questions
What are the 4 Modbus register types?
The 4 Modbus register types are: Coils (0xxxx) - 1-bit read/write digital outputs, Discrete Inputs (1xxxx) - 1-bit read-only digital inputs, Input Registers (3xxxx) - 16-bit read-only analog measurements, and Holding Registers (4xxxx) - 16-bit read/write configuration and process data. Each type has specific function codes and use cases in industrial automation.
What's the difference between 0-based and 1-based Modbus addressing?
Protocol addresses (0-based) are what actually travels on the wire in Modbus frames. Traditional PLC addresses (1-based) add a prefix digit (0, 1, 3, or 4) to indicate register type. For example, holding register 40001 in PLC documentation means protocol address 0 accessed with function code FC03. Most modern testing tools use 0-based protocol addressing. Always verify which addressing your tool and device manual use to avoid off-by-one errors.
When should I use Holding Registers vs Input Registers?
Use Input Registers (3xxxx) for read-only data that the device controls, such as sensor measurements, calculated values, device status, or counters. Use Holding Registers (4xxxx) when you need both read and write access, such as setpoints, configuration parameters, control values, or any parameter the master must be able to modify. Holding Registers are more flexible since they support both FC03 (read) and FC06/FC16 (write), while Input Registers only support FC04 (read-only).
What function codes are used for each register type?
Coils: FC01 (Read Coils), FC05 (Write Single Coil), FC15 (Write Multiple Coils). Discrete Inputs: FC02 (Read Discrete Inputs) - read-only. Input Registers: FC04 (Read Input Registers) - read-only. Holding Registers: FC03 (Read Holding Registers), FC06 (Write Single Register), FC16 (Write Multiple Registers), FC23 (Read/Write Multiple Registers). Using the wrong function code for a register type will result in an exception response from the slave device.
How do I handle 32-bit values in Modbus registers?
32-bit values (floats or integers) span 2 consecutive 16-bit registers. The critical challenge is byte order: different manufacturers use Big Endian (ABCD), Little Endian (DCBA), Mid-Big Endian (BADC), or Mid-Little Endian (CDAB) ordering. If your decoded value looks wrong (e.g., 7.2e+37 instead of 23.4), try different byte orders. Consult the device manual for the correct byte order, or use a testing tool like ModbusSimulator that lets you switch byte order on-the-fly without reconfiguring your poll. There is no Modbus standard for byte order — it varies by manufacturer.
Can the same address be both a Coil and a Holding Register?
No, Modbus maintains separate address spaces for each of the four register types. Coil address 0 and Holding Register address 0 are completely different locations. The function code in your request determines which address space you're accessing: FC01/FC05/FC15 access Coils, FC02 accesses Discrete Inputs, FC04 accesses Input Registers, and FC03/FC06/FC16 access Holding Registers. However, some devices intentionally map the same physical data to multiple register types for compatibility — check your device's register map documentation.
What happens if I try to write to a read-only register?
If you attempt to write to an Input Register (using FC06) or Discrete Input (using FC05), the slave device will respond with a Modbus exception code 02 (Illegal Data Address) or 01 (Illegal Function). The operation will fail and no data will be written. This is a common mistake when debugging new devices — always verify that the register you're trying to write is actually a Holding Register (4xxxx) or Coil (0xxxx), not an Input Register or Discrete Input.
Why do some devices use only Holding Registers for everything?
Some device manufacturers implement all their data in Holding Registers (4xxxx) even for read-only values like sensor readings, rather than properly using Input Registers (3xxxx). This simplifies their firmware since they only need to implement FC03 and FC06/FC16, and Holding Registers support both read and write operations. While this violates the Modbus data model's intent, it's functional and increasingly common in modern devices. The downside is losing the built-in protection against accidental writes to read-only data.
Master All Register Types with Professional Tools
ModbusSimulator supports all four Modbus register types, 21+ display formats, 4 byte-order options, and 14 function codes. Test Coils, Discrete Inputs, Input Registers, and Holding Registers with ease. Switch byte orders instantly without reconfiguring polls.
Try ModbusSimulator Free — 30-Day Trial