Modbus Function Codes

Function Codes: The Commands of Modbus Protocol

Imagine you’re speaking to a factory worker who only understands a specific set of verbs. To get them to do something, you have to use one of these predefined action words—no synonyms allowed. If you want them to check a machine, you say “inspect.” If you want them to adjust a setting, you say “configure.” If you want them to report a measurement, you say “read.”

This is exactly how Modbus function codes work. They are the “action verbs” of the Modbus language, telling devices exactly what to do. Each function code is a standardized command that every Modbus device understands, regardless of who made it.

The Modbus Language: Grammar of Communication

| Language Component | Modbus Component | Example |

|————————|———————-|————-|

| Speaker | Modbus Master | A PLC controller |

| Listener | Modbus Slave | A temperature sensor |

| Verb | Function Code | Read Holding Registers (03) |

| Noun | Data Address | Register 40001 |

| Object | Data Value | 2500 (representing 25.0°C) |

| Sentence | Modbus Message | “Read register 40001 from slave 5” |

Function Code Categories: Types of Verbs

Modbus function codes fall into three main categories, each serving a different purpose:

1. Read Operations: Information-Gathering Verbs

These function codes are like asking questions—they retrieve information from devices without changing anything. Think of them as “observation verbs.”

#### 01: Read Coils – “Check the Status of These Switches”

What it does: Reads the status of multiple coils (on/off values) from a slave device.

Data Type: Coils (read-write switches)

Example: A PLC uses function code 01 to check if motors 1-8 are running. It requests coils 00001-00008 from slave device 5.

Message Structure: “Slave 5, please check the status of coils 00001 through 00008 and tell me which ones are on.”

#### 02: Read Discrete Inputs – “Read These Sensor Values”

What it does: Reads the status of multiple discrete inputs (read-only switches) from a slave device.

Data Type: Discrete Inputs (read-only switches)

Example: A SCADA system uses function code 02 to monitor safety sensors on a production line. It reads discrete inputs 00001-00016 from slave device 12.

Message Structure: “Slave 12, please report the current status of your safety sensors (discrete inputs 00001-00016).”

#### 03: Read Holding Registers – “Get These Settings or Measurements”

What it does: Reads the value of multiple holding registers (read-write numeric values) from a slave device.

Data Type: Holding Registers (read-write numbers)

Example: A building management system uses function code 03 to get temperature setpoints from a HVAC controller. It reads holding registers 40001-40004 from slave device 3.

Message Structure: “Slave 3, please send me the current temperature setpoints stored in registers 40001 through 40004.”

#### 04: Read Input Registers – “Fetch These Sensor Readings”

What it does: Reads the value of multiple input registers (read-only numeric values) from a slave device.

Data Type: Input Registers (read-only numbers)

Example: A water treatment plant uses function code 04 to monitor water quality sensors. It reads input registers 30001-30003 (pH, turbidity, temperature) from slave device 8.

Message Structure: “Slave 8, please send me the latest water quality readings from your input registers 30001-30003.”

2. Write Operations: Action Verbs

These function codes actually change something in the device—like flipping a switch or adjusting a setting. They’re the “command verbs” of Modbus.

#### 05: Write Single Coil – “Turn This Switch On/Off”

What it does: Sets the value of a single coil (on/off) in a slave device.

Data Type: Coil (read-write switch)

Example: A PLC uses function code 05 to turn on a cooling fan when a temperature exceeds a threshold. It writes a value of 1 (on) to coil 00010 in slave device 6.

Message Structure: “Slave 6, please turn on the cooling fan by setting coil 00010 to 1.”

#### 06: Write Single Register – “Set This Value”

What it does: Sets the value of a single holding register in a slave device.

Data Type: Holding Register (read-write number)

Example: An operator adjusts the pressure setpoint for a pump from a human-machine interface (HMI). The HMI uses function code 06 to write 850 (85.0 PSI) to register 40005 in slave device 10.

Message Structure: “Slave 10, please set the pressure setpoint in register 40005 to 850.”

#### 15: Write Multiple Coils – “Turn These Switches On/Off”

What it does: Sets the value of multiple coils (on/off) in a slave device with a single command.

Data Type: Coils (read-write switches)

Example: At the end of a shift, a supervisor uses a control panel to turn off all lights in a factory section. The panel uses function code 15 to write 0s to coils 00020-00035 in slave device 2.

Message Structure: “Slave 2, please turn off all lights by setting coils 00020 through 00035 to 0.”

#### 16: Write Multiple Registers – “Set These Values”

What it does: Sets the value of multiple holding registers in a slave device with a single command.

Data Type: Holding Registers (read-write numbers)

Example: A recipe management system downloads a new product recipe to a batch controller. It uses function code 16 to write 12 different parameters (temperatures, times, speeds) to registers 40100-40111 in slave device 15.

Message Structure: “Slave 15, please load this recipe by setting registers 40100 through 40111 to the following values: [1800, 3600, 50, …].”

3. Diagnostic Operations: Maintenance Verbs

These function codes help maintain and troubleshoot Modbus networks. Think of them as “maintenance verbs.”

#### 08: Diagnostic – “Run This Test”

What it does: Performs diagnostic tests on a slave device.

Common Sub-Functions:

  • 0002: Return Diagnostic Register

Example: A technician uses function code 08 with sub-function 0000 to test communication with a problematic device. The slave should echo back the test data.

Message Structure: “Slave 7, please run a communication test by echoing back this data: [01 02 03 04].”

#### 17: Report Slave ID – “Tell Me About Yourself”

What it does: Retrieves identification information from a slave device.

Example: A network scanner uses function code 17 to inventory devices on a Modbus network. Each slave returns its model number, firmware version, and other identifying information.

Message Structure: “Slave 4, please send me your identification information.”

Visualizing Function Codes: A Simple Map

“`

┌─────────────────────────────────┐

│ MODBUS VERBS │

├───────────────┬─────────────────┼───────────────────┤

│ READ │ WRITE │ DIAGNOSTIC │

│ OPERATIONS │ OPERATIONS │ OPERATIONS │

├───────────────┼─────────────────┼───────────────────┤

│ 01: Read Coils│ 05: Write Single│ 08: Diagnostic │

│ 02: Read │ Coil │ 17: Report Slave │

│ Discrete │ 06: Write Single│ ID │

│ Inputs │ Register │ … and more │

│ 03: Read │ 15: Write │ │

│ Holding │ Multiple │ │

│ Registers │ Coils │ │

│ 04: Read │ 16: Write │ │

│ Input │ Multiple │ │

│ Registers │ Registers │ │

└───────────────┴─────────────────┴───────────────────┘

“`

How Function Codes Work in Practice: A Real-World Example

Let’s walk through a complete Modbus conversation between a PLC (master) and a temperature controller (slave) using function codes:

Scenario: A temperature control loop for a heating oven

1. Master (PLC) sends a read request: Uses function code 04 to read the current oven temperature from input register 30001 in slave device 5.

“`

Message: [05] [04] [00] [00] [00] [01] [41] [C8]

Breakdown: Slave 5, Read Input Registers, Start at 30001, Read 1 register

“`

2. Slave (Temperature Controller) responds: Returns the current temperature (2250 = 22.5°C).

“`

Response: [05] [04] [02] [08] [CA] [91] [D3]

Breakdown: Slave 5, Read Input Registers Response, 2 bytes of data, Value = 2250

“`

3. Master decides to adjust the setpoint: Compares the current temperature (22.5°C) with the desired setpoint (25.0°C). Uses function code 06 to write 2500 to holding register 40001.

“`

Message: [05] [06] [00] [00] [09] [C4] [69] [85]

Breakdown: Slave 5, Write Single Register, Register 40001, Value = 2500

“`

4. Slave confirms the change: Returns the new setpoint value.

“`

Response: [05] [06] [00] [00] [09] [C4] [69] [85]

Breakdown: Slave 5, Write Single Register Response, Register 40001, Value = 2500

“`

5. Master verifies the heating element status: Uses function code 01 to read coil 00001 (heating element on/off).

“`

Message: [05] [01] [00] [00] [00] [01] [FD] [CA]

Breakdown: Slave 5, Read Coils, Start at 00001, Read 1 coil

“`

6. Slave reports the heating element is on: Returns a value of 1 (on).

“`

Response: [05] [01] [01] [01] [90] [08]

Breakdown: Slave 5, Read Coils Response, 1 byte of data, Value = 1

“`

Common Misconceptions: Clearing Up Confusion

“Can I use any function code with any data type?”

No! Each function code is designed to work with specific data types:

  • Code 04 works with input registers

“Why are there separate codes for reading coils vs. discrete inputs?”

Because they’re different data types: coils are read-write, while discrete inputs are read-only. The function code tells the slave which “column” of data to access.

“When should I use single vs. multiple write commands?”

  • Use multiple write codes (15, 16) when changing several values at once—this is more efficient than sending multiple single write commands

“What happens if I use the wrong function code?”

The slave will return an error response with an exception code. Common exception codes include:

  • 03: Illegal Data Value (invalid value)

Choosing the Right Function Code

Use this simple decision tree to select the appropriate function code:

1. Do you want to read or write data?

– Read → Go to 2

– Write → Go to 3

2. What type of data do you want to read?

– On/off values → 01 (Coils) or 02 (Discrete Inputs)

– Numeric values → 03 (Holding Registers) or 04 (Input Registers)

3. What type of data do you want to write?

– Single on/off value → 05 (Write Single Coil)

– Multiple on/off values → 15 (Write Multiple Coils)

– Single numeric value → 06 (Write Single Register)

– Multiple numeric values → 16 (Write Multiple Registers)

Conclusion: The Power of Precise Verbs

Modbus function codes are the “action verbs” that make industrial communication possible. They provide a standardized way for devices to request and send data, regardless of manufacturer or device type.

By understanding these function codes—what they do, how they’re categorized, and when to use them—you can effectively communicate with any Modbus device. The verb analogy helps demystify these codes, making them easier to remember and apply in real-world scenarios.

Whether you’re checking sensor values, adjusting setpoints, or troubleshooting a network, Modbus function codes are the precise verbs that get the job done. They’re the essential commands that keep industrial systems running smoothly.