Modbus là một giao thức truyền thông phổ biến trong các hệ thống công nghiệp, đặc biệt hữu ích để kết nối các thiết bị từ xa với hệ thống điều khiển trung tâm. Trong khi đó, RS‑485 là chuẩn vật lý giúp truyền tín hiệu ổn định trên khoảng cách xa, và cho phép kết nối nhiều thiết bị trên cùng một đường truyền.
Linh kiện cần dùng
-
Raspberry Pi (3, 4 hoặc 5 tùy nhu cầu)
-
Module RS-485 to TTL.
-
Thiết bị RS-485 (cảm biến, đồng hồ, hoặc USB to RS-485 để test)
Tại sao chọn Modbus RS‑485?
Trong dự án này, giao tiếp giữa Raspberry Pi và các cảm biến được thực hiện thông qua Modbus RTU qua RS‑485. Đây là lựa chọn lý tưởng vì:
-
Tín hiệu mạnh và ổn định: Phù hợp cho môi trường công nghiệp nhiều nhiễu.
-
Kết nối nhiều thiết bị: RS‑485 cho phép giao tiếp theo mô hình đa điểm (multi-drop).
-
Truyền dữ liệu hiệu quả: Modbus RTU sử dụng định dạng nhị phân và kiểm tra lỗi CRC.
Sử dụng thư viện minimalmodbus
trong Python
Để triển khai giao tiếp Modbus RTU trên Raspberry Pi, bạn có thể sử dụng thư viện minimalmodbus
— một thư viện Python đơn giản và mạnh mẽ, hỗ trợ cả hai chế độ Modbus RTU và ASCII. Trong hầu hết các ứng dụng công nghiệp, Modbus RTU là lựa chọn ưu tiên nhờ khả năng truyền dữ liệu nhanh và hiệu quả.
Cách thức hoạt động:
-
Raspberry Pi sẽ đóng vai trò Modbus Master, gửi yêu cầu tới các thiết bị (Slave).
-
Cảm biến như đo pH, CO₂, nhiệt độ… sẽ là Slave, phản hồi lại dữ liệu theo yêu cầu.
-
Giao tiếp sử dụng cổng nối tiếp UART (hoặc qua USB‑RS485 converter nếu cần).
Ưu điểm của thư viện minimalmodbus
:
-
Đơn giản, dễ sử dụng: Thiết lập nhanh, giao diện lập trình rõ ràng.
-
Hỗ trợ nhiều kiểu dữ liệu: Đọc và ghi cả giá trị nguyên (
int
), số thực (float
), giá trị dấu chấm động 32 bit. -
Tối ưu cho Modbus RTU: Thư viện hoạt động ổn định với tốc độ truyền cao và cơ chế kiểm lỗi hiệu quả.
Giao tiếp Modbus RTU RS-485 trên Raspberry Pi không dùng thư viện Modbus
Thông thường, khi làm việc với Modbus RTU trên Raspberry Pi, người dùng sẽ chọn các thư viện như minimalmodbus
hoặc pymodbus
. Tuy nhiên, trong một số trường hợp bạn muốn:
-
Hiểu rõ cách hoạt động thấp tầng của Modbus
-
Gửi frame Modbus thủ công (raw frame)
-
Không phụ thuộc vào thư viện bên ngoài
Trong phần này, chúng ta sẽ cùng thực hiện giao tiếp Modbus RTU qua RS-485 mà không dùng bất kỳ thư viện Modbus nào, chỉ dùng thư viện serial
của Python.
Trước khi sử dụng các chân UART trên Raspberry Pi, bạn cần bật chúng lên theo các bước sau:
Mở Terminal và nhập: sudo raspi-config
Chọn: Interfacing Options
Sau đó chọn: Serial
Khi được hỏi “Would you like a login shell to be accessible over serial?”, chọn No
Thoát khỏi raspi-config và khởi động lại Raspberry Pi
Mở Terminal và chạy các lệnh sau:
sudo apt-get update sudo apt-get install python-pip sudo apt-get install python-pil sudo pip install RPi.GPIO sudo apt-get install python-serial sudo pip install serial sudo pip install pyserial
Tạo file Python trên Raspberry Pi
Sao chép đoạn mã sau và lưu lại thành file modbus_test.py
:
import serial import serial.rs485 import time import RPi.GPIO as GPIO TXDEN_1 = 7 # transmit enable pin GPIO.setwarnings(False) GPIO.setmode(GPIO.BOARD) GPIO.setup(TXDEN_1, GPIO.OUT, initial=GPIO.HIGH) # Thiết lập cổng RS485 (ttySC0 là ví dụ, bạn có thể dùng ttyAMA0 hoặc ttyUSB0 tùy cấu hình) ser = serial.rs485.RS485(port='/dev/ttySC0', baudrate=9600, timeout=5, parity=serial.PARITY_EVEN) ser.rs485_mode = serial.rs485.RS485Settings( rts_level_for_tx=False, rts_level_for_rx=False, delay_before_tx=0.0, delay_before_rx=0.0 ) # Frame dữ liệu Modbus RTU: SlaveID=1, Function=3, Address=2, Quantity=1, CRC=0x25CA SendFrame = b'\x01\x03\x00\x02\x00\x01\x25\xCA' while True: GPIO.output(TXDEN_1, GPIO.HIGH) # Bật chế độ gửi ser.write(SendFrame) GPIO.output(TXDEN_1, GPIO.LOW) # Chuyển sang chế độ nhận time.sleep(0.1) # đợi phản hồi incoming = ser.inWaiting() print("Incoming bytes:", incoming) if incoming: response = ser.read(incoming) print("Response (hex):", response.hex()) else: print("No data received.") time.sleep(2)
Thiết lập phần mềm pyMod Slave (hoặc hercules) trên máy tính
-
Cắm USB to RS485 vào máy tính.
-
Mở phần mềm như pyMod Slave hoặc hercules.
-
Chọn chế độ Modbus RTU, cổng COM tương ứng và cấu hình:
-
Baudrate: 9600
-
Parity: Even
-
Data bits: 8
-
Stop bits: 1
-
-
Mở tab Holding Registers, chọn chế độ HEX
-
Nhấn Connect và nhập một giá trị vào địa chỉ thanh ghi
2
(tương ứng với0x0002
trong frame)
Chạy thử chương trình
Trên Raspberry Pi, chạy file vừa ghi.
Nếu mọi thứ đúng, bạn sẽ thấy dữ liệu phản hồi từ Slave được in ra theo định dạng hex. Ví dụ: