Bài 15. Modbus RTU trong truyền nhận dữ liệu với ESP8266

Modbus RTU là một giao thức truyền thông công nghiệp, cho phép truyền nhận dữ liệu giữa các thiết bị thông qua đường truyền nối tiếp RS485. Modbus RTU hoạt động theo nguyên tắc Master-Slave, trong đó Master là thiết bị yêu cầu thông tin và Slave là thiết bị cung cấp thông tin. Trong bài viết này Điện thông minh E-smart sẽ cùng bạn tìm hiểu giao thức modbus này.

Modbus là gì?

Giao thức Modbus là một giao thức truyền thông công nghiệp được phát triển bởi Modicon (nay là Schneider Electric) vào năm 1979 để sử dụng với các bộ điều khiển logic lập trình (PLC) của hãng này. Modbus được sử dụng rộng rãi trong các ứng dụng tự động hóa, kiểm soát và thu thập dữ liệu (SCADA) vì nó là một giao thức mở, miễn phí bản quyền, đơn giản và dễ triển khai.

Modbus hoạt động theo nguyên tắc MasterSlave, trong đó Master là thiết bị yêu cầu thông tin và Slave là thiết bị cung cấp thông tin. Trong mạng Modbus tiêu chuẩn, có một Master và tối đa 247 Slave, mỗi Slave có một địa chỉ Slave duy nhất từ ​​1 đến 247. Master cũng có thể ghi thông tin vào các Slave.

Modbus có thể sử dụng các phương tiện truyền thông khác nhau như RS-232, RS-485, Ethernet, cáp quang, sóng vô tuyến, v.v. để truyền và nhận dữ liệu. Modbus có ba phiên bản chính là Modbus RTU, Modbus TCPModbus ASCII.

Modbus RTU trong truyền nhận dữ liệu
  • Modbus RTU: Dữ liệu được mã hóa theo hệ nhị phân, và chỉ cần một byte truyền thông cho một byte dữ liệu. Đây là giao thức truyền thông lý tưởng đối với RS-232 hay RS-485, tốc độ từ 1200 đến 115200 baud.
  • Modbus TCP: Dữ liệu Modbus được đóng gói trong một gói TCP/IP và được gửi qua mạng Ethernet. Đây là giao thức truyền thông hiện đại và linh hoạt, cho phép kết nối nhiều thiết bị qua internet.
  • Modbus ASCII: Dữ liệu được mã hóa theo hệ thập lục phân, sử dụng ký tự ASCII 4 bit. Đối với mỗi byte thông tin, cần có hai byte truyền thông, gấp đôi so với Modbus RTU hay Modbus TCP.

Modbus RTU

Modbus RTU hoạt động theo nguyên tắc Master-Slave, trong đó Master là thiết bị yêu cầu thông tin và Slave là thiết bị cung cấp thông tin. Modbus RTU sử dụng đường truyền vật lý RS-232 hoặc RS-485 để truyền và nhận dữ liệu theo hệ nhị phân.

Modbus RTU trong truyền nhận dữ liệu

Một bản tin Modbus RTU bao gồm các thành phần sau:

  • Byte địa chỉ: xác định thiết bị mang địa chỉ được nhận dữ liệu (đối với Slave) hoặc dữ liệu nhận được từ địa chỉ nào (đối với Master).
  • Byte mã hàm: xác định yêu cầu dữ liệu từ thiết bị Slave. Ví dụ mã 01: đọc dữ liệu lưu trữ dạng Bit, 03: đọc dữ liệu tức thời dạng Byte, 05: ghi dữ liệu 1 bit vào Slave, 15: ghi dữ liệu nhiều bit vào Slave.
  • Byte dữ liệu: xác định dữ liệu trao đổi giữa Master và Slave. Có thể là địa chỉ dữ liệu, độ dài dữ liệu, hoặc giá trị dữ liệu.
  • Byte CRC: xác minh tính toàn vẹn của bản tin.

Địa chỉ thanh ghi theo chuẩn Modbus

Thông tin dữ liệu được lưu trữ trong thiết bị Slave được chia trong 4 khoảng giá trị khác nhau. Hai khoảng lưu trữ các giá trị rời rạc on/off (coils) và hai khoảng lưu trữ giá trị số (register – thanh ghi). Mỗi coils và register đều có khoảng biến chỉ đọc (read-only) và biến đọc và ghi (read-write).

  • Mỗi khoảng có 9999 biến giá trị
  • Mỗi coil hoặc contact là 1 bit và được gán một địa chỉ dữ liệu trong khoảng từ 0000 đến 270E
  • Mỗi register là 1 word = 16 bit = 2 bytes và cũng được gán một địa chỉ dữ liệu từ 0000 đến 270E
Coil/Register NumbersData AddressesTypeTable Name
1-99990000 to 270ERead-WriteDiscrete Output Coils
10001-199990000 to 270ERead-OnlyDiscrete Input Contacts
30001-399990000 to 270ERead-OnlyAnalog Input Registers
40001-499990000 to 270ERead-WriteAnalog Output Holding Registers

Coil/Register Numbers có thể được coi như tên vị trí vì chúng không xuất hiện trong các thông điệp thực tế. “Data Addressses” được sử dụng trong các thông điệp truyền tải (truy xuất dữ liệu).

Ví dụ: Holding Register có số là 40001, có “Data Address” là 0000. Sự khác biệt giữa hai giá trị này là độ lệch. Mỗi bảng có một độ lệch khác nhau. 1, 10001, 30001 và 40001.

Function code

Byte thứ hai được “Master” gửi đi là “Function code”. Con số này cho “Slave” biết được rằng, địa chỉ nào cần truy cập để đọc hay ghi giá trị.

Function CodeActionTable Name
01 (01 hex)ReadDiscrete Output Coils
05 (05 hex)Write singleDiscrete Output Coil
15 (0F hex)Write multipleDiscrete Output Coils
02 (02 hex)ReadDiscrete Input Contacts
04 (04 hex)ReadAnalog Input Registers
03 (03 hex)ReadAnalog Output Holding Registers
06 (06 hex)Write singleAnalog Output Holding Register
16 (10 hex)Write multipleAnalog Output Holding Registers

Ứng dụng Modbus RTU

Modbus RTU trong truyền nhận dữ liệu

Modbus RTU có nhiều ứng dụng trong công nghiệp, chẳng hạn như:

  • Đo lường và kiểm soát các thông số như nhiệt độ, độ ẩm, áp suất, lưu lượng, mức, v.v.
  • Điều khiển và giám sát các thiết bị như van, bơm, động cơ, biến tần, relay, v.v.
  • Kết nối và tích hợp các thiết bị của các hãng khác nhau qua các phương tiện truyền thông khác nhau như RS-232, RS-485, Ethernet, cáp quang, sóng vô tuyến, v.v.
  • Truyền dữ liệu từ xa qua internet hoặc mạng di động sử dụng Modbus TCP/IP hoặc Modbus RTU over TCP/IP.
  • Lập trình và cấu hình các thiết bị sử dụng Modbus như PLC, RTU, HMI, v.v.

Ưu và nhược điểm của Modbus RTU

Ưu điểm

  • Modbus RTU có khả năng truyền dữ liệu xa lên đến 1200m với tốc độ cao .
  • Modbus RTU giảm tối thiểu số lượng dây kết nối vào các thiết bị điều khiển tự động, giúp tiết kiệm chi phí và không gian lắp đặt .
  • Modbus RTU có độ ổn định cao và ít nhiễu hơn so với tín hiệu analog 4-20mA .
  • Modbus RTU có thể kết nối và tích hợp các thiết bị của các hãng khác nhau có chuẩn Modbus RTU .
  • Modbus RTU là một giao thức mở, miễn phí bản quyền, đơn giản và dễ triển khai.

Nhược điểm

  • Modbus RTU không hỗ trợ phát hiện và khắc phục lỗi trong quá trình truyền thông.
  • Master phải thường xuyên thăm dò từng thiết bị và tìm kiếm các thay đổi trong dữ liệu. Điều này sẽ gây tiêu tốn băng thông và thời gian mạng trong các ứng dụng.
  • Modbus RTU phải được thiết kế liền kề nhau, điều này làm giới hạn các loại thiết bị liên lạc từ xa với các thiết bị có thể đệm dữ liệu để tránh tạo các khoảng trống trong quá trình truyền.
  • Modbus RTU không cung cấp bảo mật để chống lại các lệnh trái phép hoặc chặn dữ liệu.

Cách sử dụng Modbus RTU

  • Bước 1: Xác định thông số truyền thông và bảng thanh ghi.
  • Bước 2: Kết nối thiết bị Modbus RTU với thiết bị Master qua cáp RS-232 hoặc RS-485.
  • Bước 3: Sử dụng phần mềm hoặc lập trình để gửi và nhận dữ liệu theo cấu trúc của bản tin Modbus RTU.
  • Bước 4: Kiểm tra và xử lý dữ liệu nhận được từ thiết bị Modbus RTU.

Thông số truyền thông

Để giao tiếp với thiết bị Modbus RTU, bạn cần xác định các thông số sau của thiết bị:

  • Địa chỉ: Số nguyên từ 1 đến 247, xác định thiết bị trên mạng Modbus.
  • Tốc độ baud: Số bit trên giây, xác định tốc độ truyền dữ liệu. Thường là 9600, 19200, 38400 hoặc 57600 bit/s.
  • Số bit truyền: Số bit biểu diễn một byte dữ liệu. Thường là 8 bit.
  • Bit kiểm tra chẳn lẻ: Bit thêm vào cuối mỗi byte dữ liệu, kiểm tra tính toàn vẹn của byte đó. Có thể là chẳn (even) hoặc lẻ (odd).
  • Số bit stop: Số bit thêm vào sau mỗi byte dữ liệu, kết thúc việc truyền byte đó. Có thể là 1 hoặc 2.

Bảng thanh ghi

Bảng thanh ghi trong một thiết bị Modbus RTU là một bộ nhớ được chia thành các ô nhớ có địa chỉ, dùng để lưu trữ hoặc truyền nhận dữ liệu giữa thiết bị và các thiết bị khác trên mạng Modbus. Bảng thanh ghi có thể chứa các loại dữ liệu khác nhau, như số nguyên, số thực, số nhị phân, v.v. Có nhiều loại thanh ghi khác nhau trong Modbus RTU, nhưng hai loại chính là:

  • Thanh ghi giữ (Holding Register): Là thanh ghi có thể đọc và ghi dữ liệu, dùng để lưu trữ các thông số cài đặt hoặc điều khiển của thiết bị. Thanh ghi giữ có địa chỉ từ 40001 đến 49999, mỗi ô nhớ có kích thước 16 bit. Mã hàm để đọc hoặc ghi thanh ghi giữ là 03 hoặc 06.
  • Thanh ghi đầu vào (Input Register): Là thanh ghi chỉ có thể đọc dữ liệu, dùng để lưu trữ các giá trị đo lường hoặc trạng thái của thiết bị. Thanh ghi đầu vào có địa chỉ từ 30001 đến 39999, mỗi ô nhớ có kích thước 16 bit. Mã hàm để đọc thanh ghi đầu vào là 04.

Ví dụ: Bảng thanh ghi của cảm biến ES35-SW có các ô nhớ có địa chỉ từ 0000 đến 0002 và 0100 đến 0101, mỗi ô nhớ có kích thước 16 bit. Các ô nhớ có chức năng và giá trị như sau:

  • Ô nhớ 0000: Lưu trữ giá trị nhiệt độ của cảm biến, đơn vị là độ C. Giá trị này có thể được đọc bằng mã hàm 03 (đọc thanh ghi giữ). Ví dụ, nếu giá trị của ô nhớ 0000 là 012C (hex), thì nhiệt độ của cảm biến là 30 độ C.
  • Ô nhớ 0001: Lưu trữ giá trị độ ẩm của cảm biến, đơn vị là %. Giá trị này có thể được đọc bằng mã hàm 03 (đọc thanh ghi giữ). Ví dụ, nếu giá trị của ô nhớ 0001 là 0032 (hex), thì độ ẩm của cảm biến là 50%.
  • Ô nhớ 0100: Lưu trữ giá trị địa chỉ của cảm biến, từ 1 đến 247. Giá trị này có thể được đọc hoặc ghi bằng mã hàm 03 (đọc thanh ghi giữ) hoặc 06 (ghi thanh ghi giữ). Ví dụ, nếu giá trị của ô nhớ 0100 là 0001 (hex), thì địa chỉ của cảm biến là 1.
  • Ô nhớ 0101: Lưu trữ giá trị tần số của tín hiệu RS-485, đơn vị là Hz. Giá trị này có thể được đọc hoặc ghi bằng mã hàm 03 (đọc thanh ghi giữ) hoặc 06 (ghi thanh ghi giữ). Ví dụ, nếu giá trị của ô nhớ 0101 là 2580 (hex), thì tần số của tín hiệu RS-485 là 9600 Hz.

ESP8266 giao tiếp Modbus RTU

Để giao tiếp với thiết bị Modbus RTU, bạn cần kết nối ESP8266 với Module UART to RS485, một module chuyển đổi tín hiệu từ Serial sang RS-485. Bạn cũng cần thêm thư viện modbus-esp8266 vào Arduino IDE, một thư viện hỗ trợ giao thức Modbus cho ESP8266. Sau đó, bạn có thể viết code để đọc hoặc ghi giá trị của các thanh ghi Modbus trên thiết bị SLAVE.

Đọc giá trị nhiệt độ – độ ẩm từ ES35-SW

Modbus RTU trong truyền nhận dữ liệu

Thông số giao tiếp mặc định

Address (ID)BaudrateData BitsParityStop Bit
196008None1

Bảng thanh ghi

Thanh ghiThông sốTrạng tháiFunctionMô tả
Địa chỉSố lượng
01Nhiệt độ Chỉ đọc3 Giá trị -20 – 80(°C)
11Độ ẩmChỉ đọc3 Giá trị 0 – 100(%)
1001Địa chỉ thiết bị(ID)Đọc/Ghi3, 6Thiết lập bằng Switch:
DP1: 1-15.
Thiết lập bằng Software:
1-247
1011BaudrateĐọc/Ghi3, 6Giá trị tương ứng cài đặt
 2: 4800
 3: 9600
 4: 14400
 5: 19200
 6: 38400
 7: 56000
 8: 57600
 9: 115200
1021ParityĐọc3 0: None Parity
1031DataBitsĐọc3 8: 8 Databits
1041StopBitsĐọc3 1: 1 Stop bit
1051Setting ModeChỉ đọc31: Đang ở chế độ địa chỉ cài đặt bằng Switch DP1
0:  Đang ở chế độ địa chỉ cài đặt bằng phần mềm.
1061Temperature CorrectionĐọc/Ghi3, 6 Giá trị: -10 ~ 10 (°C)
1071Humidity CorrectionĐọc/Ghi3, 6 Giá trị: -10 ~ 10 (%)

Sơ đồ đấu nối phần cứng

Modbus RTU trong truyền nhận dữ liệu

Code chương trình

#include <ModbusRTU.h> // Thêm thư viện Modbus
#include <SoftwareSerial.h> // Thêm thư viện Serial ảo

#define SLAVE_ID 1 // ID của nô lệ
#define FIRST_REG 0 // Địa chỉ thanh ghi đầu
#define REG_COUNT 2 // Số lượng thanh ghi

SoftwareSerial S(D2, D1); // Serial ảo với RX=D2, TX=D1
ModbusRTU mb; // Đối tượng Modbus

bool cb(Modbus::ResultCode event, uint16_t transactionId, void* data) { // Hàm callback
  if (event != Modbus::EX_SUCCESS) { // Nếu lỗi
    Serial.print("Request result: 0x"); // In kết quả
    Serial.print(event, HEX);
  }
  return true; // Trả về true
}

void setup() {
  Serial.begin(115200); // Serial với tốc độ 115200 baud
  S.begin(9600, SWSERIAL_8N1); // Serial ảo với tốc độ 9600 baud và chế độ SWSERIAL_8N1
  mb.begin(&S); // Modbus với Serial ảo
  mb.master(); // Chế độ master
}

void loop() {
  uint16_t res[REG_COUNT]; // Mảng kết quả
  if (!mb.slave()) {    // Nếu không có giao dịch
    mb.readHreg(SLAVE_ID, FIRST_REG, res, REG_COUNT, cb); // Đọc thanh ghi
    while(mb.slave()) { // Nếu có kết nối
      mb.task(); // Thực hiện tác vụ Modbus
      delay(10); // Đợi 10 ms
    }
    Serial.println(res[0]); // In thanh ghi đầu
    Serial.println(res[1]); // In thanh ghi thứ hai
  }
  delay(1000); // Đợi 1000 ms
}

Để sử dụng code này các bạn cần cài đặt thư viện modbus-esp8266 trên Arduino IDE

Kết luận

Qua bài viết này mình đã cùng các bạn tìm hiểu về giao thức modbus và cách sử dụng thiết bị có tích hợp chuẩn giao tiếp Modbus RTU với ESP8266 thông qua Module Uart to RS485 sử dụng phần mềm Arduino IDE và thư viện modbus-esp8266. Huy vọng qua bài viết này các bạn sẽ có 1 cái nhìn tổng quát hơn về giao thức modbus trong truyền nhận dữ liệu.

5/5 - (5 bình chọn)

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Chiêu sinh khóa Lập trình ESP32 căn bản, lớp (20h-21h30) 3-5-7 ngày 07/01/2024. Học phí 1tr/khóa (20 buổi). Đăng ký qua zalo: 0919.890.938

X
Contact Me on Zalo