Modbus RTU, ASCII and TCP

Frames, function codes, addressing, data formats, exceptions, timing and gateways, with computed examples.

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.

VariantCarried onCodingError checkUsed for
Modbus RTURS-485 or RS-232 serialBinary, compactCRC-16The usual choice on serial lines
Modbus ASCIISerialReadable text, two characters per byte, starts with a colonLRC (a simple sum)Rare; slow; easy to read in a terminal
Modbus TCPEthernet, TCP port 502Binary with a 7-byte headerNone (TCP checks the data)PLC to drive and meter on Ethernet, SCADA
Modbus RTU over TCPEthernet, a serial frame carried in TCPRTU frame including the CRCCRC-16Serial 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.

Request: read 2 holding registers from address 0 of slave 101slave03function00 00start address00 02quantityC4 0BCRC lo hiResponse: 4 data bytes follow (two 16-bit registers, high byte first)01slave03function04bytes00 0Aregister 0 = 1001 02register 1 = 2585A 60CRC lo hiException response: illegal data address (the high bit of the function code is set)01slave83fn+0x8002code 2C0 F1CRC lo hiModbus TCP: the same request, a 7-byte header (MBAP) and no CRC (TCP checks the data)00 01transaction00 00protocol 000 06length 601unit03function00 00start00 02quantitySilence of at least 3.5 character times separates RTU frames. The CRC is sent low byte first.
A read request, a normal response, an exception response and the Modbus TCP version of the request.
FrameBytes (hex)Meaning
Read request01 03 00 00 00 02 C4 0BSlave 1, function 03 (read holding registers), start address 0000, quantity 0002, CRC C4 0B
Normal response01 03 04 00 0A 01 02 5A 60Slave 1, function 03, byte count 04, register 0 = 000A (10), register 1 = 0102 (258), CRC 5A 60
Exception response01 83 02 C0 F1Slave 1, function 83 (03 + 80 means an error), exception code 02 (illegal data address), CRC C0 F1
Write one register01 06 00 01 04 D2 5A 97Slave 1, function 06, address 0001, value 04D2 (1234), CRC 5A 97. The reply repeats the request.
Write two registers01 10 00 00 00 02 04 00 0A 01 02 53 FCSlave 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

CodeNameData tableTypical limit per request
01Read coilsCoils (read/write bits)2 000 bits
02Read discrete inputsDiscrete inputs (read-only bits)2 000 bits
03Read holding registersHolding registers (read/write 16-bit)125 registers
04Read input registersInput registers (read-only 16-bit)125 registers
05Write single coilCoils (value FF00 = on, 0000 = off)1 bit
06Write single registerHolding registers1 register
15 (0F)Write multiple coilsCoils1 968 bits
16 (10)Write multiple registersHolding registers123 registers
22 (16)Mask write registerHolding registers (change some bits)1 register
23 (17)Read/write multiple registersHolding registers125 read, 121 write
07, 08, 11, 12Serial diagnostics: exception status, diagnostics, event counter, event logSerial line onlyvaries
43 / 14Read device identificationVendor, product code, revisionvaries

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

Coils0xxxx (reference)1 bit, read/writeaddress 0address 1address 2address 3address 4read 01, write 05, 15addresses 0 to 65535Discrete inputs1xxxx (reference)1 bit, read onlyaddress 0address 1address 2address 3address 4read 02addresses 0 to 65535Input registers3xxxx (reference)16 bits, read onlyaddress 016 bitaddress 116 bitaddress 216 bitaddress 316 bitaddress 416 bitread 04addresses 0 to 65535Holding registers4xxxx (reference)16 bits, read/writeaddress 016 bitaddress 116 bitaddress 216 bitaddress 316 bitaddress 416 bitread 03, write 06, 16addresses 0 to 65535
The four Modbus tables, their older reference ranges, the size of each element and the function codes that access them.

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 saysAddress on the wireFunctionNote
Holding register 40001003First holding register
Holding register 4010810703108 − 1
Input register 30001004First input register
Coil 00017160117 − 1
Discrete input 100054025 − 1
Register address 0x010025603 or 04Some manuals give wire addresses in hex already
Holding register 400001 (six digits)003Newer 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.

TypeRegistersNotes
UINT1610 to 65 535
INT161−32 768 to 32 767; two’s complement: 65 535 reads as −1
UINT32 / INT322Word order differs between devices
FLOAT32 (IEEE 754)2Same word-order problem; check with a known value
FLOAT644Used by some energy meters
Bit field1Each bit is a flag: status words, alarms
Scaled integer1For example 0.1 Hz units: 450 means 45.0 Hz. Divide in the program
StringnTwo ASCII characters per register, high byte first (check)
The float 25.5 is the four bytes 41 CC 00 00 (called A B C D). Devices differ in how they fill two registers:Big-endian (ABCD)the standard Modbus order; most devices41ACCB00C00Dreg N = 16844reg N+1 = 0Word-swapped (CDAB)low word first: common in PLC and instrument gear00C00D41ACCBreg N = 0reg N+1 = 16844Byte-swapped (BADC)each word swapped; rareCCB41A00D00Creg N = 52289reg N+1 = 0Little-endian (DCBA)fully reversed00D00CCCB41Areg N = 0reg N+1 = 52289If a value reads as nonsense, try each order. A known value (such as a setpoint you typed in) tells you which one the device uses.
The same 32-bit float placed in two registers four different ways.

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.

CodeNameUsual cause
01Illegal functionThe device does not support that function (for example reading with 04 when the register is a holding register, or writing a read-only value)
02Illegal data addressThe register does not exist: an off-by-one error, the wrong table or the wrong register map
03Illegal data valueThe quantity is too large, or the value is outside the allowed range
04Server device failureThe device had an internal error while carrying out the request
05AcknowledgeAccepted but takes long; poll for the result
06Server device busyTry again later
08Memory parity errorFault reading extended memory
0A / 0BGateway path unavailable / target failed to respondA gateway could not reach the device behind it
What the client seesMeaningWhat to do
A normal replyIt workedCheck the values and the scaling
An exception replyThe link is fine; the request is wrongCompare 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 thereCheck wiring, polarity, settings, address
A reply with a bad CRCThe reply was damagedNoise, termination, baud-rate mismatch
A reply from the wrong addressA second device with the same address, or the wrong unit ID through a gatewayGive 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 processedCRC after the byte (hex)
01807E
032140
00F020
00D8F1
008419
020BC4

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

One poll at 9600 baud, 8N1, reading 2 registers (all times computed)Request 8 bytes8.3 msgap3.6 msSlave processing5.0 msResponse 9 bytes9.4 msgap3.6 msTotal 30.0 ms = about 33 polls per secondCharacter time = 10 bits / 9600 = 1.042 ms. A request of 8 characters takes 8.3 ms, a response of 9 takes 9.4 ms.The gaps (3.5 character times) and the slave’s processing time are paid on every poll: read blocks of registers, not one at a time.
One RTU transaction at 9600 baud: request, silent gap, slave processing, response and a second gap.

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 rateOne characterRequest + responseGaps (2)One transactionTen slaves
9 6001.15 ms37.8 ms8.0 ms50.8 ms508.3 ms (2.0 scans per second)
38 4000.29 ms9.5 ms3.5 ms18.0 ms179.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).

Ethernet14 BMAC addressesIP20 BIP addressesTCP20 Bport 502MBAP7 Bunit, lengthModbus PDU2 to 253 Bfunction + dataFCS4 Bframe checkOne Modbus TCP frame on the wire (a read request has a 5-byte PDU: function, start address, quantity)switch readsrouter readsfirewall rule(port 502)the device and the gateway read thisEach layer adds its own header. A sniffer shows all of them; a gateway rewrites some of them.
A Modbus TCP frame on the wire.
FieldBytesContent
Transaction ID2Chosen by the client; echoed in the reply
Protocol ID20 for Modbus
Length2Number of following bytes: unit ID + function + data
Unit ID1The slave address when passing through a gateway; 0xFF or 1 for a device that is itself the server
Function and dataup to 253Exactly 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

SCADA / PLCModbus TCP clientGatewayIP 192.168.1.50DriveRTU address 1MeterRTU address 2SensorRTU address 3EthernetTCP port 502unit ID 2RS-485slave 2The gateway drops the 7-byte TCP header, uses the unit ID as the RTU slave address, adds a CRC, waits for the replyon the serial line and sends it back. The serial bus is the bottleneck: one request at a time at the baud rate in use.Many TCP clients can ask the gateway; it queues them. Give the gateway a fixed IP address.
A Modbus TCP to RTU gateway: the unit ID selects the serial slave.

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

MistakeWhat you seeFix
Off-by-one register addressThe value belongs to the next or previous register; exception 02 at the end of a tableCheck the base (0 or 1) of the tool and the manual
Wrong function code for the tableException 01 or 02, or zerosUse 03 for holding, 04 for input registers
Word order wrong for 32-bit valuesHuge or tiny numbers for floats; large steps for integersSwap the words
Signed against unsignedA value jumps to 65 535 when it should go negativeTreat the register as INT16
Scaling forgottenA temperature of 255 instead of 25.5Divide by the device scale
Two masters on one busCorrupted frames, random timeoutsOne master only; use a gateway for several clients
Timeout shorter than the device’s replyFalse timeouts, retriesRaise the timeout above the slowest reply
Polling too fastDevice slows down or drops requestsSlow the poll; read blocks
Wrong unit ID through a gatewayNo reply or the wrong device answersSet the unit ID to the serial address
Writing every scanSlow bus, worn memory in the deviceWrite 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

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.