1. Mục tiêu
Bài viết này hướng dẫn bạn cách:
- Kết nối ESP32 với WiFi.
- Giao tiếp Modbus RTU qua UART2 để đọc các thanh ghi
Holding Register. - Chuyển các giá trị đọc được thành ký tự và ghép chuỗi hiển thị lên
Serial Monitor. - Điều khiển 3 đèn LED để báo trạng thái kết nối.
2. Phần cứng sử dụng
- Mạch ESP32 Modbus RTU RS485 ISOLATED ZenoRTU0105
- Mạch ESP32 RS485 Modbus RTU TCP/IP Ethernet ZenoLAN0105
- Nguồn cấp cho thiết bị từ 10 - 30V
- Thiết bị Slave Modbus RTU (ví dụ: cảm biến, PLC...)
3. Thư viện cần thiết
Tải tại đây: https://github.com/4-20ma/ModbusMaster
4. Code và giải thích chi tiết
Chương trình code hoàn chỉnh
#include <WiFi.h>
#include <ModbusMaster.h>
// Khai báo chân LED (kích mức thấp)
#define LED1 5
#define LED2 12
#define LED3 13
// Chân UART2
#define RXD2 17
#define TXD2 16
// Thông tin WiFi
const char* ssid = "iMaker Viet Nam";
const char* password = "imaker12345";
// Modbus
ModbusMaster node;
uint16_t startAddress = 0;
uint8_t quantity = 10;
uint16_t data[10];
char datachar[10];
// Cờ xác nhận WiFi đã kết nối
bool wifiConnected = false;
void setup() {
Serial.begin(9600);
// Cấu hình các chân LED
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
digitalWrite(LED1, HIGH); // Tắt mặc định
digitalWrite(LED2, HIGH);
digitalWrite(LED3, HIGH);
// Kết nối WiFi
WiFi.begin(ssid, password);
Serial.print("Đang kết nối WiFi");
int retry = 0;
while (WiFi.status() != WL_CONNECTED && retry < 20) {
delay(500);
Serial.print(".");
retry++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\n✅ Đã kết nối WiFi!");
// Bật 3 LED (kích mức thấp)
digitalWrite(LED1, LOW);
digitalWrite(LED2, LOW);
digitalWrite(LED3, LOW);
wifiConnected = true;
} else {
Serial.println("\n❌ Kết nối WiFi thất bại.");
}
// Khởi tạo Modbus nếu WiFi đã kết nối
if (wifiConnected) {
Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
node.begin(1, Serial2);
}
}
void loop() {
if (!wifiConnected) return;
uint8_t result = node.readHoldingRegisters(startAddress, quantity);
if (result == node.ku8MBSuccess) {
for (uint8_t j = 0; j < quantity; j++) {
data[j] = node.getResponseBuffer(j);
datachar[j] = (char)data[j];
Serial.print("Register ");
Serial.print(j);
Serial.print(": ");
Serial.println(datachar[j]);
}
string_cv();
} else {
Serial.print("❌ Modbus read failed. Error code: ");
Serial.println(result);
}
delay(1000); // Đọc mỗi giây
}
void string_cv() {
String combinedString = "";
for (int j = 0; j < quantity; j++) {
if (datachar[j] != ' ') {
combinedString.concat(datachar[j]);
}
}
combinedString.trim();
Serial.println("Chuỗi ghép: " + combinedString);
}4.1 Cấu Hình Chân và WiFi
#define LED1 5
#define LED2 12
#define LED3 13
const char* ssid = "iMaker Viet Nam";
const char* password = "imaker12345";
- 3 đèn LED báo trạng thái sẽ sáng khi kết nối WiFi thành công (do sử dụng mức LOW để bật).
- SSID và mật khẩu cần khớp với mạng WiFi hiện tại.
4.2 Kết Nối WiFi Và Bật LED Khi Thành Công
WiFi.begin(ssid, password);<br>…<br>if (WiFi.status() == WL_CONNECTED) {<br>digitalWrite(LED1, LOW); // Bật LED khi kết nối thành công<br>…<br>}Nếu kết nối WiFi thành công trong vòng 20 lần thử, đèn LED sẽ được bật lên báo hiệu.
4.3 Khởi Tạo UART2 và Modbus RTU
Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
node.begin(1, Serial2); // Slave ID = 1- UART2 được cấu hình ở tốc độ 9600 baud.
- Giao tiếp Modbus được khởi tạo với địa chỉ thiết bị slave là
1.
4.4 Vòng Lặp loop()
uint8_t result = node.readHoldingRegisters(startAddress, quantity);- Đọc 10 thanh ghi bắt đầu từ địa chỉ 0.
- Kết quả được lưu vào mảng
data[], sau đó ép kiểu sangcharđể lưu vàodatachar[].
4.5 Ghép Chuỗi Ký Tự
void string_cv() {
String combinedString = "";
...
Serial.println("Chuỗi ghép: " + combinedString);
}- Hàm này loại bỏ các ký tự khoảng trắng và in ra chuỗi đã ghép. Đây có thể là chuỗi mã hóa dữ liệu từ thiết bị Slave.
5. Kết Quả Mong Đợi
- Khi bật nguồn:
- Nếu kết nối WiFi thành công: cả 3 LED sáng.
- Mỗi giây, dữ liệu Modbus được đọc và in ra theo chuỗi.
- Nếu lỗi, sẽ có thông báo lỗi trên Serial.
6. Mở Rộng
Bạn có thể mở rộng chương trình bằng:
- Hiển thị chuỗi lên màn hình OLED/LCD.
- Gửi dữ liệu chuỗi lên MQTT hoặc HTTP Server.
- Cảnh báo qua Buzzer nếu chuỗi chứa từ khóa cảnh báo (ví dụ
"ERROR").
7. Kiểm Tra & Debug
- Kiểm tra kết nối UART đến thiết bị Slave (RX ↔ TX).
- Kiểm tra slave ID và tốc độ baud.
- Sử dụng phần mềm như Modbus Poll để test thiết bị trước.
8. Tổng Kết
Chương trình này là một ví dụ đơn giản và hiệu quả để:
- Tích hợp WiFi + Modbus RTU trên ESP32.
- Đọc và chuyển đổi dữ liệu Modbus thành chuỗi dễ hiểu.
- Ứng dụng tốt cho việc giao tiếp cảm biến, module, PLC...
