Kỹ thuật

Góc kỹ thuật

2020.10.01
Công nghiệp

Modbus - Phần 2: Mô tả chung về giao thức Modbus

1. Mô tả giao thức

      Giao thức Modbus được định nghĩa là một đơn vị dữ liệu giao thức (Protocol Data Unit - PDU) đơn giản nằm trong Lớp ứng dụng trong mô hình tham chiếu OSI hay TCP/IP, độc lập với các lớp dưới.
Việc áp dụng Modbus trên các đường bus (Ví dụ : RS-485) hay đường mạng (Ví dụ: Ethernet) cụ thể có thể bổ sung thêm một số trường dữ liệu như phần “Thông tin bổ sung” hay phần “Kiểm tra lỗi” để tạo thành đơn vị dữ liệu ứng dụng (Application Data Unit - ADU).

      Cấu trúc PDUADU của Modbus được mô tả cụ thể như bên dưới:

Hình 1. Cấu trúc cơ bản của ADU và PDU

        PDU bao gồm các vùng dữ liệu:

Trường mã chức năng (Function code field): Trường mã chức năng của Modbus PDU được mã hóa bằng một byte. Mã chức năng có giá trị hợp lệ nằm trong phạm vi 1 ... 255 thập phân (phạm vi 128 - 255 được dành riêng và được sử dụng cho các phản hồi ngoại lệ). Khi một thông điệp được gửi từ Client đến Server, mã chức năng này sẽ cho Server biết loại hành động nào sẽ thực hiện.

Trường dữ liệu (Data field) : Trường Dữ liệu của thông điệp được gửi từ Client đến Server chứa thông tin bổ sung mà Server sử dụng để thực hiện hành động được xác định bởi mã chức năng. Dữ liệu này có thể bao gồm các mục như địa chỉ đăng ký, số lượng mục cần xử lý và số byte dữ liệu thực tế trong trường.

        ADU được xây dựng bởi người sử dụng giao thức Modbus. ADU có thể khác nhau tùy theo loại Modbus. Có thể thêm vào một số thông tin bổ sung để Server có thể thực hiện chính xác hành động được xác định bởi mã chức năng. Trong thực tế, thông tin có thể bao gồm địa chỉ Client, địa chỉ thanh ghi cần thao tác, số lượng thanh ghi và số byte dữ liệu trên bộ nhớ thiết bị.

        Ví dụ dành cho việc đối chiếu các cấu trúc ADU tiêu biểu của Modbus RTU và Modbus TCP/IP:

Hình 2. Cấu trúc của Modbus TCP/IPModbus RTU

        Phần tiếp theo là các phép tính đơn giản của việc tính kích thước của các thành phần trong một ADU.

        Đầu tiên, kích thước của PDU được giới hạn bởi kích thước của gói tin chứa Modbus được áp dụng với chuẩn vật lý là Serial.

        Vì thế nên :

Kích thước PDU = 256 bytes - Địa chỉ máy chủ (ServerID) (1 byte) - CRC (2 byte) = 253 bytes

        Hiện nay Modbus được sử dụng trong các kết nối như RS-232/RS-485 hay TCP/IP nên kích thước của một ADU có thể được tính toán như sau:

→ RS232 / RS485 ADU = 253 bytes + Server address (1 byte) + CRC (2 bytes) = 256 bytes.

→ TCP MODBUS ADU = 253 bytes + MBAP (7 bytes) = 260 bytes.

        Trong quá trình truyền nhận:

❖ Nếu không có lỗi xảy ra, chức năng được yêu cầu trong Modbus ADU được xác nhận là phù hợp, Server sẽ gửi lại thông tin phản hồi có chứa dữ liệu được yêu cầu đến Client.

Hình 3. Truyền nhận bằng Modbus (Không có lỗi)

❖ Nếu có lỗi xảy ra, Server sẽ trả về một thông tin phản hồi chứa các thông báo về lỗi đó.

Hình 4. Truyền nhận bằng Modbus (Khi gặp lỗi)

2. Mã hóa dữ liệu

       Modbus sử dụng phương thức “big-Endian” để biểu diễn các địa chỉ và dữ liệu.
Trong cơ chế ”big-Endian” (xuất phát từ "big-end" nghĩa kết thúc lớn hơn), byte đầu tiên trong chuỗi biểu diễn nhị phân sẽ được ghi trước. Điều này có nghĩa là khi sử dụng Modbus để truyền đi một thông điệp có kích thước lớn hơn 1 byte thì thứ tự truyền các byte sẽ như sau:

Kích thước Giá trị
16 - bits 0x1234 Byte được gửi đầu tiên là 0x12 sau đó đến 0x34

3. Mô hình dữ liệu (Data Model) của Modbus

        Dữ liệu của Modbus được chia thành 4 loại chính với từng đặc điểm riêng biệt:

Loại dữ liệu Kiểu dữ liệu Quyền truy cập Mô tả
Discretes Input Single bit

 

Read-Only

 

Ngõ vào digital (DI) của hệ thống

(chỉ có thể đọc)

Coils Single bit

 

Read-Write

 

Ngõ ra digital (DO) của hệ thống

(có thể đọc và thay đổi giá trị)

Input Registers

 

16-bit word

 

Read-Only

 

Ngõ vào Analog (AI) của hệ thống

(chỉ có thể đọc)

Holding Registers

 

16-bit word

 

Read-Write

 

Thanh ghi giá trị của hệ thống

(có thể đọc và thay đổi giá trị)

      • Đối với từng loại dữ liệu, Modbus cho phép lựa chọn đến 65536 địa chỉ khác nhau ( 2^16 giá trị tương ứng với 2 byte ).
      • Các hoạt động đọc hoặc ghi có thể thực hiện trên nhiều địa chỉ dữ liệu liên tiếp nhau cùng lúc.
      • Giới hạn kích thước dữ liệu phụ thuộc vào từng loại mã chức năng .
      • Modbus sẽ tham chiếu đến địa chỉ vật lý trong bộ nhớ của thiết bị.
      • Địa chỉ tham chiếu của Modbus PDU là số nguyên không dấu bắt đầu từ 0.

4. Cấu trúc tổ chức thanh ghi trên Modbus

        Giao thức Modbus xác định địa chỉ của các thanh ghi theo nguyên tắc sau:

❖ Trong phần PDU, mỗi dữ liệu có thể được đánh dấu địa chỉ từ 0 đến 65535 ( 16-bit interger).

❖ Trong mô hình dữ liệu của Modbus như đã giới thiệu ở phần trên, bao gồm 4 loại dữ liệu riêng biệt, mỗi thanh ghi tương ứng từng loại dữ liệu sẽ đánh dấu địa chỉ từ 1 đến N. (N phụ thuộc vào từng loại Mã chức năng).

❖ Việc áp dụng mô hình dữ liệu của Modbus lên bộ nhớ vật lý của thiết bị sẽ phụ thuộc vào nhà sản xuất thiết bị.

        Ví dụ minh họa sau sẽ làm rõ cách mà Modbus PDU truy cập đến mô hình dữ liệu của Modbus, cũng như việc ánh xạ mô hình dữ liệu của Modbus lên bộ nhớ của thiết bị:

Hình 5. Mô hình dữ liệu của Modbus

5. Cách thức hoạt động của Modbus

        Quy trình làm việc của Modbus trên Server được mô tả theo sơ đồ như sau :

Hình 6. Quy trình làm việc của Modbus trên Server

        Trong quá trình truyền nhận dữ liệu, có thể xảy ra các trường hợp sau đây:

      • Server nhận được yêu cầu từ Client mà không có lỗi giao tiếp và có thể thực hiện chức năng bình thường, Server sẽ trả về phản hồi bình thường chứa các thông tin Client yêu cầu .
      • Server không nhận được yêu cầu từ Client do lỗi giao tiếp nên không thể thực hiện chức năng . Không có phản hồi nào được gửi về Client. Client sẽ có 1 khoảng thời gian chờ phản hồi từ Server (gọi là timeouts). Khi hết timeouts, Client sẽ báo lỗi hoặc tiếp tục xử lý tác vụ khác tùy theo người sử dụng.
      • Server nhận được yêu cầu từ Client và nhưng phát hiện lỗi giao tiếp (parity, LCR, CRC,…) . Không có phản hồi nào được gửi về Client. Client sẽ có 1 khoảng thời gian chờ phản hồi từ Server. Khi hết thời gian timeouts, Client sẽ báo lỗi hoặc tiếp tục xử lý tác vụ khác tùy theo người sử dụng.
      • Server nhận được yêu cầu từ Client mà không có lỗi giao tiếp nhưng không thể xử lý được các chức năng mà Client yêu cầu. Server sẽ trả về phản hồi ngoại lệ chứa các thông tin về lỗi đó.

Hình 7. Modbus PDU

Một phản hồi ngoại lệ gồm hai thành phần như sau:

      • Mã chức năng ngoại lệ (Exception Function Code): Trong một phản hồi bình thường, Server sẽ gửi lại Mã chức năng của do Client yêu cầu. Tất cả các Mã chức năng có bit đầu tiên bằng 0. Tuy nhiên, trong một phản hồi ngoại lệ, Server đặt MSB của Mã chức năng thành 1 (Exception Function Code = Function Code + 0x80). Mã chức năng này giúp Client có thể biết được đoạn phản hồi được gửi là một phản hồi ngoại lệ, nghĩa là đang có lỗi xảy ra, và Client sẽ kiểm tra giá trị của Mã ngoại lệ.
      • Mã ngoại lệ (Exception Code): Trong phản hồi bình thường, Server sẽ trả về dữ liệu hoặc số liệu thống kê trong trường dữ liệu (bất kỳ thông tin nào được Client yêu cầu). Tuy nhiên, trong một phản hồi ngoại lệ (có lỗi), Server sẽ trả về Mã ngoại lệ để mô tả lỗi xảy ra ở Server.

Sau đây là ví dụ về phản hồi ngoại lệ từ Server gửi đến Client khi xảy ra lỗi

Yêu cầu từ Client Phản hồi từ Server
Mô tả Mã code (Hex) Mô tả Mã code (Hex)
Mã chức năng 01 Mã chức năng ngoại lệ 81
Địa chỉ bắt đầu, byte cao 04 Mã ngoại lệ 02
Địa chỉ bắt đầu, byte thấp A1
Số Input, byte cao 00
Số Input, byte thấp 01

Mô tả :

        • Khi Client gửi yêu cầu đến Server, PDU bao gồm Mã chức năng và Dữ liệu yêu cầu.
      • Theo đó Mã chức năng (0x01) tương ứng với chức năng Đọc trạng thái Coil.
      • Client yêu cầu bắt đầu đọc tại địa chỉ 1185 (0x04A1) và số lượng Coil cần đọc là 1 (0x0001).
      • Do xảy ra lỗi nên Server sẽ trả về một phản hồi ngoại lệ với Mã chức năng ngoại lệ là 0x81.
      • Lỗi xảy ra do địa chỉ cần đọc không tồn tại nên Mã ngoại lệ tương ứng là 0x02.

Hình 8. Sơ đồ ví dụ của một phản hồi ngoại lệ khi có lỗi ở Server

        Mỗi lỗi sẽ có một Mã ngoại lệ tương ứng.
        Bảng dưới đây mô tả một số loại lỗi có thể xảy ra và Mã ngoại lệ của nó.

Code Tên lỗi Mô tả
0x01 ILLEGAL FUNCTION Mã chức năng do Client yêu cầu không phải là một hành động mà Server có thể thực hiện hoặc mã chức năng không hợp lệ.
0x02 ILLEGAL DATA ADDRESS

 

Địa chỉ dữ liệu cần truy vấn không phải là địa chỉ Server có thể truy cập.

Địa chỉ có thể không tồn tại hoặc số lượng địa chỉ muốn truy cập cùng lúc vượt quá số lượng cho phép.

0x03 ILLEGAL DATA VALUE Giá trị chứa trong trường dữ liệu không hợp lệ. Ví dụ, độ dài của dữ liệu vượt quá mức cho phép.
0x04 SERVER DEVICE FAILURE Xảy ra lỗi không thể giải quyết khi Server cố gắng thực hiện hành động được yêu cầu.
0x05 ACKNOWLEDGE Server đã chấp nhận yêu cầu và đang xử lý, nhưng sẽ cần một khoảng thời gian dài để thực hiện. Phản hồi này được trả về để đề phòng timeouts ở Client.
0x06 SERVER DEVICE BUSY

 

Thông báo Server đang xử lý lệnh tiêu tốn thời gian dài. Client sẽ truyền lại tin nhắn sau khi Server rảnh.
0x08 MEMORY PARITY ERROR

 

Xảy ra khi thực hiện mã chức năng 20 và 21 (dùng để đọc và ghi file lưu).

Server đã đọc file lưu, nhưng phát hiện ra lỗi chẵn lẻ trong bộ nhớ.

0x0A GATEWAY PATH UNAVAILABLE

 

Không thể phân bố đường dẫn để liên lạc giữa cổng đầu vào và đầu ra. Thông thường là do cổng bị cấu hình sai hoặc quá tải.
0x0B GATEWAY TARGET DEVICE FAILED TO RESPOND

 

Không có phản hồi nào được từ thiết bị. Thông thường có nghĩa là thiết bị cần kết nối không có trên mạng

7. Một số Mã chức năng thông dụng của Modbus

        Mã chức năng của Modbus PDU được mã hóa bằng một byte. Mã hợp lệ nằm trong phạm vi từ 1 đến. 255 trong hệ số thập phân (phạm vi 128 - 255 được dành riêng và được sử dụng cho các phản hồi ngoại lệ).
        Bảng sau đây thống kê một số mã chức năng trong Modbus PDU:

Hình 9. Thông tin của một vài chức năng thường được sử dụng trong thực tế

❖ Chức năng 01: Đọc trạng thái Coil - Đọc trạng thái On/Off của Coil (Read Coils)

Chức năng này dùng để đọc trạng thái ngõ ra của thiết bị. Có thể đọc trạng thái của nhiều Coil khác nhau cùng một lúc. Tuy nhiên, chỉ có thể đọc trạng thái của một thiết bị trong một thời điểm. Cấu trúc của đoạn tin nhắn chức năng 01 như sau:

Cấu trúc truy vấn chức năng 01
Byte Giá trị Mô tả
1 1...247 Địa chỉ thiết bị Server
2 1 Mã chức năng
3 0...255 Địa chỉ bắt đầu, byte cao
4 0...255 Địa chỉ bắt đầu, byte thấp
5 0...255 Số các Coil, byte cao
6 0...255 Số các Coil, byte thấp
7(…8) LRC/CRC Giá trị kiểm tra Error

Trong đoạn tin nhắn trả về, giá trị các Coil tương ứng với một bit. Trạng thái của Coil được quy định là 1 = BẬT và 0 = TẮT. Giá trị Coil của từng địa chỉ chỉ định theo thứ tự từ (MSB LSB). Nếu số lượng Coil trả về không phải là bội số của 8, các bit còn lại trong byte dữ liệu cuối cùng sẽ được đệm bằng các số không.

Ví dụ, khi muốn đọc giá trị Coil có địa chỉ là 20-38, tin nhắn truyền nhận có cấu trúc như sau:

Yêu cầu

Phản hồi
Mô tả Mã code (Hex) Mô tả

Mã code (Hex)

Mã chức năng 01 Mã chức năng 01
Địa chỉ bắt đầu, byte cao 00 Số lượng byte 03
Địa chỉ bắt đầu, byte thấp 13 Trạng thái Coil 27-20 CD
Số Coil, byte cao 00 Trạng thái Coil 35-28 6B
Số Coil, byte thấp 13 Trạng thái Coil 38-36 05

Do muốn đọc từ Coil có địa chỉ là 20 nên địa chỉ tương tương ứng trong PDU là 19 (0x0013), số lượng Coil muốn đọc là 13.

Trạng thái của các Coil từ 27-20 được hiển thị dưới dạng mã hex CD hoặc nhị phân 1100 1101. Coil 27 là MSB của byte này và Coil 20 là LSB. Theo quy ước, các bit trong một byte được hiển thị với MSB ở bên trái và LSB ở bên phải. Do đó, trong byte đầu tiên là ‘27 đến 20’, từ trái sang phải. Byte tiếp theo có đầu ra ‘35 đến 28, từ trái sang phải. Trong byte cuối cùng, trạng thái của các Coil từ 38-36 được hiển thị dưới dạng mã hex 05 hoặc nhị phân 0000 0101. Do chỉ đọc trạng thái của 3 Coil nên 5 bit cao sẽ biểu diễn bằng các số 0.

❖ Chức năng 02: Đọc trạng thái Input (Read Discrete Inputs)

Chức năng này dùng để đọc trạng thái ngõ vào của thiết bị. Cũng giống như chức năng 01 ta có thể đọc đồng thời trạng thái của nhiều ngõ vào cùng lúc nhưng chỉ đọc từ một thiết bị. Cấu trúc của đoạn tin nhắn chức năng 02 như sau:

Cấu trúc truy vấn chức năng 02

Byte

Giá trị

Mô tả

1 1...247 Địa chỉ thiết bị Server
2 2 Mã chức năng
3 0...255 Địa chỉ bắt đầu, byte cao
4 0...255 Địa chỉ bắt đầu, byte thấp
5 0...255 Số các input, byte cao
6 0...255 Số các input, byte thấp
7(…8) LRC/CRC Giá trị kiểm tra Error

Đoạn tin nhắn trả về có cấu trúc tương tự như tin nhắn trả về của chức năng 01. Giá trị các Input tương ứng với một bit. Trạng thái của Input được quy định là 1 = BẬT và 0 = TẮT. Giá trị Coil của từng địa chỉ chỉ định theo thứ tự từ (MSB LSB).

Ví dụ, khi muốn đọc giá trị Input có địa chỉ là 197 - 218, tin nhắn truyền nhận có cấu trúc như sau:

Mô tả Mã code (Hex) Mô tả Mã code (Hex)
Mã chức năng 02 Mã chức năng 02
Địa chỉ bắt đầu, byte cao 00 Số lượng byte 03
Địa chỉ bắt đầu, byte thấp C4 Trạng thái Input 204-197 AC
Số Input, byte cao 00 Trạng thái Input 212-205 DB
Số Input, byte thấp 16 Trạng thái Input 218-213 35

Do muốn đọc từ Input có địa chỉ là 197 nên địa chỉ tương tương ứng trong PDU là 196 (0x00C4), số lượng Coil muốn đọc là 20 (0x0016).

Tuy nhiên, đối với từng thiết bị, tùy theo nhà sản xuất địa chỉ của Input có thể bắt đầu khác nhau (Các Input trên các thiết bị bắt đầu đánh số từ 10001. Giá trị địa chỉ này tương đương địa chỉ 0 trong Modbus PDU).Trạng thái của các Input 204-197 được hiển thị dưới dạng hex là AC hoặc nhị phân 1010 1100. Input 204 là MSB và Input 197 là LSB. Trạng thái của các Input 218-213 được hiển thị dưới dạng hex là 35 hoặc nhị phân 0011 0101. Input 218 ở vị trí bit thứ ba từ trái sang, các bit cao khác sẽ biểu diễn bằng các số 0.

❖ Chức năng 03: Đọc trạng thái thanh ghi giá trị ( Read Holding Register)

Các giá trị bên trong một thiết bị có hỗ trợ Modbus được lưu trong các thanh ghi. Mỗi thanh ghi rộng 2 byte. Chức năng 03 dùng để đọc trạng thái của thanh ghi. Ta có thể đọc đồng thời trạng thái của nhiều thanh ghi cùng lúc nhưng chỉ đọc từ một thiết bị. Cấu trúc của đoạn tin nhắn chức năng 03 như sau:

Cấu trúc truy vấn chức năng 03
Byte Giá trị Mô tả
1 1...247 Địa chỉ thiết bị Server
2 3 Mã chức năng
3 0...255 Địa chỉ bắt đầu, byte cao
4 0...255 Địa chỉ bắt đầu, byte thấp
5 0...255 Số lượng thanh ghi, byte cao
6 0...255 Số lượng thanh ghi, byte thấp
7(…8) LRC/CRC Giá trị kiểm tra Error

Trong tin nhắn phản hồi, giá trị của mỗi thanh ghi tương ứng với 2 byte dữ liệu. Data byte đầu tiên chứa byte cao, và data byte thứ hai chứa byte thấp.

Ví dụ, khi muốn đọc giá trị thanh ghi có địa chỉ là 108 - 110, tin nhắn truyền nhận có cấu trúc như sau:

Yêu cầu

Phản hồi

Mô tả

Mã code (Hex)

Mô tả

Mã code (Hex)

Mã chức năng

03

Mã chức năng

03

Địa chỉ bắt đầu, byte cao

00

Số lượng byte

06

Địa chỉ bắt đầu, byte thấp

6B

Trạng thái thanh ghi (108), byte cao

02

Số thanh ghi, byte cao

00

Trạng thái thanh ghi (108), byte thấp

2B

Số thanh ghi, byte thấp

03

Trạng thái thanh ghi (109), byte cao

00

Trạng thái thanh ghi (109), byte thấp

00

Trạng thái thanh ghi (110), byte cao

00

Trạng thái thanh ghi (110), byte thấp

64

Do muốn đọc từ thanh ghi có địa chỉ là 108 nên địa chỉ tương tương ứng trong PDU là 107 (0x006B), số lượng thanh ghi muốn đọc là 03 (0x0003). Đối với từng thiết bị, tùy theo nhà sản xuất địa chỉ của thanh ghi có thể bắt đầu khác nhau (Các thanh ghi trong thiết bị tương thích Modbus thường bắt đầu ở địa chỉ 40001).

Trong thông tin trả về, nội dung của thanh ghi 108 được hiển thị dưới dạng 2 byte có giá trị là 0x022B hoặc 555. Nội dung của các thanh ghi 109 và 110 lần lượt là 0x0000 0x0064 hoặc 0 và 100.

❖ Chức năng 15: Ghi trạng thái nhiều Coil (Write Multiple Coils)

Chức năng này được sử dụng để ghi giá trị cho nhiều Coil cùng một lúc. Giá trị các Coil của từng địa chỉ chỉ định theo thứ tự từ (MSB LSB). Nếu số lượng Coil muốn ghi giá trị không phải bội số của 8, các bit trong byte dữ liệu tương ứng với các Coil không sử dụng nên được gán là 0(tương ứng với Off). Cấu trúc của đoạn tin nhắn chức 15 như sau:

Cấu trúc truy vấn chức năng 15

Byte

Giá trị

Mô tả

1

1...247

Địa chỉ thiết bị Server

2

15

Mã chức năng

3

0...255

Địa chỉ bắt đầu, byte cao

4

0...255

Địa chỉ bắt đầu, byte thấp

5

0...255

Số lượng thanh ghi, byte cao

6

0...255

Số lượng thanh ghi, byte thấp

7(…8)

LRC/CRC

Số lượng byte (N)

n

N*1 byte

Giá trị của Coil

n+1(…)

LRC/CRC

Giá trị kiểm tra Error

Tin nhắn phản hồi sẽ bao gồm Mã chức năng, địa chỉ bắt đầu và số lượng Coil cần ghi.

Ví dụ, muốn ghi giá trị của 10 Coil bắt đầu từ địa chỉ 20 thì tin nhắn truyền nhận có cấu trúc như sau:

Yêu cầu Phản hồi
Mô tả Mã code (Hex) Mô tả Mã code (Hex)
Mã chức năng 15 Mã chức năng 15
Địa chỉ bắt đầu, byte cao 00 Địa chỉ bắt đầu, byte cao 00
Địa chỉ bắt đầu, byte thấp 13 Địa chỉ bắt đầu, byte thấp 13
Số lượng Coil, byte cao 00 Số lượng Coil, byte cao 00
Số lượng Coil, byte thấp 0A Số lượng Coil, byte thấp 0A
Số lượng Byte 02
Giá trị Coil CD
Giá trị Coil 01

Do muốn ghi từ Coil có địa chỉ là 20 nên địa chỉ tương tương ứng trong PDU là 19 (0x0013), số lượng Coil muốn ghi là 10 (0x000A) nên cần 2 Byte dữ liệu. Giá trị cần ghi (0xCD01) tương ứng với các Coil như sau:

Bit:

1

1 0 0 1 1 0 1 0 0 0 0 0 0 0 1
Output: 27 26 25 24 23 22 21 20 35 - - - - - 29 28

Các thông tin liên quan