(Khóa học: Lập trình & Điều khiển Động Cơ từ Cơ Bản tới Nâng Cao)
? Mục tiêu bài học
Trong phần 6 này, chúng ta sẽ nâng cấp hệ thống điều khiển robot không dây lên cấp độ chuyên nghiệp hơn — đó là truyền dữ liệu hai chiều (bi-directional communication) giữa tay cầm điều khiển (TX) và xe robot (RX) qua sóng RF 2.4GHz sử dụng module NRF24L01.
Hệ thống này không chỉ gửi lệnh điều khiển từ tay cầm tới robot, mà còn cho phép robot gửi ngược dữ liệu cảm biến, tốc độ, và trạng thái pin trở lại tay cầm, giúp người điều khiển theo dõi trạng thái thực tế của robot theo thời gian thực.
? 1. Tổng quan hệ thống truyền dữ liệu 2 chiều
Sơ đồ khái niệm:
| Vai trò | Thiết bị | Chức năng |
|---|---|---|
| TX (Transmitter) | ESP32-C3 + NRF24L01 | Gửi lệnh điều khiển, nhận dữ liệu phản hồi |
| RX (Receiver) | ESP32 DevKit + NRF24L01 | Nhận lệnh điều khiển, gửi dữ liệu cảm biến phản hồi |
? Giao tiếp 2 chiều giúp hệ thống hoạt động như một cặp song công giả lập (Half-Duplex):
- TX gửi → RX nhận
- Sau đó RX phản hồi → TX nhận
NRF24L01 hỗ trợ sẵn cơ chế Auto-Ack + payload reply, cho phép gửi dữ liệu phản hồi trong cùng một chu kỳ truyền.
⚙️ 2. Dữ liệu cần truyền giữa hai thiết bị
| Hướng truyền | Nội dung | Mục đích |
|---|---|---|
| TX → RX | action, speed, mode | Điều khiển hướng, tốc độ, chế độ |
| RX → TX | distance, voltage, status | Gửi dữ liệu cảm biến và trạng thái pin |
? 3. Cấu trúc dữ liệu truyền
Gói lệnh điều khiển (TX → RX)
struct ControlPacket {
char action; // 'F','B','L','R','S'
uint8_t speed; // 0..255
bool sportMode; // 1 = Sport, 0 = Kid
};
Gói dữ liệu phản hồi (RX → TX)
struct FeedbackPacket {
uint16_t distance; // Khoảng cách cảm biến HC-SR04
float voltage; // Điện áp pin (V)
uint8_t status; // 1 = OK, 0 = Low Power / Warning
};
? 4. Lập trình phía robot (RX) – Gửi phản hồi về tay cầm
Robot (Receiver) nhận lệnh điều khiển, thực thi, sau đó gửi phản hồi lại.
? Code mẫu:
#include <SPI.h>
#include <RF24.h>
#define CE_PIN 17
#define CSN_PIN 16
RF24 radio(CE_PIN, CSN_PIN);
const byte address[6] = "ROBOT";
struct ControlPacket {
char action;
uint8_t speed;
bool sportMode;
};
struct FeedbackPacket {
uint16_t distance;
float voltage;
uint8_t status;
};
ControlPacket cmd;
FeedbackPacket fb;
#define TRIG 12
#define ECHO 14
#define BAT_PIN 34
uint16_t readDistance() {
digitalWrite(TRIG, LOW); delayMicroseconds(2);
digitalWrite(TRIG, HIGH); delayMicroseconds(10);
digitalWrite(TRIG, LOW);
long duration = pulseIn(ECHO, HIGH, 30000);
return duration * 0.034 / 2;
}
float readBattery() {
int raw = analogRead(BAT_PIN);
return raw * (3.3 / 4095.0) * 2; // chia đôi mạch đo pin
}
void setup() {
Serial.begin(115200);
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
pinMode(BAT_PIN, INPUT);
SPI.begin();
radio.begin();
radio.openReadingPipe(1, address);
radio.startListening();
Serial.println("RX ready with feedback");
}
void loop() {
if (radio.available()) {
radio.read(&cmd, sizeof(cmd));
// Xử lý điều khiển robot
Serial.printf("Recv %c (%d)\n", cmd.action, cmd.speed);
// Chuẩn bị phản hồi
fb.distance = readDistance();
fb.voltage = readBattery();
fb.status = (fb.voltage > 6.8) ? 1 : 0;
// Gửi lại phản hồi cho TX
radio.stopListening();
radio.write(&fb, sizeof(fb));
radio.startListening();
delay(50);
}
}
?️ 5. Lập trình tay cầm (TX) – Nhận dữ liệu phản hồi
Tay cầm (Transmitter) sau khi gửi lệnh, chờ và nhận dữ liệu phản hồi từ robot.
Code mẫu:
#include <SPI.h>
#include <RF24.h>
#define CE_PIN 7
#define CSN_PIN 10
RF24 radio(CE_PIN, CSN_PIN);
const byte address[6] = "ROBOT";
struct ControlPacket {
char action;
uint8_t speed;
bool sportMode;
};
struct FeedbackPacket {
uint16_t distance;
float voltage;
uint8_t status;
};
ControlPacket cmd;
FeedbackPacket fb;
void setup() {
Serial.begin(115200);
SPI.begin();
radio.begin();
radio.openWritingPipe(address);
radio.stopListening();
Serial.println("TX ready for feedback");
}
void loop() {
cmd.action = 'F';
cmd.speed = 200;
cmd.sportMode = true;
radio.write(&cmd, sizeof(cmd));
// Nghe phản hồi
radio.startListening();
unsigned long start = millis();
while (!radio.available() && millis() - start < 100) { delay(2); }
if (radio.available()) {
radio.read(&fb, sizeof(fb));
Serial.printf("Distance: %d cm | Battery: %.2fV | Status: %s\n",
fb.distance, fb.voltage, fb.status ? "OK" : "LOW");
}
radio.stopListening();
delay(200);
}
⚡ 6. Giải thích cơ chế truyền hai chiều
- TX gửi gói lệnh điều khiển → RX nhận.
- RX thực thi lệnh, đọc cảm biến → gửi phản hồi lại.
- TX đọc dữ liệu phản hồi và hiển thị trên Serial hoặc OLED.
- Quá trình lặp lại liên tục với tốc độ ~5–10 lần/giây.
? Với cấu trúc này, tay cầm và robot hoạt động như một hệ thống song công giả lập (Half-duplex communication).
? 7. Hiển thị phản hồi trực quan trên OLED (TX)
Tay cầm có thể hiển thị thông tin phản hồi:
| Dữ liệu | Hiển thị |
|---|---|
| distance | Khoảng cách vật cản (cm) |
| voltage | Mức pin của robot |
| status | “OK” hoặc “LOW BATTERY” |
Code hiển thị OLED:
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 oled(128, 64, &Wire, -1);
void showFeedback() {
oled.clearDisplay();
oled.setTextSize(1);
oled.setTextColor(SSD1306_WHITE);
oled.setCursor(0, 0);
oled.printf("Dist: %d cm\n", fb.distance);
oled.printf("Volt: %.2fV\n", fb.voltage);
oled.printf("Status: %s\n", fb.status ? "OK" : "LOW");
oled.display();
}
? 8. Kiểm thử và kết quả
| Tình huống | Kết quả mong đợi |
|---|---|
| Robot hoạt động bình thường | TX hiển thị dữ liệu cập nhật ổn định |
| Pin yếu | TX nhận cảnh báo “LOW” |
| Vật cản gần | TX hiển thị khoảng cách giảm |
| Mất kết nối | TX không nhận phản hồi → cảnh báo mất sóng |
? 9. Lợi ích của truyền dữ liệu hai chiều
| Lợi ích | Ý nghĩa |
|---|---|
| ? Theo dõi trạng thái robot | Biết được tình trạng pin, khoảng cách vật cản |
| ? Phản hồi thông minh | Có thể hiển thị thông báo và cảnh báo real-time |
| ⚡ Điều khiển chính xác hơn | Tay cầm điều chỉnh tốc độ dựa trên phản hồi |
| ?️ Tăng tính an toàn | Robot có thể dừng khi pin yếu hoặc gặp vật cản |
? 10. Bước tiếp theo
Trong (phần 7): Kiểm thử & Demo thực tế, bạn sẽ học cách tổng hợp toàn bộ hệ thống — từ điều khiển, báo hiệu, truyền dữ liệu 2 chiều — để thực hiện demo robot hoàn chỉnh và đo hiệu suất thực tế của hệ thống.



Leave a Reply