Site icon TAPIT

Truyền nhận dữ liệu với giao tiếp Serial (UART) trên Arduino

Chuẩn giao tiếp truyền thông nối tiếp UART trên Arduino (hay còn được biết đến với tên gọi Serial) là chuẩn giao tiếp được sử dụng rất nhiều trong các ứng dụng hệ thống nhúng. Trong bài viết này, mình sẽ hướng dẫn các bạn tiếp cận và lập trình với giao tiếp UART một cách đơn giản nhất, còn về cơ bản sâu hơn thì các bạn xem tại bài viết này.

Khai báo UART: 
– Có 2 cách để khai báo sử dụng UART trên Arduino, nhưng phổ biến nhất là Serial.begin(9600), trong đó 9600 là tốc độ baud và sử dụng khung truyền mặc định 8-N-1 (8 bit dữ liệu, không sử dụng bit kiểm tra chẵn lẻ, 1 bit kết thúc). Bạn có thể tìm hiểu kĩ hơn tại đây.  Đồng thời việc khai báo này cũng chuyển chân digital 0 và digital 1 thành chức năng truyền nhận dữ liệu: Chân digital 0 được gắn với bộ nhận dữ liệu bên trong vi điều khiển và chân digiatal 1 được nối với bộ truyền dữ liệu bên trong vi điều khiển.


Nối dây 2 thiết bị: 
– Nếu các bạn sử dụng Board Arduino để giao tiếp với máy tính (sử dụng cửa sổ Serial monitor trên ARDUINO IDE) thì không cần phải nối thêm gì cả vì trên board Arduino đã thực hiện sẵn việc đó, chỉ cần cắm cab USB vào là được. Để hiểu thêm về cấu trúc của board Arduino thì các bạn có thể xem qua bài viết này.
– Nếu các bạn sử dụng Arduino để giao tiếp với 1 thiết bị, 1 module khác thì các bạn nối chéo, TX – RX và RX – TX và đừng quên 1 điều là kiểm tra xem 2 thiết bị đã chung GND chưa, vì nếu chưa thì chúng sẽ không hiểu mức logic của nhau ==> không giao tiếp được.
– Phức tạp hơn tí nữa là nếu như 2 thiết bị khác mức logic, ví dụ như 1 thiết bị 5v giao tiếp với 1 thiết bị 3.3V thì các bạn cần thêm các mạch để chuyển đổi điện áp cho phù hợp.

Truyền dữ liệu:
– Để truyền dữ liệu thì các bạn sử dụng hàm Serial.print(x); trong đó x là cái mà các bạn muốn in lên ở bất kì kiểu dữ liệu gì cũng được, rất tiện lợi. Nếu bạn muốn truyền thêm ký tự kết thúc câu (\r)  và ký tự xuống dòng (\n) thì sử dụng Serial.println(x) là được.

Nhận dữ liệu: 
– Nền tảng Arduino đã hỗ trợ người dùng rất nhiều khi đã xây dựng sẵn 1 bộ đệm UART (buffer) có kích cỡ 64byte(Arduino Uno). Mỗi lần nhận 1 ký tự thì ký tự này sẽ được tự động chuyển vào bộ đệm. Người dùng muốn đọc dữ liệu chỉ cần làm việc với bộ đệm là được. Vậy làm việc với bộ đệm như thế nào?
+ Kiểm tra bộ đệm: Trước khi thực hiện thao tác đọc và xử lý dữ liệu của thiết bị khác gửi đến thì nên kiểm tra bộ đệm trước. Câu lệnh Serial.available() sẽ trả về cho các bạn số kí tự (byte) hiện có trong bộ đệm. ==>Bạn sử dụng lệnh: if(Serial.available()) {đọc và xử lý dữ liệu khi có dữ liệu}
+ Đọc dữ liệu: Để đọc 1byte từ bộ đệm các bạn sử dụng lệnh Serial.read(); Tuy nhiên trong thực tế thì hầu hết chúng ta cần đọc 1 chuỗi ký tự. Các bạn có thể đọc từng ký tự, sau đó ghép chúng lại thành 1 chuỗi hoặc sử dụng kiểu dữ liệu String mà Arduino hỗ trợ (lưu ý String chữ S viết hoa). Lệnh Serial.readString() sẽ giúp các bạn đọc được tất cả các kí tự có trong bộ đệm.
+ Lưu ý: Bộ đệm UART sẽ mất dữ liệu ngay sau khi các bạn đọc. Vì vậy bạn nên đọc và lưu ra 1 biến và làm việc với biến đó. 

Kiểu String:
Kiểu String trong Arduino giúp cho người dùng thao tác với chuỗi đơn giản hơn với rất nhiều hàm hỗ trợ. Mình giới thiệu 1 số hàm phổ biến mà các bạn thường gặp tại đây. 

1. myString.indexOf(val): Hàm này sẽ giúp bạn tìm được vị trí của 1 ký tự hoặc 1 chuỗi (val) trong 1 chuỗi khác (myString). Xem chi tiết tại đây
2. myString.toInt(): Từ trên màn hình Serial Monitor các bạn bấm 168 để gửi đi thì Arduino sẽ nhận được chuỗi “168”, để khôi phục lại thành số 168 thì các bạn sử dụng hàm toInt(). Xem chi tiết hơn tại đây.
3. substring(): Trong một chuỗi dữ liệu lớn nhận được thì sẽ có phần dữ liệu nằm trong chuỗi đó mà các bạn cần tách ra để sử dụng. Lúc này hàm substring sẽ là trợ thủ đắc lực cho bạn. Xem chi tiết hơn tại đây.
4. myString.toCharArray(): Hàm này giúp các bạn chuyển chuỗi ở kiểu String thành 1 mảng kiểu char. Khi làm việc với một số thư viện, người phát triển đã khai báo sẵn các hàm có các tham số kiểu char *, lúc này các bạn có thể truyền vào char * hoặc char array, còn String thì không được chấp nhận, vì vậy việc chuyển đổi kiểu dữ liệu là cần thiết, xem thêm tại đây. Khi chuyển String thành mảng thì các bạn có thể sử dụng thêm hàm length() để xác định được số lượng phần tử của mảng, xem thêm tại đây. (sau đó nhớ cộng thêm 1 vì sử dụng mảng kiểu char để lưu chuỗi thì cần có ký tự Null sau cùng).

Nếu có thắc mắc gì, các bạn cứ bình luận để thảo luận thêm cho rõ nha.  Chúc các bạn thành công!
Xem thêm:  Tổng hợp hướng dẫn Internet of Things với NodeMCU ESP8266 và ESP32

Thuong Nguyen