IoTLabs

Nghiên cứu, Sáng tạo và Thử nghiệm

Serial UART — Giao Tiếp Arduino với Máy Tính và Debug Chương Trình

Serial UART Là Gì?

UART (Universal Asynchronous Receiver/Transmitter) là giao thức truyền thông nối tiếp — dữ liệu gửi từng bit một qua 2 dây:

  • TX (Transmit): Gửi dữ liệu — chân D1 trên Arduino Uno
  • RX (Receive): Nhận dữ liệu — chân D0 trên Arduino Uno

Khi cắm cáp USB vào máy tính, chip USB (ATmega16U2 hoặc CH340) chuyển đổi giữa USB và UART — cho phép Arduino “nói chuyện” với máy tính qua Serial Monitor.

Ứng dụng chính:

  • Debug: in giá trị biến, trạng thái chương trình
  • Nhận lệnh từ máy tính (điều khiển từ terminal)
  • Truyền dữ liệu cảm biến lên máy tính
  • Giao tiếp giữa 2 Arduino hoặc với module GPS, GSM, BT

Khởi Tạo Serial

void setup() {
  Serial.begin(9600); // Baud rate: số bit/giây
}

Baud rate phổ biến: 9600, 115200 (nhanh hơn, dùng khi cần truyền nhiều data).

Quan trọng: Baud rate trong code phải khớp với Serial Monitor — nếu khác sẽ thấy ký tự lạ.

Gửi Dữ Liệu Lên Máy Tính

Serial.print()Serial.println()

Serial.print("Nhiệt độ: ");   // In không xuống dòng
Serial.println(25.5);         // In + xuống dòng
Serial.println();             // Dòng trống

Các dạng dữ liệu:

Serial.println(42);            // Int: "42"
Serial.println(3.14159, 2);    // Float 2 chữ số thập phân: "3.14"
Serial.println("Hello IoT");   // String
Serial.println(true);          // Boolean: "1" (true=1, false=0)
Serial.println(255, HEX);      // Hex: "FF"
Serial.println(255, BIN);      // Binary: "11111111"

In Nhiều Biến Trên Một Dòng

int temp = 28;
float humidity = 65.5;

Serial.print("T=");
Serial.print(temp);
Serial.print("°C, H=");
Serial.print(humidity, 1);
Serial.println("%");
// Output: T=28°C, H=65.5%

📷 [Hình minh hoạ: Sơ đồ luồng Serial UART Arduino ↔ PC — mũi tên TX/RX, USB-B, cửa sổ Serial Monitor, teal arrows trên nền trắng]

Mở Serial Monitor

Trong Arduino IDE 2:

  • Nút magnifying glass góc phải màn hình
  • Hoặc Ctrl+Shift+M (Windows) / Cmd+Shift+M (macOS)

Chú ý chọn đúng baud rate ở góc dưới phải Serial Monitor (phải khớp với Serial.begin()).

Đọc Dữ Liệu Từ Máy Tính

Kiểm Tra Dữ Liệu Có Sẵn

if (Serial.available() > 0) {
  // Có dữ liệu trong buffer
}

Serial.available() trả về số byte đang chờ trong buffer (0 nếu không có gì).

Đọc Từng Byte

void loop() {
  if (Serial.available() > 0) {
    char received = Serial.read(); // Đọc 1 byte
    Serial.print("Nhận được: ");
    Serial.println(received);
  }
}

Gõ một ký tự trong Serial Monitor → Arduino in lại ký tự đó.

Nhận Lệnh Điều Khiển LED

const int LED_PIN = 13;

void setup() {
  pinMode(LED_PIN, OUTPUT);
  Serial.begin(9600);
  Serial.println("Gõ '1' để bật LED, '0' để tắt");
}

void loop() {
  if (Serial.available() > 0) {
    char cmd = Serial.read();

    if (cmd == '1') {
      digitalWrite(LED_PIN, HIGH);
      Serial.println("LED: BẬT");
    } else if (cmd == '0') {
      digitalWrite(LED_PIN, LOW);
      Serial.println("LED: TẮT");
    }
  }
}

Đọc Chuỗi Lệnh

String inputBuffer = "";

void setup() {
  Serial.begin(9600);
  Serial.println("Sẵn sàng nhận lệnh:");
}

void loop() {
  while (Serial.available() > 0) {
    char c = Serial.read();

    if (c == '\n') {
      // Nhận được dòng hoàn chỉnh
      processCommand(inputBuffer);
      inputBuffer = "";
    } else if (c != '\r') {
      inputBuffer += c;
    }
  }
}

void processCommand(String cmd) {
  cmd.trim();
  Serial.print("Lệnh nhận: [");
  Serial.print(cmd);
  Serial.println("]");

  if (cmd == "STATUS") {
    Serial.println("OK - Arduino đang chạy");
  } else if (cmd.startsWith("LED:")) {
    String val = cmd.substring(4);
    digitalWrite(13, val == "ON" ? HIGH : LOW);
    Serial.println("LED đã được " + val);
  }
}

Gửi lệnh LED:ON hoặc LED:OFF từ Serial Monitor (chọn “Both NL & CR”).

Debug Cảm Biến Theo Thời Gian Thực

const int LDR_PIN = A0;
const int POT_PIN = A1;
unsigned long lastPrint = 0;

void setup() {
  Serial.begin(115200); // Baud cao hơn cho nhiều data
}

void loop() {
  if (millis() - lastPrint >= 500) {
    lastPrint = millis();

    int ldr = analogRead(LDR_PIN);
    int pot = analogRead(POT_PIN);

    // Format dễ copy vào Excel/Python
    Serial.print(millis()); Serial.print(",");
    Serial.print(ldr);      Serial.print(",");
    Serial.println(pot);
  }
}

Copy data từ Serial Monitor → paste vào Excel để vẽ đồ thị.

Serial.write() vs Serial.print()

Serial.print(65);     // In "65" (chuỗi text)
Serial.write(65);     // Gửi byte có giá trị 65 → hiện ký tự 'A'

write() gửi byte thô — dùng khi giao tiếp với thiết bị nhận binary data.

Tổng Kết

HàmChức năng
Serial.begin(9600)Khởi động Serial ở 9600 baud
Serial.print(x)Gửi dữ liệu, không xuống dòng
Serial.println(x)Gửi dữ liệu + xuống dòng
Serial.available()Số byte đang chờ đọc
Serial.read()Đọc 1 byte từ buffer

Serial UART là công cụ debug số 1 cho Arduino — luôn mở Serial Monitor khi phát triển dự án.

Bài tiếp theo: Servo Motor — điều khiển góc quay chính xác từ 0° đến 180° với thư viện Servo.h.