Modbus RTU, ASCII and TCP
Frames, function codes, addressing, data formats, exceptions, timing and gateways, with computed examples.
On this page
- The three variants
- Modbus RTU frames
- Function codes
- Data tables and addressing
- Data formats: integers, floats, strings
- Exceptions and error handling
- CRC-16 and LRC step by step
- Timing and polling
- Modbus ASCII
- Modbus TCP
- Gateways and device servers
- Setting up a Modbus link
- Common mistakes
- Security
- FAQ
The three variants
Modbus, published by Modicon in 1979, is the most widely supported industrial protocol. It is simple, open and free, and it is found in meters, drives, soft starters, sensors, power analyzers, flow computers and every PLC. A client (the older word is master) sends a request to a server (slave) and waits for the reply. The data is organized as four tables of numbered bits and 16-bit registers.
| Variant | Carried on | Coding | Error check | Used for |
|---|---|---|---|---|
| Modbus RTU | RS-485 or RS-232 serial | Binary, compact | CRC-16 | The usual choice on serial lines |
| Modbus ASCII | Serial | Readable text, two characters per byte, starts with a colon | LRC (a simple sum) | Rare; slow; easy to read in a terminal |
| Modbus TCP | Ethernet, TCP port 502 | Binary with a 7-byte header | None (TCP checks the data) | PLC to drive and meter on Ethernet, SCADA |
| Modbus RTU over TCP | Ethernet, a serial frame carried in TCP | RTU frame including the CRC | CRC-16 | Serial device servers and some gateways |
Modbus RTU frames
An RTU frame is the station address (1 to 247; 0 is broadcast), the function code, the data and a two-byte CRC, sent low byte first. Frames are separated by a silence of at least 3.5 character times, which is how the receiver knows a frame has ended. Because the frame may have no gap of more than 1.5 character times inside it, the master must send each frame without pausing.
| Frame | Bytes (hex) | Meaning |
|---|---|---|
| Read request | 01 03 00 00 00 02 C4 0B | Slave 1, function 03 (read holding registers), start address 0000, quantity 0002, CRC C4 0B |
| Normal response | 01 03 04 00 0A 01 02 5A 60 | Slave 1, function 03, byte count 04, register 0 = 000A (10), register 1 = 0102 (258), CRC 5A 60 |
| Exception response | 01 83 02 C0 F1 | Slave 1, function 83 (03 + 80 means an error), exception code 02 (illegal data address), CRC C0 F1 |
| Write one register | 01 06 00 01 04 D2 5A 97 | Slave 1, function 06, address 0001, value 04D2 (1234), CRC 5A 97. The reply repeats the request. |
| Write two registers | 01 10 00 00 00 02 04 00 0A 01 02 53 FC | Slave 1, function 10 hex (16), address 0000, quantity 0002, byte count 04, values 000A and 0102. The reply echoes address and quantity. |
The Modbus Frame and CRC Calculator builds and decodes frames like these.
Function codes
| Code | Name | Data table | Typical limit per request |
|---|---|---|---|
| 01 | Read coils | Coils (read/write bits) | 2 000 bits |
| 02 | Read discrete inputs | Discrete inputs (read-only bits) | 2 000 bits |
| 03 | Read holding registers | Holding registers (read/write 16-bit) | 125 registers |
| 04 | Read input registers | Input registers (read-only 16-bit) | 125 registers |
| 05 | Write single coil | Coils (value FF00 = on, 0000 = off) | 1 bit |
| 06 | Write single register | Holding registers | 1 register |
| 15 (0F) | Write multiple coils | Coils | 1 968 bits |
| 16 (10) | Write multiple registers | Holding registers | 123 registers |
| 22 (16) | Mask write register | Holding registers (change some bits) | 1 register |
| 23 (17) | Read/write multiple registers | Holding registers | 125 read, 121 write |
| 07, 08, 11, 12 | Serial diagnostics: exception status, diagnostics, event counter, event log | Serial line only | varies |
| 43 / 14 | Read device identification | Vendor, product code, revision | varies |
Most devices implement only 03, 04, 06 and 16, plus 01, 02, 05 and 15 for bits. Function codes outside this list are manufacturer specific: check the manual.
Data tables and addressing
Each table has up to 65 536 elements numbered from 0. The function code selects the table, so a message never needs to say which table it means: function 03 always reads holding registers.
Reference numbers against wire addresses
Manuals often list registers with an older five-digit reference: 40001 for the first holding register. The leading 4 only says which table; the register is number 1, and goes on the wire as address 0 (the specification counts from 0 in the message and from 1 in the data model). Some manuals list the wire address and others the reference number, and some tools add 1 for you.
| Manual says | Address on the wire | Function | Note |
|---|---|---|---|
| Holding register 40001 | 0 | 03 | First holding register |
| Holding register 40108 | 107 | 03 | 108 − 1 |
| Input register 30001 | 0 | 04 | First input register |
| Coil 00017 | 16 | 01 | 17 − 1 |
| Discrete input 10005 | 4 | 02 | 5 − 1 |
| Register address 0x0100 | 256 | 03 or 04 | Some manuals give wire addresses in hex already |
| Holding register 400001 (six digits) | 0 | 03 | Newer devices with more than 9 999 registers |
If a reading is the neighbor of the value you expected, you are off by one: check whether the tool, the PLC and the manual all use the same convention. This is the single most common Modbus problem, so test with a value you know.
Data formats: integers, floats, strings
A Modbus register holds 16 bits and knows nothing about what they mean. The device manual says whether a register is an unsigned integer, a signed integer, a bit field, a value in tenths of a unit, or half of a 32-bit number.
| Type | Registers | Notes |
|---|---|---|
| UINT16 | 1 | 0 to 65 535 |
| INT16 | 1 | −32 768 to 32 767; two’s complement: 65 535 reads as −1 |
| UINT32 / INT32 | 2 | Word order differs between devices |
| FLOAT32 (IEEE 754) | 2 | Same word-order problem; check with a known value |
| FLOAT64 | 4 | Used by some energy meters |
| Bit field | 1 | Each bit is a flag: status words, alarms |
| Scaled integer | 1 | For example 0.1 Hz units: 450 means 45.0 Hz. Divide in the program |
| String | n | Two ASCII characters per register, high byte first (check) |
Worked example: a REAL over two registers
- The value 25.5 as a 32-bit IEEE 754 float is 0x41CC0000: sign 0, exponent 131 (24), mantissa 1.59375.
- High word first (ABCD): register N = 0x41CC (16 844), register N+1 = 0x0000 (0).
- Low word first (CDAB): register N = 0x0000, register N+1 = 0x41CC. If the PLC reads this as high-word-first, it sees 0x000041CC = 2.37 × 10−41 and shows zero.
- Check with a known value: a room temperature of 25.5 that reads as 0, or as 1.85 × 1037, has the wrong word or byte order. Most PLCs and HMIs have a word-swap setting; otherwise swap the two words in the program.
- Scaled integers have no such issue, but check the scale: 255 in tenths is 25.5.
Exceptions and error handling
If a server cannot carry out a request, it replies with the function code plus 0x80 and an exception code. If it did not understand the frame at all (bad CRC, bad parity), it says nothing, and the client times out.
| Code | Name | Usual cause |
|---|---|---|
| 01 | Illegal function | The device does not support that function (for example reading with 04 when the register is a holding register, or writing a read-only value) |
| 02 | Illegal data address | The register does not exist: an off-by-one error, the wrong table or the wrong register map |
| 03 | Illegal data value | The quantity is too large, or the value is outside the allowed range |
| 04 | Server device failure | The device had an internal error while carrying out the request |
| 05 | Acknowledge | Accepted but takes long; poll for the result |
| 06 | Server device busy | Try again later |
| 08 | Memory parity error | Fault reading extended memory |
| 0A / 0B | Gateway path unavailable / target failed to respond | A gateway could not reach the device behind it |
| What the client sees | Meaning | What to do |
|---|---|---|
| A normal reply | It worked | Check the values and the scaling |
| An exception reply | The link is fine; the request is wrong | Compare the address, function and quantity with the manual |
| No reply (timeout) | The server did not hear the request, ignored it (bad CRC or parity), or is not there | Check wiring, polarity, settings, address |
| A reply with a bad CRC | The reply was damaged | Noise, termination, baud-rate mismatch |
| A reply from the wrong address | A second device with the same address, or the wrong unit ID through a gateway | Give each device its own address |
CRC-16 and LRC step by step
The RTU CRC is computed over every byte before it. Start with 0xFFFF. For each byte, XOR it into the low byte of the CRC, then repeat eight times: if the lowest bit is 1, shift right and XOR with 0xA001; otherwise only shift right. The final value is sent low byte first.
| Byte processed | CRC after the byte (hex) |
|---|---|
| 01 | 807E |
| 03 | 2140 |
| 00 | F020 |
| 00 | D8F1 |
| 00 | 8419 |
| 02 | 0BC4 |
The result is 0x0BC4, sent as C4 0B. A receiver that runs the same calculation over the whole frame, CRC included, gets zero. The CRC detects all single-bit errors, all burst errors up to 16 bits and almost all longer ones.
Worked example: the ASCII LRC
- Modbus ASCII sends each byte as two hexadecimal characters, starts with a colon and ends with CR LF. The error check is the LRC: add the bytes (ignoring carry beyond 8 bits) and take the two’s complement.
- For the same request the bytes are 01 03 00 00 00 02. Their sum is 06, so the LRC is 100 hex − 06 = FA.
- The frame is :010300000002FA CR LF: 17 characters instead of 8 bytes, and far easier to read in a terminal.
Timing and polling
Worked example: how fast can I poll?
Ten slaves on one RS-485 line. For each, the master reads 10 holding registers: an 8-byte request and a response of 5 + 2 × 10 = 25 bytes (address, function, byte count, 20 data bytes, 2 CRC). Each character is 11 bits at 8E1, and the slave takes about 5 ms to answer.
| Baud rate | One character | Request + response | Gaps (2) | One transaction | Ten slaves |
|---|---|---|---|---|---|
| 9 600 | 1.15 ms | 37.8 ms | 8.0 ms | 50.8 ms | 508.3 ms (2.0 scans per second) |
| 38 400 | 0.29 ms | 9.5 ms | 3.5 ms | 18.0 ms | 179.5 ms (5.6 scans per second) |
Quadrupling the baud rate cuts the cycle by about 65 percent, not 75, because the fixed gap and the slave’s turnaround time do not shrink.
Worked example: one block against twenty single reads
- Reading 20 consecutive registers in one request (9 600 baud, 8E1) takes about 73.8 ms.
- Reading them as 20 separate one-register requests takes 20 × 30.2 = 604.2 ms, about 8.2 times as long, because every request pays the gaps and the slave’s processing again.
- The rule: group the registers you need into as few contiguous blocks as possible, even if you read some you do not use.
- Poll fast things often and slow things rarely. A temperature does not need reading every 50 ms.
- Set the timeout above the worst-case reply time (typically 500 to 1000 ms on serial), and limit retries (2 or 3) so one dead device does not stall the whole line.
- Skip devices that are down. Poll a faulted slave only occasionally, so a dead drive does not cost a timeout on every cycle.
- Write on change only. Writing the same value every cycle wastes time and can wear out device memory (for example EEPROM parameters).
Modbus ASCII
ASCII mode is a historical alternative for slow or noisy lines and for links with long delays between characters (modems, radios), since a gap inside a frame does not end the frame. It uses 7 data bits and ends each frame with CR LF. Almost nothing new uses it, but a device that offers “ASCII” as a setting is usually asking you to choose between this and RTU: both ends must use the same.
Modbus TCP
Modbus TCP puts the same request and data on Ethernet, TCP port 502. The serial address and the CRC are replaced by a 7-byte MBAP header: a transaction identifier (the client numbers each request and the server repeats it, so replies can be matched), a protocol identifier (always 0), the length of what follows, and a unit identifier. TCP already checks the data, so there is no CRC. The longest message is 260 bytes (7 + 253).
| Field | Bytes | Content |
|---|---|---|
| Transaction ID | 2 | Chosen by the client; echoed in the reply |
| Protocol ID | 2 | 0 for Modbus |
| Length | 2 | Number of following bytes: unit ID + function + data |
| Unit ID | 1 | The slave address when passing through a gateway; 0xFF or 1 for a device that is itself the server |
| Function and data | up to 253 | Exactly as in RTU |
- Many clients at once. A Modbus TCP server accepts several connections (often 4 to 16, check the manual); a single serial master cannot do that.
- Keep connections open. Opening a new connection for every request is slow and exhausts the server’s connection table; hold one connection per client and reuse it.
- Unit ID. Some devices ignore it and some insist on a specific value (1 or 255). When talking through a gateway, it selects the serial slave.
- Timeouts. TCP can mask a dead device for tens of seconds: use a short application timeout and detect a dropped connection quickly (keep-alive).
- Port. The standard port is 502; a few devices use another.
Gateways and device servers
A gateway lets a PLC or SCADA on Ethernet reach serial devices. Two things to remember: the serial line is the bottleneck (the gateway can only forward one request at a time at the baud rate in use), and the gateway has its own timeout for the slave, which should be longer than the slowest device reply and shorter than the client’s timeout. A serial device server is similar but may simply tunnel the raw serial bytes over TCP, so the client sends RTU frames (CRC included) inside TCP: that is “Modbus RTU over TCP”, a different framing from Modbus TCP.
Setting up a Modbus link
- 1. Decide who is the client. Usually the PLC polls the drives, meters and sensors. An HMI or SCADA may poll the PLC, which then acts as a server.
- 2. Set the servers to unique addresses and the shared serial settings (or unique IP addresses and port 502).
- 3. Get the register map from each device’s manual: the registers, their types, units, scaling, whether they are read-only, and the word order.
- 4. Test with a PC first. A Modbus client tool (Modbus Poll, QModMaster, mbpoll) and a USB-RS485 adapter shows whether the device answers, without any PLC program. If the PC works and the PLC does not, the fault is in the PLC settings or the program.
- 5. Configure the PLC client (a Modbus configuration or message instruction; see Connecting PLCs, Drives and HMIs) with the same settings and a poll for each block of registers.
- 6. Check scaling, word order and address base and verify one value against the device’s display.
- 7. Set sensible timeouts and retries and handle a lost device in the program: raise an alarm and use a safe value, rather than continuing with the last number.
- 8. Document the map: device, address, register, type, scale, unit, who reads it.
Common mistakes
| Mistake | What you see | Fix |
|---|---|---|
| Off-by-one register address | The value belongs to the next or previous register; exception 02 at the end of a table | Check the base (0 or 1) of the tool and the manual |
| Wrong function code for the table | Exception 01 or 02, or zeros | Use 03 for holding, 04 for input registers |
| Word order wrong for 32-bit values | Huge or tiny numbers for floats; large steps for integers | Swap the words |
| Signed against unsigned | A value jumps to 65 535 when it should go negative | Treat the register as INT16 |
| Scaling forgotten | A temperature of 255 instead of 25.5 | Divide by the device scale |
| Two masters on one bus | Corrupted frames, random timeouts | One master only; use a gateway for several clients |
| Timeout shorter than the device’s reply | False timeouts, retries | Raise the timeout above the slowest reply |
| Polling too fast | Device slows down or drops requests | Slow the poll; read blocks |
| Wrong unit ID through a gateway | No reply or the wrong device answers | Set the unit ID to the serial address |
| Writing every scan | Slow bus, worn memory in the device | Write only when the value changes |
Security
Modbus has no authentication, no encryption and no integrity protection beyond the CRC. Anyone who can reach a Modbus device on the network can read it and write to it, including a function code that stops a drive or changes a set point. Never expose port 502 to the internet or to the office network; place Modbus devices on a protected machine network, restrict which addresses may connect, and use a gateway or firewall that allows only the function codes and address ranges you need. A secure variant (Modbus/TCP Security, with TLS on port 802) exists but few devices support it yet. See Industrial Network Security.
Related
- Industrial Communication: the overview of this guide.
- Serial Communication: RS-232, RS-422 and RS-485: the electrical layer under Modbus RTU.
- Connecting PLCs, Drives and HMIs: Modbus on Allen-Bradley, Siemens, Mitsubishi, Omron and others.
- Sniffers, Analyzers and Serial Tools: reading Modbus frames with a sniffer.
- Modbus Frame and CRC Calculator.
FAQ
What is the difference between Modbus RTU and Modbus TCP?
They carry the same requests and data tables. RTU runs over a serial line (usually RS-485), uses a CRC and silent gaps to frame messages, and handles one transaction at a time. TCP runs over Ethernet, drops the CRC and slave address in favor of a header, and allows several clients. Many devices offer both, and gateways convert between them.
What do client, server, master and slave mean?
The current specification says client and server. Master and slave are the older names for the same roles and are still used in most manuals and tools.
Can I mix Modbus devices from different manufacturers?
Usually yes, provided they share baud rate, parity and stop bits and have unique addresses. The register maps differ for each device, so you must read each manual, but the protocol is the same.
Why does my 32-bit value read as nonsense?
The two 16-bit registers are in the opposite word order. Swap the words (a word-swap or byte-order setting) in the PLC, HMI or master software.
How many devices can one Modbus RTU bus have?
Addresses 1 to 247 allow 247, but the RS-485 electrical limit is 32 unit loads (more with modern transceivers) and the poll time grows with each device. Most buses carry 10 to 30.
Is Modbus fast enough for control?
For slow processes and supervision, yes. For motion control and fast loops, no: use a real-time network (EtherCAT, PROFINET IRT, EtherNet/IP). Modbus TCP is typically tens of milliseconds, and serial hundreds of milliseconds for a full poll cycle.
References
- Modbus Organization, MODBUS Application Protocol Specification V1.1b3, MODBUS over Serial Line Specification and Implementation Guide V1.02, and MODBUS Messaging on TCP/IP Implementation Guide V1.0b (modbus.org).
- Modbus Organization, MODBUS/TCP Security Protocol Specification.
- IEEE 754-2019, Standard for Floating-Point Arithmetic (the float format).
- TIA/EIA-485-A (the electrical layer of Modbus RTU on RS-485).
Last reviewed: October 2026. Speeds, lengths, node counts and menu names are typical: confirm against the specification and the manufacturer’s documentation for the devices you use.
