**Modbus** hay MODBUS là một giao thức truyền thông ở tầng Application theo mô hình OSI, hỗ trợ giao tiếp theo mô hình client/server giữa các thiết bị kết nối trong nhiều loại bus hoặc mạng khác nhau. Modbus được Modicon (nay là Schneider Electric) xuất bản vào năm 1979 để sử dụng với các bộ PLC của chính hãng này. Modbus sau đó đã trở thành một giao thức truyền thông tiêu chuẩn *de facto* và là một phương tiện phổ biến để kết nối các thiết bị điện tử công nghiệp.

Modbus phổ biến trong môi trường công nghiệp vì nó được xuất bản công khai và miễn phí bản quyền. Nó được phát triển cho các ứng dụng công nghiệp, tương đối dễ triển khai và bảo trì so với các tiêu chuẩn khác và có ít hạn chế, ngoài kích thước gói dữ liệu, và định dạng dữ liệu được truyền.

Giao thức Modbus sử dụng các cổng truyền thông nối tiếp, Ethernet hoặc bộ giao thức Internet làm lớp truyền tải (transport layer) để hỗ trợ giao tiếp truyền và nhận từ nhiều loại bus hoặc mạng khác nhau. Ví dụ, có thể có một thiết bị đo nhiệt độ và một thiết bị khác đo độ ẩm cùng được kết nối với cùng một cáp, cả hai đều có thể truyền dữ liệu đo được đến cùng một máy tính, thông qua Modbus.

Modbus thường được sử dụng để kết nối máy tính sử dụng trong quá trình giám sát nhà máy/hệ thống với một thiết bị đầu cuối từ xa (RTU) trong hệ thống Kiểm soát Giám sát và Thu thập Dữ liệu (SCADA) trong ngành điện lực. Trong Modbus, nhiều kiểu dữ liệu được đặt tên từ các khái niệm điều khiển công nghiệp của các thiết bị nhà máy như một ngõ ra vật lý đơn được gọi là *coil* và một ngõ vào vật lý đơn được gọi là *discrete input* hoặc *contact.*

Việc phát triển và cập nhật các giao thức Modbus do Modbus Organization quản lý kể từ tháng 4 năm 2004, khi Schneider Electric chuyển giao quyền cho tổ chức này. Modbus Organization là một hiệp hội của những người dùng và nhà cung cấp các thiết bị Modbus thúc đẩy việc sử dụng bộ giao thức truyền thông này, cũng như việc giải quyết vấn đề kiến trúc cho các hệ thống tự động hóa phân tán trên nhiều phân khúc thị trường.

Mô tả giao thức
---------------

Mô hình triển khai của các giao thức với Modbus
Các chuẩn truyền hoặc mạng hiện tại đã được triển khai với Modbus bao gồm:

* TCP/IP qua mạng Ethernet.
* Truyền thông nối tiếp bất đồng bộ bằng nhiều phương thức truyền thông khác nhau như EIA/TIA-232-E, EIA-422, EIA/TIA-485-A, cáp quang, sóng vô tuyến,...
* MODBUS PLUS: Mạng token tốc độ cao

Kiến trúc của một hệ thống mạng với Modbus
Để hỗ trợ cho việc truyền thông dữ liệu trên mạng Modbus, có nhiều modem và gateway được thiết kế riêng để hỗ trợ giao thức Modbus (xem hình: *Kiến trúc của một hệ thống mạng với Modbus*).

### PDU và ADU

Modbus định nghĩa **protocol data unit**, viết tắt **PDU**, (tạm dịch: đơn vị dữ liệu của giao thức) độc lập với các giao thức hoạt động ở tầng dưới (xem hình: *Mô hình triển khai của các giao thức với Modbus*). Việc ánh xạ giao thức Modbus với các loại bus hoặc mạng cụ thể sẽ sinh thêm các trường tương ứng, từ đó hình thành các **application data unit**, viết tắt: **ADU** (tạm dịch: đơn vị dữ liệu của ứng dụng). ADU sẽ được hình thành bởi một client trong mạng Modbus khi client này khởi tạo một transaction (tạm dịch: kết nối). Cụ thể, thành phần của PDU và ADU sẽ bao gồm:

* PDU = Function code + Data
* ADU = Additional address + PDU + Error check

ADU còn được gọi một cách thông dụng là **Modbus frame** như trong tài liệu chính thức của Modbus và ở các ứng dụng triển khai thực tế, dù **frame** là từ để chỉ đơn vị dữ liệu ở tầng Data-link trong mô hình OSI và TCP/IP (trong khi Modbus là giao thức ở tầng Application).

Kích thước tối đa của PDU là 253 byte. Kích thước tối đa của ADU với RS232/RS485 là 256 byte, với TCP là 260 byte.

Modbus sử dụng ‘big-Endian’ để đại diện cho trường address và data. Khi đó, với giá trị 16 bit thì byte MSB sẽ được truyền đi trước. Ví dụ: Với giá trị 0x1234 trong thanh ghi 16 bit, byte 0x12 sẽ được truyền đi trước rồi mới đến 0x34.

Trường function code có kích thước 1 byte, có nhiệm vụ cho server biết phải thực thi hành động gì. Giá trị function code từ 1 đến 255 (giá trị thập phân), với khoảng giá trị từ 128 - 255 dùng cho các exception response (tạm dịch: phản hồi ngoại lệ).

Mỗi trường data trong PDU sẽ có địa chỉ từ 0 đến 65535 (không nhầm lẫn với địa chỉ trong trường Additional address của ADU). Trường data có thể không có, khi đó sẽ có kích thước là 0, trong trường hợp này server sẽ không yêu cầu thông tin gì cả và function code khi đó sẽ định rõ hành động cần thực thi. Nếu không có lỗi xảy ra trong quá trình giao tiếp, trường data của ADU trong phản hồi từ server cho client sẽ bao gồm các data được yêu cầu. Nếu xảy ra lỗi, trường bao gồm mã lỗi ngoại lệ (exception code) sẽ được ứng dụng từ phía server (server application) dùng để xác định sẽ làm gì tiếp theo.

### Modbus transaction và PDU

Một Modbus transaction giữa client và server sẽ hoạt động như sau:

* **Bước 1**: Client khởi tạo một request với PDU = Function code + data request
* **Bước 2**: Server nhận request từ client. Server sẽ thực thi tuần tự các quá trình xác thực function code, xác định địa chỉ trường data (trong PDU), xác định giá trị cho trường data này và cuối cùng là thực thi Modbus function với function code tương ứng. Nếu không xảy ra bất cứ lỗi nào trong toàn bộ các quá trình này thì server sẽ phản hồi PDU = Function code + data response. Do quá trình hoàn toàn không xảy ra lỗi nên Function code phản hồi này của server cũng chính là Function code gởi từ client. Nếu xảy ra bất cứ các lỗi nào tương ứng với một trong các quá trình trên thì server sẽ phản hồi PDU gồm Exception Function code + Exception code (PDU mb\_excep\_rsp\_pdu định nghĩa bên dưới).
* **Bước 3**: Client nhận phản hồi và kết thúc quá trình.

Từ hoạt động trên, Modbus định nghĩa 3 loại PDU:

* MODBUS Request PDU, mb\_req\_pdu
* MODBUS Response PDU, mb\_rsp\_pdu
* MODBUS Exception Response PDU, mb\_excep\_rsp\_pdu

**mb\_req\_pdu = Function code (1 byte) + request data (n byte)**

Trường request data sẽ có kích thước cụ thể phụ thuộc vào loại function code và thường gồm các thông tin như giá trị biến, data offset, sub-function codes,...

**mb\_rsp\_pdu = Function code (1 byte) + response data (n byte)**

Trường response data sẽ có kích thước cụ thể phụ thuộc vào loại function code và thường gồm các thông tin như giá trị biến, data offset, sub-function codes,...

**mb\_excep\_rsp\_pdu = Exception Function code (1 byte) + request data (n byte)**

Exception Function code = Function code (1 byte) + 0x80

Khi đó Exception Function code sẽ có bit MSB bằng 1, các bit còn lại giống với Function code.

Exception code (1 byte) của mb\_excep\_rsp\_pdu sẽ được định nghĩa trong bảng "MODBUS Exception Codes".

### Mô hình dữ liệu của Modbus

Modbus xây dựng mô hình dữ liệu dựa trên các table (tạm dịch: bảng) có thuộc tính khác nhau, với 4 primary table (tạm dịch: bảng cơ sở) là:

| Primary table | Quyền | Kích thước | Chú thích |
| --- | --- | --- | --- |
| Discretes input | Chỉ đọc | 1 bit | Kiểu dữ liệu này có thể được cung cấp bởi một hệ thống I/O |
| Coils | Đọc/Ghi | 1 bit | Kiểu dữ liệu này có thể được thay đổi bởi phần mềm ứng dụng |
| Input registers | Chỉ đọc | 16 bit word | Kiểu dữ liệu này có thể được cung cấp bởi một hệ thống I/O |
| Holding registers | Đọc/Ghi | 16 bit word | Kiểu dữ liệu này có thể được thay đổi bởi phần mềm ứng dụng |

Function code
-------------

Có 3 loại Modbus Function code là Public, User-Defined và Reserved.

### **Public Function Codes**

**Public Function Codes** là loại function code được Modbus Organization định nghĩa và mang giá trị duy nhất với các tài liệu liên quan được công bố rõ ràng.

Bảng Public Function Code:

| Loại chức năng | Tên chức năng | Function code (giá trị thập phân) | Ghi chú |
| --- | --- | --- | --- |
| Data Access | Truy cập 1 bit | Ngõ đầu vào vật lý rời rạc | Đọc Discrete Inputs | 02 |  |
| Bits nội hoặc coil vật lý | Đọc coil | 01 |  |
| Ghi một coil | 05 |  |
| Ghi nhiều coil | 15 |  |
| Truy cập 16 bit | Thanh ghi vật lý đầu vào | Đọc input register | 04 |  |
| Thanh ghi nội bộ hoặc thanh ghi đầu ra vật lý | Đọc nhiều holding register | 03 |  |
| Ghi một thanh ghi | 06 |  |
| Ghi nhiều thanh ghi | 16 |  |
| Đọc/ghi nhiều thanh ghi | 23 |  |
| Ghi thanh ghi Mask | 22 |  |
| Đọc hàng đợi FIFO | 24 |  |
| Truy cập File record | Đọc file record | 20 |  |
| Ghi file record | 21 |  |
| Chuẩn đoán lỗi | Đọc lỗi trạng thái ngoại lệ | 07 | chỉ nối tiếp |
| Chẩn đoán lỗi | 08 | chỉ nối tiếp |
| Get Com event counter | 11 | chỉ nối tiếp |
| Get Com Event Log | 12 | chỉ nối tiếp |
| Báo Server ID | 17 | chỉ nối tiếp |
| Đọc ID thiết bị | 43 |  |
| Khác | Đóng gói Interface Transport | 43 |  |
|  | CANopen General Reference | 43 |  |

Lưu ý: Một số tài liệu sử dụng thuật ngữ *Force* thay cho *Write,* ví dụ như *Force Single Coil* thay cho *Write Single Coil* (Ghi một coil).

#### Ví dụ với Function code 01 (đọc coil)

Function code này cho phép đọc trạng thái của từ 1 đến 2000 coil của một thiết bị từ xa. mb\_req\_pdu (request PDU) khi đó sẽ có 2 byte cho biết địa chỉ của coil đầu tiên cần đọc (từ 0x0000 đến 0xFFFF) và 2 byte để cho biết số lượng coil cần đọc. mb\_req\_pdu sẽ định địa chỉ coil từ 0, tức là coil thứ 1 sẽ có địa chỉ 0. mb\_rsp\_pdu (response PDU) nếu đọc thành công sẽ có 1 byte mang giá trị cho biết số byte tương ứng số lượng coil cần đọc và số byte mang giá trị trạng thái của các coil cần đọc. Cụ thể, mb\_rsp\_pdu và mb\_rsp\_pdu sẽ có cấu trúc sau:

**mb\_req\_pdu**

* Function code: 0x01 (1 byte)
* Starting Address (Địa chỉ của coil đầu tiên cần đọc): Giá trị từ 0x0000 đến 0xFFFF (2 byte)
* Quantity of coils (Số lượng coil cần đọc): Giá trị từ 1 đến 2000 (0x7D0) (2 byte)

**mb\_rsp\_pdu**

* Function code: 0x01 (1 byte)
* Byte count: 1 byte
* Coil Status: n byte

Ví dụ của một mb\_req\_pdu và mb\_rsp\_pdu để đọc trạng thái coil thứ tự từ 20-38 sẽ bao gồm:

**mb\_req\_pdu**:

* Function code: 0x01
* Starting Address High byte: 0x00
* Starting Address Low byte: 0x13
* Quantity of Outputs High byte: 0x00
* Quantity of Outputs Low byte: 0x13

Starting Address (2 byte) sẽ có giá trị 0x0013, hay 19 trong hệ thập phân tương ứng với coil thứ tự 20.

Quantity of Outputs (2 byte) sẽ có giá trị 0x0013, hay 19 trong hệ thập phân tương ứng với 19 giá trị trạng thái coil cần đọc (từ coil 20-38).

**mb\_rsp\_pdu**:

* Function code: 0x01
* Byte Count: 0x03
* Outputs status 27-20: 0xCD
* Outputs status 35-28: 0x6B
* Outputs status 38-36: 0x05

Do cần đọc 19 giá trị (20-38) nên cần 3 byte để biểu diễn các giá trị trạng thái coil. Do đó Byte Count mang giá trị 0x03. Trạng thái coil 20 đến 27 có giá trị 0xCD hex, dạng nhị phân sẽ là 1100 1101. Khi đó giá trị của coil 27 sẽ là MSB, còn coil 20 sẽ là LSB. Với coil 28 đến 35 cũng tương tự. Với coil từ 36 - 38, trạng thái sẽ là 0x05, dạng nhị phân sẽ là 0000 0101. Khi đó giá trị trạng thái của coil 38 sẽ là bit thứ 3 tính từ phải sang, tức là 1, còn giá trị trạng thái của coil thứ 36 sẽ là bit LSB. 5 bit còn lại sẽ đều được ghi giá trị 0.

### User-Defined Function Codes

User-Defined Function Codes là Function code do người dùng tự định nghĩa. Có 2 dãy giá trị cho user-defined function codes là từ 65 đến 72 và từ 100 đến 110 (giá trị thập phân). Việc sử dụng User-Defined Function Codes sẽ không đảm giá trị là duy nhất.

### Reserved Function Codes

Reserved Function Codes là các Function code được sử dụng bởi các sản phẩm của một số công ty.

Exception response
------------------

Khi một client gởi request đến server sẽ xảy ra một trong 4 khả năng với request này:

* Nếu server nhận được request và thực thi bình thường, server sẽ trả về một normal response.
* Nếu server không nhận được request từ client do lỗi trên đường truyền thì sẽ không có response được phản hồi. Chương trình bên phía client cuối cùng sẽ gặp vấn đề timeout cho request bị lỗi này
* Nếu server nhận được request nhưng phát hiện một lỗi trên đường truyền (như lỗi parity LRC, CRC), thì cũng sẽ không trả về response. Chương trình bên phía client cuối cùng sẽ gặp vấn đề timeout cho request này.
* Nếu server nhận được request nhưng không thể xử lý request này (ví dụ như request yêu cầu đọc giá trị của một thanh ghi không tồn tại) thì server sẽ trả về một **exception response** để thông báo cho client biết về nguyên nhân của lỗi này.

Exception response message bao gồm 2 trường khác với một normal response message:

* Function Code: Bit MSB của function code trong Exception response sẽ có giá trị 1, tức là giá trị function code này lớn hơn function code của request message được gởi đến 1 giá trị là 0x80.
* Data: Server trả về exception code trong trường Data. Trường này định nghĩa nguyên nhân gây ra lỗi.

Các giá trị exception code:

| Code | Tên | Ý nghĩa |
| --- | --- | --- |
| 01 | ILLEGAL FUNCTION | Function code nhận được trong truy vấn không được server công nhận hoặc cho phép |
| 02 | ILLEGAL DATA ADDRESS | Địa chỉ data nhận được trong truy vấn là địa chỉ không được cho phép trên server. |
| 03 | ILLEGAL DATA VALUE | Giá trị trong trường data của query là giá trị không được server chấp nhận. |
| 04 | SERVER DEVICE FAILURE | Đã xảy ra lỗi không thể khôi phục trong khi server đang cố gắng thực hiện hành động được yêu cầu |
| 05 | ACKNOWLEDGE | Server đã nhận được request yêu cầu và nhưng cần một khoảng thời gian dài để xử lý request này. Response này được trả lại để ngăn lỗi timeout xảy ra cho client. |
| 06 | SERVER DEVICE BUSY | Server đang xử lý một chương trình cần thời gian dài, client cần gởi lại request sau. |
| 08 | MEMORY PARITY ERROR | Server cố gắng đọc file record và phát hiện lỗi parity trong bộ nhớ. Client có thể thử lại request. |
| 10 | GATEWAY PATH UNAVAILABLE | Chuyên dùng trong việc nối các gateway. Thường cho biết gateway đã bị cấu hình sai hoặc quá tải |
| 11 | GATEWAY TARGET DEVICE FAILED TO RESPOND | Chuyên dùng trong việc nối các gateway. Cho biết không có phản hồi nào từ server, thường có nghĩa rằng thiết bị không tồn tại trong mạng. |

Giao thức MODBUS over Serial Line
---------------------------------

Tiêu chuẩn Modbus cũng chuẩn hóa **MODBUS over Serial Line**, một giao thức trên đường truyền nối tiếp để trao đổi các Modbus request giữa một master và nhiều slave. Giao thức **MODBUS over Serial Line** là một giao thức dạng Master-Slave, nằm ở tầng Data Link (lớp 2) trong mô hình OSI. Với giao thức truyền thông Modbus ở tầng Application, mô hình client/server được sử dụng giữa các thiết bị kết nối trên mạng hoặc bus. Với giao thức Modbus over Serial line, vai trò của **client** được thực hiện bởi **Master**, còn vai trò của **server** được thực hiện bởi **Slave**.

Một bus nối tiếp hỗ trợ giao thức Modbus over Serial Line chỉ có một master và tối đa 247 slave, các slave trong mạng Modbus over Serial Line do đó bắt buộc phải có địa chỉ từ 1 đến 247 cho quá trình xác định địa chỉ trong quá trình truyền thông, và địa chỉ này phải là duy nhất. Master sẽ không có địa chỉ cụ thể. Quá trình truyền thông sẽ được khởi tạo bởi master, master chỉ có thể khởi tạo một Modbus transaction tại một thời điểm. Slave sẽ không bao giờ truyền dữ liệu nếu không nhận được request từ master, các slave cũng sẽ không bao giờ giao tiếp với nhau.

Master sẽ khởi tạo request đến slave ở hai chế độ là **unicast** và **broadcast**. Trong **chế độ unicast**, master sẽ gởi request đến slave có địa chỉ cần đến. Sau khi nhận request và xử lý hoàn tất, slave sẽ phản hồi lại message reply cho master. Như vậy trong chế độ này, một Modbus transaction sẽ bao gồm 2 message: một request từ master và một reply từ slave. Trong **chế độ broadcast**, master sẽ gởi request đến toàn bộ slave, với địa chỉ broadcast sẽ là 0 (đây không phải địa chỉ của master vì master không có địa chỉ cụ thể). Các broadcast request được dùng cho quá trình ghi lệnh (command) đến slave. Không có message phản hồi từ slave trả về cho master trong chế độ này và tất cả các slave bắt buộc phải nhận broadcast request từ master.

Việc ánh xạ PDU của Modbus với bus nối tiếp của giao thức Modbus over Serial Line sinh ra Modbus Serial Line PDU.

Modbus over Serial Line PDU = Address + PDU + CRC (hoặc LRC)

Với PDU = Function code + Data

* Trường Address chỉ bao gồm địa chỉ của slave.
* Trường PDU của Modbus over Serial Line có thành phần hoàn toàn như PDU của Modbus Application protocol
* Trường kiểm soát lỗi (Error check với CRC/LRC): Phương pháp tính toán giá trị cho trường này phụ thuộc vào phương pháp truyền với giao thức Modbus Serial Line là ASCII hay RTU.

Trên tầng Physical (tầng 1), **MODBUS over Serial Line** triển khai với RS485 hoặc RS232, với TIA/EIA-485 2 dây (TIA/EIA-485 Two-Wire interface) là phổ biến nhất. RS485 4 dây (RS485 Four-Wire interface) cũng có thể được dùng để triển khai. TIA/EIA-232-E (RS232) cũng có thể được sử dụng nhưng chỉ dùng cho các ứng dụng giao tiếp điểm-điểm tầm ngắn. MODBUS over Serial Line có 2 chế độ truyền là **RTU** và **ASCII** tương ứng với 2 loại **Modbus RTU** và **Modbus ASCII**.

### Modbus RTU

Mỗi 1 byte (8 bit) data/message của Modbus RTU truyền đi sẽ có định dạng tổng cộng 11 bit bao gồm:

* 1 start bit
* 8 bit data/message, bit LSB được truyền trước
* 1 bit parity
* 1 stop bit

Một frame truyền của Modbus RTU sẽ bao gồm

| Địa chỉ slave | Function Code | Data | CRC |
| --- | --- | --- | --- |
| 1 byte | 1 byte | 0 đến 252 byte | 2 byte gồm 1 byte CRC thấp (trước) và 1 byte CRC cao (sau) |

Để đảm bảo quá trình truyền thông trọn vẹn, thời gian cách nhau của các frame truyền Modbus RTU nên ít nhất bằng thời gian truyền của 3.5 ký tự và thời gian cách nhau để truyền 2 ký tự liên tiếp tối đa bằng thời gian truyền của 1.5 ký tự.

Ví dụ với baudrate bằng 19200 bps, thời gian truyền 3.5 (t3.5) và 1.5 (t1.5) ký tự sẽ là (lưu ý 1 ký tự được biểu diễn bằng mã ASCII với 8 bit (1 byte) thì sẽ cần 11 bit để truyền):

{\displaystyle t3.5=3.5\*\left({\frac {11\*1000}{19200}}\right)=2.005ms}

{\displaystyle t1.5=1.5\*\left({\frac {11\*10^{6}}{19200}}\right)=859.375us}

Modbus RTU khuyến khích sử dụng giá trị 750µs cho thời gian t1.5 và 1.750ms cho t3.5.

### Modbus ASCII

Khi giao thức MODBUS Serial Line hoạt động ở chế độ ASCII, mỗi byte sẽ được truyền đi dưới dạng 2 ký tự ASCII.

Thành phần frame dữ liệu của Modbus ASCII bao gồm: 1 bit start, 7 bit dữ liệu với bit LSB được gởi trước, 1 bit để kiểm tra chẵn lẻ, 1 stop bit nếu dùng parity hoặc 2 bit nếu không dùng parity. Bên cạnh frame dữ liệu, Modbus ASCII còn dùng thêm trường kiểm tra lỗi hình thành theo phương pháp Longitudinal Redundancy Check (tạm dịch: Kiểm dư theo chiều dọc). Modbus ASCII message bắt đầu bởi dấu hai chấm (":", với mã ASCII là 0x3A) và kết thúc bởi cặp ký dự dòng mới ở cuối là CR/LF (mã ASCII là 0x0D và 0x0A).

#### Định dạng frame của Modbus ASCII

| Tên | Chiều dài (byte) | Hàm số |
| --- | --- | --- |
| Start | 1 | Bắt đầu bằng dấu hai chấm `:` (Giá trị hex ASCII là `3A`) |
| Address | 2 | Địa chỉ station |
| Function | 2 | Cho biết các mã chức năng như đọc coil/đầu vào |
| Data | *n* × 2 | Dữ liệu + độ dài sẽ được điền tùy thuộc vào loại message |
| LRC | 2 | Checksum (Longitudinal redundancy check) |
| End | 2 | Cặp Carriage return + line feed (CR/LF) (các giá trị ASCII `0D`, `0A`) |

Định dạng frame của Modbus ASCII này chủ yếu được sử dụng trên các đường nối tiếp không đồng bộ 7 hoặc 8-bit.

Địa chỉ, hàm, dữ liệu và LRC đều là các cặp ký tự có thể đọc được trong hệ thập lục phân viết hoa đại diện cho các giá trị 8 bit (0–255). Ví dụ, 122 (7 × 16 + 10) sẽ được biểu thị là `7A`.

LRC được tính bằng tổng các giá trị 8 bit (không bao gồm ký tự đầu và cuối), phủ định (phần bù của hai) và được mã hóa dưới dạng giá trị 8 bit. Ví dụ: nếu địa chỉ, hàm và dữ liệu mã hóa thành 247, 3, 19, 137, 0 và 10, thì tổng của chúng là 416. Phần bù của hai (−416) được cắt thành 8 bit là 96 (ví dụ: 256 × 2 - 416), sẽ được biểu diễn dưới dạng `60` trong hệ thập lục phân. Do đó khung sau `:F7031389000A60<CR><LF>`. Nó chỉ được chỉ định để sử dụng làm tổng kiểm tra: bởi vì nó được tính toán trên dữ liệu được mã hóa chứ không phải các ký tự được truyền, đặc tính 'Dọc' của nó không có sẵn để sử dụng với các bit chẵn lẻ để xác định lỗi một bit.

### Kiểm soát lỗi trên đường truyền

Trường CRC gồm 2 byte với giá trị được tính toán bởi bên truyền đi rồi thêm giá trị CRC này vào PDU. Đa thức sinh (generating polynomial) quy định cho Modbus tên là CRC-16-IBM: *x*16 + *x*15 + *x*2 + 1.

Modbus TCP
----------

*Modbus TCP/IP* hoặc *Modbus TCP* thực hiện việc truyền thông qua mạng TCP/IP, kết nối qua cổng 502. Modbus TCP/IP không yêu cầu tính toán checksum, vì các lớp thấp hơn đã hỗ trợ checksum.

| Tên | Chiều dài (byte) | Tính năng |
| --- | --- | --- |
| Transaction identifier | 2 | Để đồng bộ hóa giữa các thông báo của máy chủ và máy khách |
| Protocol identifier | 2 | 0 cho Modbus / TCP |
| Length field | 2 | Số byte còn lại trong khung này |
| Unit identifier | 1 | Địa chỉ máy chủ (255 nếu không được sử dụng) |
| Function code | 1 | Function code như trong các variant khác |
| Data bytes | *NS* | Dữ liệu dưới dạng phản hồi hoặc lệnh |

Định dạng frame của Modbus TCP này chủ yếu được sử dụng trên mạng Ethernet.

*Unit identifier* được sử dụng với các thiết bị Modbus/TCP là tổng hợp của một số thiết bị Modbus, ví dụ như trên các cổng Modbus/TCP đến Modbus RTU. Trong trường hợp đó, unit identifier cho biết địa chỉ server của thiết bị sau gateway. Các thiết bị hỗ trợ Modbus/TCP thường bỏ qua Unit Identifier.

Đối với các giao thức sử dụng Ethernet như Modbus TCP, bất kỳ thiết bị nào cũng có thể gửi lệnh Modbus do đó tất cả đều có thể hoạt động như một client, mặc dù thông thường chỉ có một thiết bị hoạt động như một client.

Ngoài ra còn có 2 biến thể tương tự Modbus TCP được triển khai bao gồm:

* *Modbus over TCP/IP hoặc Modbus over TCP hoặc Modbus RTU/IP:* Đây là một biến thể Modbus khác với Modbus TCP ở việc checksum đã bao gồm trong gói tin (payload) như với Modbus RTU.
* *Modbus over UDP:* Sử dụng Modbus qua UDP trên mạng IP, và loại bỏ các header được yêu cầu của TCP.

Các phiên bản khác của Modbus
-----------------------------

Các biến thể khác của giao thức Modbus bao gồm: 

* *Modbus Plus (Modbus+, MB + hoặc MBP):* Modbus Plus là độc quyền của Schneider Electric và không giống như các biến thể khác, nó hỗ trợ giao tiếp ngang hàng giữa nhiều clients. Nó yêu cầu một bộ đồng xử lý chuyên dụng (dedicated co-processor) để xử lý hỏi vòng nhanh như HDLC. Modbus Plus sử dụng cáp xoắn trên đường truyền vật lý ở tốc độ 1 Mbit/s và máy biến áp cách ly tại mỗi node, điều này làm cho tín hiệu của nó ở dạng kích hoạt cạnh (transition/edge-triggered) thay vì kích hoạt mức điện áp (voltage/level-triggered). Cần có phần cứng đặc biệt để kết nối Modbus Plus với máy tính, thường là một thẻ được làm cho bus ISA, PCI hoặc PCMCIA.
* *Pemex Modbus:* Đây là một phần mở rộng của Modbus tiêu chuẩn, hỗ trợ lịch sử dữ liệu và luồng dữ liệu. Nó được thiết kế cho công ty dầu khí Pemex để sử dụng trong kiểm soát quá trình và chưa bao giờ được chấp nhận rộng rãi.
* *Enron Modbus:* Đây là một phần mở rộng khác của Modbus tiêu chuẩn do Enron Corporation phát triển với sự hỗ trợ cho các biến số nguyên và dấu phẩy động 32-bit cũng như lịch sử dữ liệu và luồng dữ liệu. Các kiểu dữ liệu được ánh xạ bằng cách sử dụng các địa chỉ chuẩn. Dữ liệu lịch sử đáp ứng tiêu chuẩn công nghiệp của Viện Dầu khí Hoa Kỳ (American Petroleum Institute, viết tắt API) về cách dữ liệu được lưu trữ.[*cần dẫn nguồn*]
* *Modbus Plus:* dù có tên gọi Modbus nhưng Modbus Plus không phải là một biến thể của Modbus. Nó là một giao thức khác, liên quan đến token passing. Đây là đặc điểm kỹ thuật độc quyền của Schneider Electric, mặc dù nó chưa được công bố chứ không phải được cấp bằng sáng chế. Nó thường được triển khai bằng cách sử dụng chipset tùy chỉnh chỉ dành cho các đối tác của Schneider.

Mô hình dữ liệu và lời gọi hàm giống hệt nhau đối với 4 biến thể đầu tiên của giao thức; chỉ có sự đóng gói dữ liệu là khác nhau. Tuy nhiên, các biến thể, đặc biệt là các định dạng frame của chúng đều không tương thích với nhau.

Trên Modbus RTU, Modbus ASCII và Modbus Plus (tất cả đều là mạng nhiều dây cáp đơn RS-485), chỉ node chỉ định làm client mới có thể bắt đầu một lệnh. Tất cả các thiết bị khác là server và phản hồi các yêu cầu và lệnh.

### JBUS mapping

Một *giao thức thực tế khác* có liên quan chặt chẽ đến Modbus xuất hiện sau nó, và được xác định bởi thương hiệu PLC April Automates, kết quả của nỗ lực hợp tác giữa các công ty Pháp Renault Automation và Merlin Gerin et Cie vào năm 1985: **JBUS**. Sự khác biệt giữa Modbus và JBUS tại thời điểm đó (số lượng thực thể, trạm máy chủ) hiện không còn liên quan vì giao thức này gần như biến mất với dòng PLC tháng 4 mà AEG Schneider Automation mua vào năm 1994 và sau đó đã lỗi thời. Tuy nhiên cái tên JBUS đã tồn tại ở một mức độ nào đó.

JBUS hỗ trợ các mã chức năng 1, 2, 3, 4, 5, 6, 15 và 16 và do đó tất cả các thực thể được mô tả ở trên. Tuy nhiên, cách đánh số khác với JBUS:

* Số và địa chỉ trùng nhau: thực thể # *x* có địa chỉ *x* trong khung dữ liệu.
* Do đó, số thực thể không bao gồm loại thực thể. Ví dụ: giữ thanh ghi # 40010 trong Modbus sẽ giữ thanh ghi # 9, nằm ở địa chỉ 9 trong JBUS.
* Số 0 (và do đó địa chỉ 0) không được hỗ trợ. Máy chủ không nên triển khai bất kỳ dữ liệu thực nào tại số và địa chỉ này và nó có thể trả về giá trị null hoặc gây ra lỗi khi được yêu cầu.

Lịch sử phát triển
------------------

Các port Modbus chuẩn của các bộ Modicon controller sử dụng đầu nối tương thích RS-232C với các quy định về chân kết nối, loại cáp, mức tín hiệu, tốc độ baud và parity check. Các bộ controller này có thể kết nối mạng trực tiếp hoặc thông qua modem.

Vào ngày 9 tháng 7 năm 2020, hội đồng Modbus Organization chính thức công bố sử dụng mô hình client/server thay cho mô hình maser/slave đồng thời cũng bỏ việc sử dụng mô hình query và response trước đó khi nói về hoạt động của Modbus. Khác với mô hình client/server hiện tại khi client sẽ khởi tạo ADU, ở mô hình master/slave trước đó, chỉ có một thiết bị làm master là có thể khởi tạo quá trình truy vấn (query). Ở mô hình master/slave này, các thiết bị khác hoạt động như những slave trong hệ thống, sẽ phản hồi lại master bằng cách cung cấp dữ liệu được yêu cầu bởi master hoặc thực hiện một hành động khác tương ứng trong query. Một thiết bị master tiêu biểu ba gồm bộ xử lý trung tâm (host processors) và một bản lập trình (programming panel). Thiết bị slave tiêu biểu là các PLC.

Master có thể định địa chỉ của các slave hoặc phát (broadcast) message (gói tin) tới tất cả slave. Tùy theo địa chỉ tương ứng với slave mà slave đó sẽ phản hồi message trở lại. Message của master sẽ có định dạng bao gồm địa chỉ của slave cần truy vấn, một function code để định thao tác cần slave thực thi, dữ liệu cần gởi đi, và một trường kiểm tra lỗi. Message phản hồi của slave cũng có định dạng tương tự master với trường địa chỉ của slave đó, function code, dữ liệu trả về và một trường kiểm tra lỗi. Nếu không xảy ra lỗi trong quá trình nhận message truy vấn từ master, trường function code của slave sẽ có giá trị như function code từ message của master, trường dữ liệu trả về sẽ là giá trị mà slave thu được như giá trị trạng thái hay giá trị thanh ghi. Nếu xảy ra lỗi, trường function code sẽ có giá trị để master biết được rằng đây là một phản hồi lỗi từ slave, và trường data sẽ có mã code để mô tả lỗi này. Trường kiểm tra lỗi sẽ cho master biết được nội dung message có hợp lệ không.

Hạn chế
-------

* Vì Modbus được thiết kế vào cuối những năm 1970 để giao tiếp với các bộ PLC, nên số lượng kiểu dữ liệu bị giới hạn trong phạm vi những kiểu dữ liệu mà PLC có thể hiểu được vào thời điểm đó. Các đối tượng nhị phân lớn không được hỗ trợ.
* Không có phương pháp tiêu chuẩn cho một node để tìm mô tả (description) của một data object, ví dụ, để xác định xem một giá trị thanh ghi có đại diện cho nhiệt độ từ 30 đến 175 độ hay không.
* Vì Modbus là một giao thức dạng server/client (trước đây là master/slave), không có cách nào để một thiết bị trường báo cáo một ngoại lệ (exception) (ngoại trừ qua Ethernet TCP/IP, được gọi là open-mbus) - node client phải thường xuyên thực hiện quá trình hỏi vòng tuần tự (polling) các thiết bị trường để tìm kiếm sự thay đổi trong dữ liệu. Điều này làm băng thông và thời gian xử lý trong mạng, đặc biệt là ảnh hưởng đến các ứng dụng với chi phí băng thông đắt, chẳng hạn như qua liên kết vô tuyến tốc độ bit thấp.
* Trên một data link, chỉ có thể đánh địa chỉ cho 247 thiết bị Modbus, điều này giới hạn số lượng thiết bị trường có thể được kết nối với trạm mẹ (parent station) (tuy nhiên Ethernet TCP/IP là một ngoại lệ).
* Các đường truyền Modbus phải liền nhau, điều này giới hạn các loại thiết bị truyền thông từ xa với những thiết bị có thể bộ đệm dữ liệu để tránh các khoảng trống trong quá trình truyền.
* Bản thân giao thức Modbus không cung cấp bảo mật chống lại các lệnh trái phép hoặc đánh chặn dữ liệu.

Xem thêm
--------

* CAN bus

Tài liệu tham khảo
------------------

* MODBUS Application Protocol (2012). *Modbus application protocol specification V1.1b3* (PDF).
* MODBUS over Serial Line protocol (2006). *MODBUS over Serial Line Specification & Implementation guide V1.02* (PDF).
* MODICON, Inc. (1996). *Modicon Modbus Protocol Reference Guide/Modbus Over Serial Line (for legacy application only)* (PDF).

Chú thích
---------

1. 1 2 3  MODBUS Application Protocol 2012, tr. 2.
2. ↑  MODICON, Inc. 1996, "Preface"
3. ↑  Drury, Bill (2009). *Control Techniques Drives and Controls Handbook* (PDF) (ấn bản 2). Institution of Engineering and Technology. tr. 508–.
4. ↑  "Modbus FAQ". *Modbus*. Modbus Organization, Inc. Truy cập ngày 1 tháng 11 năm 2012.
5. ↑  "About Modbus Organization". *Modbus*. Modbus Organization, Inc. Truy cập ngày 8 tháng 11 năm 2012.
6. 1 2  MODBUS Application Protocol 2012, tr. 3, "4.1 Protocol description"
7. 1 2 3  MODBUS Application Protocol 2012, tr. 5, "4.1 Protocol description"
8. ↑  MODBUS Application Protocol 2012, tr. 7, "4.4 MODBUS Addressing model"
9. 1 2  MODBUS Application Protocol 2012, tr. 4, "4.1 Protocol description"
10. ↑  MODBUS Application Protocol 2012, tr. 9, "Figure 9 MODBUS Transaction state diagram"
11. ↑  MODBUS Application Protocol 2012, tr. 6, "4.3 MODBUS Data model"
12. 1 2 3  MODBUS Application Protocol 2012, tr. 10, "5 Function Code Categories"
13. 1 2  MODBUS Application Protocol 2012, tr. 11
14. ↑  Clarke, Gordon; Reynders, Deon (2004). *Practical Modern Scada Protocols: Dnp3, 60870.5 and Related Systems*. Newnes. tr. 47–51. ISBN 0-7506-5799-5.
15. ↑  MODBUS Application Protocol 2012, tr. 12, "6.1 01 (0x01) Read Coils"
16. 1 2  MODBUS Application Protocol 2012, tr. 47, "7 MODBUS Exception Responses"
17. ↑  MODBUS Application Protocol 2012, tr. 48, "7 MODBUS Exception Responses"
18. ↑  MODBUS over Serial Line protocol 2006, tr. 4
19. 1 2 3  MODBUS over Serial Line protocol 2006, tr. 5
20. 1 2 3 4  MODBUS over Serial Line protocol 2006, tr. 8
21. 1 2  MODBUS over Serial Line protocol 2006, tr. 7
22. 1 2  MODBUS over Serial Line protocol 2006, tr. 12
23. 1 2 3  MODBUS over Serial Line protocol 2006, tr. 13, "2.5.1.1 MODBUS Message RTU Framing"
24. ↑  MODBUS over Serial Line protocol 2006, tr. 16, "2.5.2 The ASCII Transmission Mode"
25. 1 2 3  modicon.com 2000, tr. 6Lỗi sfn: không có mục tiêu: CITEREFmodicon.com2000 (trợ giúp)
26. ↑  MODBUS over Serial Line protocol 2006, tr. 39, "Calculation algorithm of the CRC 16"
27. ↑  *Modbus Messaging on TCP/IP Implementation Guide V1.0b*
28. ↑  "Java Modbus Library - About". 2010. Truy cập ngày 7 tháng 2 năm 2017.
29. ↑  "What is the difference between Modbus and Modbus Plus?". Schneider Electric. Truy cập ngày 7 tháng 2 năm 2017.
30. ↑  "Simply Modbus - About Enron Modbus". Simply Modbus. Truy cập ngày 7 tháng 2 năm 2017.
31. ↑  "Modbus Plus - Modbus Plus Network - Products overview - Schneider Electric United States". Schneider-electric.com. Truy cập ngày 3 tháng 1 năm 2014.
32. 1 2 3  modicon.com 2000, tr. 41.1.1 Transactions on Modbus NetworksLỗi sfn: không có mục tiêu: CITEREFmodicon.com2000 (trợ giúp)
33. ↑  "PRESS RELEASE: Modbus Organization Replaces Master-Slave with Client-Server" (PDF). *modbus.org*. ngày 9 tháng 7 năm 2020. Truy cập ngày 9 tháng 8 năm 2021.
34. ↑  modbus.org 1996, tr. 51.1.1 Transactions on Modbus NetworksLỗi sfn: không có mục tiêu: CITEREFmodbus.org1996 (trợ giúp)
35. 1 2  modicon.com 2000, tr. 51.1.1 Transactions on Modbus NetworksLỗi sfn: không có mục tiêu: CITEREFmodicon.com2000 (trợ giúp)
36. ↑  "Modbus Organization Replaces Master-Slave with Client-Server" (PDF). *Modbus Organization, Inc*. Truy cập ngày 7 tháng 8 năm 2021.
37. ↑  Palmer; Shenoi, Sujeet biên tập (25 tháng 3 năm 2009). *Critical Infrastructure Protection III*. Third IFIP WG 11. 10 International Conference. Hanover, New Hampshire: Springer. tr. 87. ISBN 978-3-642-04797-8.

Liên kết ngoài
--------------

* Trang web chính thức

**Tài liệu kĩ thuật**

* Modbus over serial line V1.0 Tài liệu về phiên bản cũ hơn của *MODBUS over Serial Line V1.02*
* *Modicon Modbus Protocol Reference Guide* (hay *MODBUS Over Serial Line FOR LEGACY APPLICATIONS ONLY,* theo tên gọi của *Modbus Organization*): Tài liệu 121 trang; 1996. Tài liệu hiện tại đã lỗi thời và chỉ được tham chiếu cho các hệ thống Modbus cũ

Khác
* Modbus for Field Technicians
* Modbus tutorial | Modbus protocol, ASCII & RTU Frames, Modbus Working RF Wireless World