USB Native vs USB-UART: Khác Biệt Quyết Định
Trước khi viết dòng code nào, cần phân biệt rõ 2 loại USB trên board ESP32-S3:
USB-UART Bridge (CH340/CP2102)
- Chip bridge riêng trên board (thường là CH340G hoặc CP2102)
- Chuyển đổi UART của ESP32 → USB
- Máy tính thấy: cổng COM/ttyUSB (Serial port)
- Dùng để: upload code, Serial Monitor
- Không phải USB native của ESP32-S3
USB OTG Native (ESP32-S3)
- Trực tiếp từ chip ESP32-S3 ra connector USB
- Máy tính thấy: tùy bạn lập trình — CDC, HID, Mass Storage, v.v.
- Cần: board dẫn chân GPIO19 (D-) và GPIO20 (D+) ra connector USB
- Đây là USB thực sự, do firmware ESP32-S3 điều khiển
Cổng USB thứ 1 (thường là UART/JTAG):
→ Qua CH340 → Upload code, Serial Monitor thông thường
Cổng USB thứ 2 (Native USB):
→ Trực tiếp từ ESP32-S3 → CDC, HID, MSC, Host
Board ESP32-S3-DevKitC-1 có cả 2 cổng USB, ghi rõ “UART” và “USB” trên board.
Tại Sao USB Native Hữu Ích?
| Tính năng | USB-UART Bridge | USB OTG Native |
|---|---|---|
| Serial debug | Có | Có (CDC) |
| HID Keyboard/Mouse | Không | Có |
| USB Mass Storage | Không | Có |
| USB Audio | Không | Có |
| USB Host | Không | Có (giới hạn) |
| Tốc độ | Theo UART baud rate | Full Speed 12 Mbps |
| Cần driver PC | CH340 driver | Không (CDC tự nhận) |
CDC: USB Serial Không Cần Driver
CDC (Communication Device Class) cho phép ESP32-S3 xuất hiện như một cổng Serial trên máy tính — không cần driver, tự nhận trên Windows 10+, macOS và Linux:
#include "USB.h"
#include "USBCDC.h"
USBCDC USBSerial;
void setup() {
// Khởi động USB CDC
USB.begin();
USBSerial.begin(115200); // Baud rate chỉ là placeholder, USB không dùng
delay(1000); // Chờ host nhận device
USBSerial.println("ESP32-S3 USB CDC ready!");
}
void loop() {
// Đọc từ máy tính
if (USBSerial.available()) {
String cmd = USBSerial.readStringUntil('\n');
USBSerial.printf("Nhận: %s\n", cmd.c_str());
if (cmd.trim() == "status") {
USBSerial.printf("Heap: %lu KB\n", ESP.getFreeHeap() / 1024);
USBSerial.printf("Core: %d\n", xPortGetCoreID());
}
}
}
Máy tính sẽ thấy cổng COM mới (Windows) hoặc /dev/ttyACM0 (Linux) — không cần cài driver.
HID Keyboard: Biến ESP32-S3 Thành Bàn Phím
HID (Human Interface Device) cho phép ESP32-S3 gửi keystroke, mouse movement đến máy tính:
#include "USB.h"
#include "USBHIDKeyboard.h"
USBHIDKeyboard Keyboard;
void setup() {
// Đặt tên device (hiện trong Device Manager)
USB.manufacturerName("IoTLabs");
USB.productName("ESP32-S3 Macro Pad");
USB.begin();
Keyboard.begin();
delay(1000);
}
void loop() {
// Gửi Ctrl+C khi nút được nhấn
if (digitalRead(BUTTON_PIN) == LOW) {
Keyboard.press(KEY_LEFT_CTRL);
Keyboard.press('c');
delay(50);
Keyboard.releaseAll();
delay(200); // Debounce
}
}
Ứng dụng thực tế:
// Macro pad: gửi keyboard shortcut phức tạp
void sendVSCodeDebugShortcut() {
Keyboard.press(KEY_LEFT_CTRL);
Keyboard.press(KEY_LEFT_SHIFT);
Keyboard.press('d');
delay(100);
Keyboard.releaseAll();
}
// Tự động điền form (cẩn thận với bảo mật!)
void typeText(const char* text) {
Keyboard.print(text); // Gõ cả chuỗi text
}
HID Mouse: Con Chuột USB
#include "USB.h"
#include "USBHIDMouse.h"
USBHIDMouse Mouse;
void setup() {
USB.begin();
Mouse.begin();
delay(1000);
}
void loop() {
int x = map(analogRead(JOYSTICK_X), 0, 4095, -10, 10);
int y = map(analogRead(JOYSTICK_Y), 0, 4095, -10, 10);
Mouse.move(x, y, 0); // Di chuyển cursor
if (digitalRead(CLICK_BTN) == LOW) {
Mouse.click(MOUSE_LEFT);
delay(200);
}
delay(20); // ~50 fps
}
CDC + HID Kết Hợp
Một ESP32-S3 có thể vừa là CDC Serial vừa là HID cùng lúc (composite device):
#include "USB.h"
#include "USBCDC.h"
#include "USBHIDKeyboard.h"
USBCDC USBSerial;
USBHIDKeyboard Keyboard;
void setup() {
USB.begin();
USBSerial.begin();
Keyboard.begin();
delay(1000);
USBSerial.println("Composite USB: CDC + HID ready");
}
void loop() {
// Nhận lệnh từ Serial để gửi keypress
if (USBSerial.available()) {
String cmd = USBSerial.readStringUntil('\n');
if (cmd.startsWith("key:")) {
String keyStr = cmd.substring(4);
Keyboard.print(keyStr.c_str());
USBSerial.printf("Sent: %s\n", keyStr.c_str());
}
}
}
USB Host: Kết Nối Thiết Bị USB Vào ESP32-S3
ESP32-S3 có thể làm USB Host — kết nối bàn phím, chuột, USB hub vào ESP32-S3. Cần thêm mạch VBUS switch để cấp 5V cho thiết bị ngoài.
Thư viện: esp_tinyusb (ESP-IDF) hoặc USB Host Shield ported.
#include "usb/usb_host.h"
#include "class/hid/hid_host.h"
// Callback khi có thiết bị HID kết nối vào
void hid_host_event_callback(hid_host_device_handle_t hid_device_handle,
const hid_host_driver_event_t event, void* arg) {
switch (event) {
case HID_HOST_DRIVER_EVENT_CONNECTED:
Serial.println("HID device connected!");
// Lấy report descriptor, xác định là keyboard hay mouse
break;
case HID_HOST_DRIVER_EVENT_DISCONNECTED:
Serial.println("HID device disconnected");
break;
}
}
USB Host thực tế trên ESP32-S3 còn hạn chế và cần ESP-IDF, chưa hoàn thiện trong Arduino framework. Dùng được cho kết nối bàn phím/chuột đơn giản.
Lưu Ý Quan Trọng
1. Bootloop khi chỉ có USB Native
Nếu board chỉ có cổng USB Native (không có UART bridge), bạn cần bật USB CDC On Boot trong Arduino IDE:
- Tools → USB CDC On Boot: Enabled
- Khi bật: Serial (UART) và USBSerial (CDC) hoạt động song song
- Không bật:
Serial.println()không ra USB CDC
2. Upload khi dùng USB Native
Khi upload qua cổng USB Native:
- Giữ nút BOOT
- Nhấn RESET
- Thả BOOT
- Board vào bootloader mode → upload được
3. Không phải board nào cũng có USB Native
Kiểm tra datasheet board: chân GPIO19 và GPIO20 phải được dẫn ra connector USB. Một số board chỉ dùng USB-UART bridge, không expose USB native.
Tổng Kết
| Mode USB | Thư Viện | Dùng Cho |
|---|---|---|
| CDC Serial | USBCDC | Debug, command interface không cần driver |
| HID Keyboard | USBHIDKeyboard | Macro pad, shortcut controller |
| HID Mouse | USBHIDMouse | Custom pointing device |
| HID Gamepad | USBHIDGamepad | Game controller |
| Mass Storage | USBMSC | Xuất file SD card qua USB |
| Host HID | usb_host (ESP-IDF) | Đọc bàn phím/chuột cắm vào |
Bài tiếp theo: Bài 8 — Edge AI Trên ESP32-S3: SIMD, ESP-DSP, ESP-NN và Giới Hạn Thực Tế — Vector instructions làm gì, ESP-DSP cho FFT và signal processing, TFLite Micro và thực tế AI trên chip nhúng.
📚 Series: Sức Mạnh ESP32-S3 Dual-Core
⬅️ Bài trước: S3 Dual-Core – Bài 6: DMA, LCD, Camera Giao Tiếp Tốc Độ Cao
➡️ Bài tiếp theo: S3 Dual-Core – Bài 8: Edge AI – ESP-DSP, ESP-NN Giới Hạn Thực Tế


