TRUYỀN THÔNG GIAO TIẾP GIỮA PLC VÀ ARDUINO QUA RS485 MODBUS
PHẦN I. MODBUS RTU
1.1. Chuẩn truyền Modbus RTU.
MODBUS hoạt động theo nguyên tắc “Master – Slave” hay còn gọi là “Chủ – Tớ”. Một Master có thể kết nối được với một hay nhiều “Slave”. “Master” thường là PLC, PC, DCS, RTU hay SCADA. “Slave” thường là các thiết bị cấp hiện trường. Nói một cách dễ hiểu, nó là một phương pháp được sử dụng để truyền thông tin qua đường dây nối tiếp giữa các thiết bị điện tử. Thiết bị yêu cầu thông tin được gọi là Modbus Master và thiết bị cung cấp thông tin là Modbus Slaves. 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. Các thiết bị được liên kết với nhau theo đường truyền chính:
– Chiều dài đường truyền và tốc độ tối đa cho phép:
- 40 Feet = 12m => 10 Mbits/sec
- 400 Feet = 122m => 1 Mbits/sec
- 4000 Feet = 1219m => 100 kbits/sec
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 RS232 hay RS485, tốc độ từ 1200 đến 115000 baud. Tốc độ phổ biến nhất là từ 9600 đến 19200 baud. MODBUS RTU là giao thức truyền thông công nghiệp được sử dụng rộng rãi nhất.
1.2. Cấu trúc khung truyền Modbus RTU.
- Một gói tin của Mobus RTU bao gồm cấu trúc như sau:
1-byte địa chỉ – 1 byte mã hàm – n byte dữ liệu – 2 byte CRC.
1.3. Chức năng và vai trò cụ thể của các byte trong frame như sau:
1.3.1. Chức năng của các byte theo khung truyền chung.
- Byte địa chỉ (Slave ID):
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) và có độ dài một Byte. Địa chỉ này được quy định từ 0-254.
- Byte mã hàm(Function codes):
Được quy định từ Master, xác định yêu cầu dữ liệu từ thiết bị Slave và có độ dài một Byte.
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
06: ghi dữ liệu 1 word vào Slave
15: ghi dữ liệu nhiều bit vào Slave
16: ghi dữ liệu vào nhiều thanh ghi.
- Byte dữ liệu(data):
Xác định dữ liệu trao đổi giữa Master và Slave
a. Đọc dữ liệu:
· Master:
– 2 byte địa chỉ dữ liệu – 2 byte độ dài dữ liệu
· Slave:
– 2 byte địa chỉ dữ liệu – 2 byte độ dài dữ liệu – n byte dữ liệu đọc được
b. Ghi dữ liệu:
· Master:
– 2 byte địa chỉ dữ liệu – 2 byte độ dài dữ liệu – n byte dữ liệu cần ghi
· Slave:
– 2 byte địa chỉ dữ liệu – 2 byte độ dài dữ liệu
- Byte CRC:
2 byte kiểm tra lỗi của hàm truyền, cách tính giá trị của byte CRC 16 bit.
1.3.2. Chức năng của các byte theo các function được sử dụng trong PLC và Arduino.
Để có được kết quả nhận biết được frame dữ liệu thì chúng ta sử dụng phần mềm QCOM (hoặc tùy bạn sử dụng công cụ nào để đọc giao tiếp UART cũng được) để phân tích các frame và kết quả thu được theo các function được sử dụng như sau:
a. Function 06 Preset Single Resgister.
Ví dụ: Ghi giá trị vào thanh ghi 40002 ở thiết bị ID = 1 thì frame là:
Frame send:
01 06 00 01 00 10 D9 C6
Frame Reciver:
01 06 00 01 00 10 D9 C6
Trong đó:
- 01 là địa chỉ slave.
- 06 là function 06. (Preset Single Resgister)
- 00 01 địa chỉ thanh ghi. (~ thanh ghi 40002)
- 00 10 dữ liệu được ghi.
- D9 C6 2 Byte checksum.
b. Function 16 Preset Multiple Registers.
Ví dụ: Ghi giá trị vào thanh ghi 40001 ở thiết bị ID = 1 thì frame là:
Frame Send:
01 10 00 00 00 01 02 00 10 A7 9C
Trong đó:
- 01 là ID Slave.
- 10 là function. (Preset Multiple Registers)
- 00 00 địa chỉ thanh ghi. (~ Thanh ghi 40001)
- 00 01 số thanh ghi được ghi dữ liệu vào (ở đây ghi vào một thanh ghi thì có giá trị là 1).
- 02 số byte dữ liệu.
- 00 10 Giá trị dữ liệu được ghi.
- A7 9C 2 Byte Checksum.
Frame Reciver:
01 10 00 00 00 01 01 C9
Trong đó:
- 01 là ID Slave.
- 10 là function. (Preset Multiple Registers)
- 00 00 địa chỉ thanh ghi. (~ Thanh ghi 40001)
- 00 01 số thanh ghi được ghi dữ liệu vào (ở đây ghi vào một thanh ghi thì có giá trị là 1).
- 01 C9 2 Byte Checksum.
c. Function 03 Read Holding Registers.
Ví dụ: Đọc giá trị từ thanh ghi 40001 từ Arduino có frame là:
Frame Send:
01 03 00 00 00 01 84 0A
Trong đó:
- 01 Là ID slave.
- 03 Là function. (Read Holding Registers)
- 00 00 địa chỉ thanh ghi(~40001).
- 00 01 Số lượng thanh ghi.
- 84 0A 2 Byte Checksum.
Frame Reciver:
01 03 02 00 01 79 84
Trong đó:
- 01 Là ID slave.
- 03 Là function. (Read Holding Registers)
- 02 Số Byte đọc.
- 00 01 dữ liệu.
- 79 84 2 Byte Checksum.
1.4. Địa chỉ dữ liệu và 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à 1bit 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 bít = 2 bytes và cũng được gán một địa chỉ dữ liệu từ 0000 đến 270E.
Coil/Register Numbers | Data Addresses | Type | Table Name |
1-9999 | 0000 to 270E | Read-Write | Discrete Output Coils |
10001-19999 | 0000 to 270E | Read-Only | Discrete Input Contacts |
30001-39999 | 0000 to 270E | Read-Only | Analog Input Registers |
40001-49999 | 0000 to 270E | Read-Write | Analog 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.
PHẦN II. CHUẨN TRUYỀN THÔNG RS485 TRONG PLC S7-1200
2.1. Chuẩn truyền thông RS485 trong PLC.
Module Rs485 là thiết bị chức năng truyền thông để kết hợp với PLC để thực hiện giao thức truyền thông RS485 với các thiết bị khác. Đối với khung truyền thì Frame truyền theo khung chuẩn Mobus RTU. Trong lập trình cho PLC thì sử dụng các module chức năng để phục vụ cho việc kết nối và truyền dữ liệu. Chúng ta chỉ cần cấu hình, thiết lập các biến để kết nối và truyền dữ liệu tới thiết bị trường.
Trước khi vào phần lập trình thì chúng ta cần phải cấu hình module CM1241 (Module RS485) được kết nối với PLC.
Sau khi thêm Module CM1241 thì chúng ta vào phần cấu hình để cấu hình một vài thông số Baud rate, Parity, Data bits, Stop bits theo hình bên dưới:
Đối với PLC là master và các thiết bị thường là Slave thì chúng ta sử dụng 2 module code như sau:
2.1.1. Module code COMM_LOAD_DB.
MB_COMM_LOAD: Dùng để cấu hình cho cổng kết nối vì vậy nó sẽ được khởi động đầu tiên và chỉ chạy 1 lần trong cả quá trình truyền thông. Vì vậy khối hàm này bắt buộc phải có và cách sử dụng cũng như cấu hình cho khối này được đính kèm theo ở phần phụ lục:
Chúng ta cài đặt các thông số cho hàm MB_COMM_LOAD với các thông số như trên trong đó:
REQ: Đóng vai trò như là 1 bit enable, nghĩa là khi nó bằng 1 thì hàm sẽ được thực hiện. Mặt khác như đã nói ở trên hàm này chỉ cần thực hiện 1 lần để khởi tạo các thông số truyền thông. Do đó bit REQ chỉ có giá trị bằng 1 trong vòng lặp đầu tiên. Do vậy khi bắt đầu chương trình hàm MB_COMM_LOAD sẽ được thực hiện luôn.
PORT: Giá trị của PORT chính là giá trị của thông số Hardware indentifier trong quá trình thiết lập module lúc đầu. Giá trị 269 là giá trị được thiết lập mặc định khi cấu hình thiết bị
BAUD: tốc độ baud được chọn theo các giá trị như: 9600, 12500… nhưng thường là chọn 9600 và được chọn theo cấu hình đã được thiết lập.
PARITY: được thiết lập theo như cấu hình được thiết lập trước đó.
MB_DB là khối dữ liệu được tham chiếu từ khối MASTER
2.1.2. Khối MB_MASTER.
REQ: Là bit enable, khi nó được bật lên thì quá trình truyền thông được thực hiện.
MB_ADDR: Là địa chỉ của Slave, các địa chỉ này được thiết lập trên Slave.
DATA_ADDR: là địa chỉ thanh ghi dữ liệu ở Slave.
MODE: Bit này sẽ được set tùy theo mục đích sử dụng của ta là đọc hay ghi. Cụ thể chúng ta tham khảo các mode theo bảng dưới đây:
PHẦN III. KẾT NỐI PLC VỚI ARDUINO
3.1. Kết nối các thiết bị.
Arduino UNO | MAX-485 TTL to RS-485 Converter Module |
0(RX) | RO |
1(TX) | DI |
2 | DE & RE |
+5V | VCC |
GND | GND |
DB9 | MAX-485 TTL to RS-485 Converter Module |
A | 3 |
B | 8 |
VCC | 5V |
GND | GND |
3.2. Phần code ở Ardunio.
#include “ModbusRtu.h” //Library for using Modbus in Arduino
Modbus slave (1, Serial, 2); //Modbus slave ID as 1 and 1 connected via RS-485 and 4 connected to DE & RE pin of RS-485 (ID from 1 to 247)
//Define Object bus for class modbus
uint16_t modbus_array[] = {0, 0, 0}; //Array initilized with three 0 values
int Number [10] = {0xFC, 0x60, 0xDA, 0xF2, 0x66, 0xB6, 0xBE, 0xE0, 0xFE, 0xF6};
// the setup routine runs once when you press reset:
void setup()
{
Serial.begin(9600);
slave.start();
}
void loop()
{
if (slave.poll( modbus_array, 2 ) > 4) //Used to receive or write value from Master
{
// write value analog (A0 pin) for register 40002 of Arduino
modbus_array[1] = analogRead(A0);
Serial.println( analogRead(A0) );
delay(500);
}
}
PHẦN IV. KẾT LUẬN
Trên đây là bài viết chia sẻ về giao tiếp giữa PLC S7-1200 và arduino qua chuẩn truyền thông RS485. Hy vọng bài viết này sẽ hỗ trợ, giúp đỡ được nhiều bạn trong vấn đề làm việc với PLC và arduino, hoặc cũng như các loại vi điều khiển khác, và lớn hơn nữa là có thể làm những dự án công nghiệp mà không đủ điều kiện để tiếp cận PLC. Nếu trong bài viết có gì sai sót, cần điều chỉnh thì hãy cho mình biết để mình điều chỉnh lại nhé.
Chúc thành công!
Tìm hiểu thêm các bài viết liên quan:
Truyền thông nối tiếp trong lập trình vi điều khiển – Giao tiếp UART
Truyền nhận dữ liệu với giao tiếp Serial (UART) trên Arduino
Khái niệm về giao thức Modbus RTU và kết nối phần cứng
Tìm hiểu về khung truyền Modbus RTU
Tấn Lĩnh – Thành Trung
ATOMA Technology