ModBus Protocol Overview

Discuss the Implementation and Development of MODBus Devices
User avatar
ZerOne
Site Admin
Posts: 262
Joined: Sun Dec 13, 2020 8:21 am

Can we ask a Modbus device who made it and what it can do? Sometimes—but there is no universal “list every supported feature” command. Here is a cautious sequence, starting with the standard identity service rather than guessing registers.

Before sending anything
Use an authorised controlled bench with one device, known RTU serial settings and a known unit address. These examples use address 01; do not assume an unknown unit uses it. Do not use broadcast address 0, connect a second active master to a running bus, or scan arbitrary addresses. Isolate active loads and prevent unintended operation; qualified personnel must handle any hazardous wiring. A mains meter still requires its approved safe supply arrangement—these packets are not instructions for DIY live electrical work.

If you do not know the serial settings/address, obtain them from the label, setup display, saved configuration or vendor documentation. Do not change configuration to force a match. See the hardware-support checklist.

All frames below are complete RTU ADUs: unit address, function/data and two CRC bytes. Hexadecimal bytes are shown throughout. CRC covers every byte before the CRC and is transmitted low byte first. Line wrapping in a frame is formatting only, not a transmission pause.

Step 1: standard basic device identification
This is function 43 decimal (2B hex), MEI type 14 decimal (0E hex), read-identification code 01 (basic stream), starting object 00.
Request:

Code: Select all

01 2B 0E 01 00 70 77
Illustrative successful reply:

Code: Select all

01 2B 0E 01 01 00 00 03 00 10 45 78 61 6D 70 6C 65 20 43 6F 6E 74 72 6F 6C 73 01 07 44 45 4D 4F
2D 49 4F 02 03 31 2E 30 E6 F5
This reply is invented educational data, not a real brand or a captured hardware trace. It decodes as:
  • 01: addressed server.
  • 2B 0E 01: identification service, basic stream response.
  • 01: basic identification conformity, stream access only.
  • 00 00: no more objects follow; next-object ID is unused/zero.
  • 03: three objects follow.
  • 00 10 followed by 16 ASCII bytes: VendorName = “Example Controls”.
  • 01 07 followed by 7 ASCII bytes: ProductCode = “DEMO-IO”.
  • 02 03 followed by 3 ASCII bytes: MajorMinorRevision = “1.0”.
  • The final two bytes are the RTU CRC, not part of the revision string.
Object lengths count bytes, not registers; objects are not fixed-width fields. The product code may identify a family or catalogue reference rather than a friendly model name. Use the actual returned text to find the exact manufacturer's manual and firmware map.

What this tests: whether this addressed device currently implements this identification request, and what identity it reports. It does not enumerate its I/O map or prove the reported identity is genuine.

A standards-based Illegal Function response to that request would be:
Possible exception reply:

Code: Select all

01 AB 01 9E F0
Here AB is 2B with the exception bit set and 01 is Illegal Function. This can mean unimplemented or not allowable in the current state. It does not mean the device lacks ordinary Modbus register reads.

Step 2: optional serial Report Server ID
Function 17 decimal is 11 hex. This is not function 17 hex, and it is not the FC43/14 identification service. It is serial-line-only and not universally implemented. Use it where the device's documentation permits it.
Request:

Code: Select all

01 11 C0 2C
Invented successful reply:

Code: Select all

01 11 06 42 FF 44 45 4D 4F CB 17
In this fictional response, 06 counts the following six data bytes: server-ID byte 42, run-indicator FF (ON), and four vendor-specific bytes spelling “DEMO”. The server-ID byte 42 is not the bus address 01. Run-indicator 00 means OFF; FF means ON, but do not treat this as proof of physical output state.

The server-ID byte and additional bytes have vendor-specific meanings. There is no standard decoding that turns every such response into a model number. Length/content can vary; use the matching manual. An unsupported/not-allowable response could instead be:
Possible exception reply:

Code: Select all

01 91 01 8C 50
This request checks that one service, not the complete capabilities of the product. FC43/14 and Report Server ID are independent; success of one does not imply support for the other.

Timeout is different from an exception
No reply could mean a wrong address, baud/parity mismatch, wiring/CRC trouble, unavailable device or gateway issue. Silence alone does not establish unsupported functions. Stop and check the known setup rather than advancing through a blind packet sweep.

RTU timing matters
Frames are separated by at least t3.5 character times; a gap greater than t1.5 character times within a frame makes that frame incomplete and it must be discarded. Character time is based on the serial character format, not just eight data bits. For baud rates above 19200, the serial guide recommends fixed t1.5 = 750 microseconds and t3.5 = 1.750 milliseconds. A serial adapter/library should implement this; do not paste individual bytes with long pauses. The device's response timeout is separate from these framing intervals.

All example CRCs were calculated and independently cross-checked in software. Nothing here was tested on hardware.

Sources
Modbus Application Protocol V1.1b3: sections 6.13, 6.21 and 7
Modbus Serial Line Guide V1.02: sections 2.2, 2.5.1 and Appendix B
User avatar
ZerOne
Site Admin
Posts: 262
Joined: Sun Dec 13, 2020 8:21 am

The basic identification reply is not necessarily the whole response. A correct client must read the length fields and continuation fields, not assume three short strings always fit in one packet.

Conformity is about identification access, not all device features
In an FC43/14 reply, conformity 01, 02 or 03 means basic, regular or extended identification with stream access. Values 81, 82 or 83 mean the corresponding level plus individual-object access. This is not a list of supported coil/register functions.

Basic objects are 00 VendorName, 01 ProductCode and 02 MajorMinorRevision. Regular objects can include VendorUrl, ProductName and ModelName. Additional identification objects do not replace the application register map.

Read-identification code 01 requests basic data; 02 requests regular data; 03 requests extended data. Do not confuse that request field with the returned conformity field. Request code 04 selects one specific object and should only be used if the returned conformity advertises individual access (81/82/83). No individual-access test is needed for this sequence.

Worked continuation example—all identity strings below are fictional
To make the need for a second frame real, imagine a server with VendorName “Example Controls”, a deliberately extreme ProductCode made of 230 capital P characters, and revision “1.0”. This is artificial teaching data, not a real manufacturer's identity. Those three objects plus the response header exceed the 253-byte PDU maximum; each object itself fits and is not split between frames.

Initial request (same basic request as before):

Code: Select all

01 2B 0E 01 00 70 77
First response: vendor object only:

Code: Select all

01 2B 0E 01 01 FF 01 01 00 10 45 78 61 6D 70 6C 65 20 43 6F 6E 74 72 6F 6C 73 15 35
After 2B 0E 01, the response fields are conformity 01, More Follows FF, Next Object ID 01, and object count 01. Then object 00, length 10 hex, contains “Example Controls”.

Do not stop because only one object arrived. Keep read-identification code 01 and use the returned next-object ID:
Continuation request, starting object 01:

Code: Select all

01 2B 0E 01 01 B1 B7
Second response, product and revision:

Code: Select all

01 2B 0E 01 01 00 00 02 01 E6 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 02 03 31 2E 30 7D 20
This second reply has conformity 01, More Follows 00, Next Object ID 00 and object count 02. Object 01 has length E6 hex (230 decimal), followed by 230 bytes of 50 hex (ASCII P). Object 02 has length 03 and contains “1.0”. Its final two bytes are CRC. Both responses and both requests are shown completely, including CRCs; line wrapping does not divide a packet.

What this tests: correct retrieval of the remaining objects from the same identification stream. In practice, follow the returned FF/next-ID fields until More Follows is 00. Do not invent a continuation merely because you expected more fields. Apply bounded retries/timeouts and stop on non-progressing or malformed responses instead of looping forever.

The hypothetical long product is deliberately awkward so the segmentation rule can be demonstrated without pretending that a device may arbitrarily split three tiny objects that already fit. A real device normally returns much shorter identity strings.

Important boundaries
  • Do not split an object value between response packets: the standard treats each object as indivisible.
  • Parse each object's explicit length before reading the next object. ASCII text is not necessarily null-terminated.
  • The next-object ID is an identification-object index, not a holding-register address or a unit address.
  • An identity response is information supplied by the server, not cryptographic authentication. A simulator or another device can imitate it; CRC only checks transmission integrity, not trustworthiness.
This is packet construction verified in software, not a recording of a live device. The next reply uses real manufacturer documentation to show the difference between a claimed identity and a supported, mapped read.

Sources
Modbus Application Protocol V1.1b3: PDU limit in section 4.1, identification/continuation in section 6.21
Modbus Serial Line Guide V1.02: RTU frame and CRC
User avatar
ZerOne
Site Admin
Posts: 262
Joined: Sun Dec 13, 2020 8:21 am

Here are two separate real-product examples. They are alternatives for different devices, not packets to send one after another to the same unknown unit. Both assume an authorised safe setup and a known unit address of 01. Do not use measurement reads to guess the brand of an unidentified live device.

Example A: Schneider Electric Modicon M218 identification
Schneider's M218 Modbus Manager manual explicitly lists basic identification object 00 as “Schneider Electric”, object 01 as the controller reference (example “TM218LDA24DRN”), and object 02 as revision text formatted aa.bb.cc.dd. Its serial manager supports RTU or ASCII and master or slave modes; the controller must be configured as an RTU slave for this RTU example.

Standard basic identity request:

Code: Select all

01 2B 0E 01 00 70 77
Constructed example reply based on those documented objects:

Code: Select all

01 2B 0E 01 01 00 00 03 00 12 53 63 68 6E 65 69 64 65 72 20 45 6C 65 63 74 72 69 63 01 0D 54 4D
32 31 38 4C 44 41 32 34 44 52 4E 02 0B 30 31 2E 30 30 2E 30 30 2E 30 30 D4 60
This is not a manufacturer-published byte trace or a captured reply. The vendor and controller-reference strings come from the manual. Revision “01.00.00.00” is explicitly invented example text in the documented format, not a claim about installed firmware. Conformity 01 and the single-frame layout are illustrative protocol fields, not fields independently established by that manual. Actual conformity, revision, lengths and CRC must match the received response.

The three object lengths here are 12 hex (18 bytes), 0D hex (13 bytes) and 0B hex (11 bytes). Decode them as “Schneider Electric”, “TM218LDA24DRN” and “01.00.00.00”.

What this tests: that the addressed unit answers basic identity, and supplies information consistent with the M218 documentation. It does not prove that the reference is genuine or disclose the installed PLC application's map.

The same manual lists supported slave functions for digital I/O and word access, but warns that only located controller-application variables are accessible. Therefore I am not inventing fixed M218 input or register offsets here. Obtain the actual application's mapping before trying data reads. A generic function-support table is not enough to choose a safe valid address.

Example B: Eastron SDM120-Modbus documented voltage read
Eastron's SDM120-Modbus protocol document, section 2.1 and its FC04 register map, gives voltage at traditional input-register reference 30001, PDU start offset 0000, occupying two 16-bit registers (four bytes) as an IEEE-754 floating-point value in volts. Its document specifies paired-register reads and even start/count for these floats. Verify the document against the exact installed variant/firmware.

This particular offset zero is justified by that map. It is not a general “read register zero on every unknown product” probe.
Manufacturer-documented complete request for unit 01:

Code: Select all

01 04 00 00 00 02 71 CB
Manufacturer-documented example reply for approximately 230.2 V:

Code: Select all

01 04 04 43 66 33 34 1B 38
These request/reply bytes, including CRC 71 CB and 1B 38, are printed in the manufacturer's document; I have recalculated both CRCs. They are a published worked example, not my hardware capture or a promise that any actual supply currently measures 230.2 V.

The response contains byte count 04 and data 43 66 33 34. Decoding those four bytes as the documented high-word-first float gives approximately 230.200012 V (displayed as 230.2 V). A real response varies with the measurement and therefore has a different data field/CRC.

What this tests: an FC04 read of that specific known range, correct two-register decoding, and a plausible measurement to compare with an appropriate trusted indication. A plausible reply alone does not prove this is an Eastron meter—other devices can share the same mapping or emulate it. The measurement packet does not contain a make/model string. No claim is made here that this meter supports the identity requests in the other examples.

Possible failure responses to this FC04 read
Exception 02 (Illegal Data Address):

Code: Select all

01 84 02 C2 C1
Exception 03 (Illegal Data Value):

Code: Select all

01 84 03 03 01
The function 84 is the exception form of 04. Code 02 concerns the address/length combination; it does not establish that all FC04 reads are unsupported. Code 03 concerns an invalid request-data/structural value; it is not a universal engineering-range check. With this documented request, an exception is a reason to recheck the exact model, map version, mode, settings and request—not a reason to sweep addresses. A timeout has no exception bytes: troubleshoot communication separately.

How to investigate supported features after identification
Use the hardware-support checklist and the exact manufacturer/model/firmware manual. Select a documented safe readable point for each table you actually need:
  • FC01 decimal/01 hex: a known coil readback range.
  • FC02 decimal/02 hex: a known discrete-input range.
  • FC03 decimal/03 hex: a known readable holding-register range.
  • FC04 decimal/04 hex: a known input-register range, as in the meter example above.
I have intentionally not supplied universal packets for the other three: without an actual matching map, an address/count would be a guess. Even reads can have device-specific side effects such as clearing a status; use documentation-approved entries. A successful read establishes support only for that request/range in the present configuration.

Reading holding registers does not prove write permission or support for FC06. Reading coils does not prove they can safely be written. There is no safe general read-only packet that proves operation of FC05, FC06, FC15 (0F hex) or FC16 (10 hex). Determine those capabilities from the manual/vendor and application permissions; do not issue exploratory write tests. This sequence contains no writes, configuration changes, diagnostic resets/restarts or indiscriminate read sweeps.

Ultimately, packet replies can supply identity strings and confirm narrowly targeted reads. They cannot universally enumerate features, reveal physical wiring/output behaviour, supply missing measurement scaling, or authenticate a device. Vendor documentation and safe verification remain essential. All non-published frames above are constructed examples checked in software, not hardware tests.

Sources
Schneider Electric: M218 Modbus Manager, supported slave functions and basic identification objects
Eastron: SDM120-Modbus protocol, section 2.1 and FC04 register map
Modbus Application Protocol V1.1b3: data model, read functions, exceptions and identification
Post Reply

Return to “MODBus Protocol Discussion”