Bài 5. Serial Monitor

Bài 5. Serial Monitor

Trong bài học này, chúng ta sẽ xây dựng mô hình như trong bài 4, có bổ sung thêm một số yếu tố để điều khiển LED từ trên máy tính sử dụng Arduino Serial Monitor. Trình theo dõi serial (serial monitor) là một kết nối giữa máy tính và Arduino – nó cho phép gửi và nhận các dòng văn bản (text), nhằm gỡ lỗi hoặc điều khiển Arduino từ máy tính.

Với ví dụ trong bài học này, bạn sẽ dùng tính năng này để gửi các lệnh điều khiển LED từ máy tính của bạn. Chúng ta cũng sẽ sử dụng các linh kiện tương tự như Bài 4. Do đó, nếu bạn chưa thực hành bài 4, hãy quay lại trước khi tiếp tục.

Chương trình Serial Monitor

Đầu tiên, hãy nạp sketch bên dưới vào Arduino. Sau đó, chúng ta sẽ phân tích cách mà chương trình làm việc.

/*
Bài 5. Serial Monitor
*/

int latchPin = 5;
int clockPin = 6;
int dataPin = 4;

byte leds = 0;

void setup()
{
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
updateShiftRegister();
Serial.begin(9600);
while (! Serial); // Wait untilSerial is ready - Leonardo
Serial.println("Enter LED Number 0 to 7 or 'x' to clear");
}

void loop()
{
if (Serial.available())
{
char ch = Serial.read();
if (ch >= '0' && ch <= '7')
{
int led = ch - '0';
bitSet(leds, led);
updateShiftRegister();
Serial.print("Turned on LED ");
Serial.println(led);
}
if (ch == 'x')
{
leds = 0;
updateShiftRegister();
Serial.println("Cleared");
}
}
}

void updateShiftRegister()
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, leds);
digitalWrite(latchPin, HIGH);
}

Sau khi nạp sketch vào board Arduino, nhấp vào biểu tượng bên phải của Arduino IDE như đã khoanh tròn bên dưới.

Cửa sổ bên dưới sẽ được mở ra

Cửa sổ này được gọi là trình theo dõi Serial (Serial Monitor) và là một phần của Arduino IDE. Chức năng của nó cho phép bạn gửi và nhận các thông điệp từ máy tính đến board Arduino và ngược lại (thông qua cáp USB).

Thông điệp “Enter LED Number 0 to 7 or ‘x’ to clear” được gửi từ Arduino, thông báo rằng chúng ta có thể gửi lệnh ‘x’ để tắt tất cả LED hoặc một con số từ 0 đến 7 để bật LED mang số tương ứng.

Hãy thử gõ dòng lệnh sau: x 0 3 5, trên ô nhập của Serial Monitor và nhấn nút ‘Send’. Các đèn LED tương ứng 0, 3, 5 được bật và cửa sổ Serial Monitor hiển thị như sau

Tiếp tục, gõ ‘x’, tất cả LED sẽ tắt. Hãy thử gõ một con số bất kì từ 1 đến 7 và quan sát hiệu ứng của chuỗi LED.

Code Arduino

Sketch sử dụng trong bài học này dựa trên Bài 4. Tuy nhiên, chúng ta sẽ thay đổi một chút ít. Hãy xem lại toàn bộ sketch của ví dụ này.

Đầu tiên, trong hàm ‘setup’, có 3 dòng lệnh mới thêm vào cuối.

void setup()
{
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
updateShiftRegister();
Serial.begin(9600);
while (! Serial); // Wait untilSerial is ready - Leonardo
Serial.println("Enter LED Number 0 to 7 or 'x' to clear");
}

Trước hết, chúng ta có lệnh ‘Serial.begin(9600)’. Điều này cho phép bắt đầu giao tiếp serial, do đó Arduino có thể gửi lệnh ra ngoài thông qua kết nối USB. Giá trị 9600 được gọi là ‘baud rate’ (tốc độ truyền) của kết nối. Bạn có thể thay đổi đến giá trị lớn hơn, tuy nhiên bạn cũng phải thay đổi giá trị này trang Arduino Serial Monitor cùng giá trị. Điều này chúng ta sẽ bàn đến sau, còn bây giờ hãy cứ để giá trị 9600.

Dòng lệnh bắt đầu với ‘while’ đảm bảo rằng đã có kết nối với máy tính trước khi nó gửi đi thông điệp. Nếu không, thông điệp sẽ được gửi, nhưng không hiển thị. Tuy nhiên, dòng này chỉ thực sự cần thiết nếu sử dụng Arduino Leonardo, bởi Arduino Uno sẽ tự động reset nếu bạn mở Serial Monitor, trong khi điều này không xảy ra trên board Leonardo.

Dòng lệnh cuối cùng trong hàm ‘setup’ gửi đi thông điệp mà chúng ta thấy ở cửa sổ Serial Monitor.

Hàm ‘loop’ là nơi mà tất cả các hoạt động diễn ra:

void loop()
{
if (Serial.available())
{
char ch = Serial.read();
if (ch >= '0' && ch <= '7')
{
int led = ch - '0';
bitSet(leds, led);
updateShiftRegister();
Serial.print("Turned on LED ");
Serial.println(led);
}

if (ch == 'x')
{
leds = 0;
updateShiftRegister();
Serial.println("Cleared");
}
}
}

Tất cả mọi thứ xảy ra bên trong hàm ‘loop’ được đặt trong một phát biểu ‘if’. Do đó nếu giá trị trả về của lệnh ‘Serial.available()’ không bằng ‘true’ thì không có việc gì xảy ra.

‘Serial.available()’ sẽ trả về giá trị ‘true’ nếu dữ liệu được gửi đến Arduino và sẵn sàng để xử lý. Thông điệp đến được lưu giữ ở bộ nhớ đệm và Serial.available() trả về ‘true’ nếu bộ nhớ đệm không rỗng.

Nếu có thông điệp đến, nó sẽ thực hiện dòng lệnh kế tiếp:

char ch = Serial.read();

Dòng lệnh này sẽ đọc một kí tự tiếp theo từ bộ nhớ đệm, sau đó loại bỏ nó khỏi bộ nhớ đệm. Kí tự này được đặt vào biến ‘ch’. Biến ‘ch’ được khai báo dưới dạng char, viết tắt của ‘character’ (kí tự), có khả năng lưu giữ được một kí tự đơn.

Nếu bạn tuân theo chỉ dẫn tại Serial Monitor, thì kí tự đó sẽ là một trong các số từ 0 đến 7 hoặc chữ ‘x’.

Phát biểu ‘if’ tiếp theo sẽ kiểm tra xem đó có phải là một số đơn hợp lệ hay không, bằng cách so sánh ‘ch’ lớn hơn hoặc bằng kí tự ‘0’ và bé hơn hoặc bằng kí tự ‘7’. Trông có vẻ đây là một cách so sánh kì dị, tuy vậy nó vẫn được chấp nhận.

Mỗi kí tự được đại diện bởi một con số duy nhất, được gọi là giá trị ASCII của chúng. Điều đó có nghĩa là khi chúng ta so sánh các kí tự sử dụng <= và >= thì thực sự chúng ta đang so sánh giá trị ASCII của chúng.

Nếu điều kiện đó được thỏa mãn, dòng lệnh tiếp theo được thực hiện:

int led = ch - '0';

Bây giờ chúng ta sẽ thực hiện phép tính số học với các kí tự. Chúng ta sẽ trừ đi ‘0’ từ bất cứ số nào chúng ta nhập vào. Do đó, nếu bạn gõ ‘0’ thì ‘0’ – ‘0’ sẽ bằng 0. Nếu bạn gõ ‘7’ thì ‘7’ – ‘0’ được 7 bởi thực sự giá trị ASCII của chúng mới được sử dụng trong phép trừ.

Khi biết được số của LED mà chúng ta muốn bất, chúng ta sẽ thực hiện lệnh bitSet trong biến ‘leds’ và cập nhật trạng thái của thanh ghi.

bitSet(leds, led);
updateShiftRegister();

Hai dòng tiếp theo sẽ gửi lại thông điệp xác nhận đến Serial Monitor.

Serial.print("Turned on LED ");
Serial.println(led);

Dòng đâu tiên sử dụng Serial.print thay vì Serial.println. Điểm khác biệt giữa hai lệnh này là Serial.print sẽ không bắt đầu một dòng mới sau khi gửi xong. Chúng ta sử dụng lệnh này trong dòng đầu tiên, vì chúng ta muốn gửi đi thông điệp gồm 2 phần. Phần đầu tiên là câu chung: ‘Turned on LED ‘ và theo sau đó là số thứ tự của LED.

Số thứ tự của LED được lưu trong một biến ‘int’. Serial.print có thể nhận một chuỗi kí tự đặt giữa hai dấu ngoặc kép, hoặc một ‘int’ hay một loại biến bất kì khác.

Sau phát biểu ‘if’ thứ nhất được thực hiện nếu một con số đơn được phát hiện, thì phát biểu ‘if’ thứ hai sẽ kiểm tra xem ‘ch’ có phải là kí tự ‘x’ hay không.

if (ch == 'x')
{
leds = 0;
updateShiftRegister();
Serial.println("Cleared");
}

Nếu đúng, nó sẽ tắt hết tất cả các LED và gửi một thông điệp xác nhận đến Serial Monitor.

Bạn có thể làm gì?

Chúng ta đã gửi kí tự để điều khiển LED một cách rời rạc, bằng cách nhấp vào send sau mỗi kí tự. Tuy nhiên, nó vẫn làm việc tốt, nếu bạn gửi tất cả kí tự trong một câu lệnh. Hãy thử gõ vào Serial Monitor chuỗi ‘x0246’ và nhấp ‘Send’.

Bây giờ, hãy tìm hiểu xem Arduino có thể giao tiếp nhanh như thế nào. Thay đổi ‘baud rate’ trong sketch từ 9600 sang 115200 và nạp lại vào board. Sau đó, mở Serial Monitor và chọn 115200 từ danh sách.

Bạn có thể thấy rằng mọi thứ vẫn làm việc tốt. Giao tiếp với tốc độ cao thường không cần thiết, do đó baud rate 9600 thường được lựa chọn sử dụng, như nhiều thiết bị ngoại vi serial chẳng hạn mô-đun GPS sẽ đặt giá trị này là baud rate mặc định.

Thử thay đổi baud rate không trùng khớp – sử dụng Serial.begin(9600) và chọn 57600 trong danh sách. Hãy xem kết quả!

Serial Monitor cũng là một cách gỡ lỗi sketch hiệu quả. Đôi khi, nếu sketch không thực hiện đúng như mong muốn của chúng ta, hãy đặt hàm Serial.println() vào vị trí đó để kiểm tra chương trình xử lý có đúng như kế hoạch hay không.

Chia sẻ bài này

Comments (2)

  • Long Reply

    ở dòng 6 trong hàm loop em chép bị lỗi chưa khai báo ‘gt’ ‘amp’ ‘lt’ và lỗi dấu ‘=’ và ‘;’ (&&amp)

    Tháng mười một 18, 2024 at 8:11 chiều
    • OpenBuilds Reply

      Cảm ơn bạn. Mình đã sửa lại bài, do lỗi trong quá trình copy code nhé. Bạn xem và thử lại!

      Tháng ba 11, 2025 at 12:12 chiều

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *