BÀI 17 : UART-GIAO TIẾP GIỮ A2 ARDUINO
1. Giới thiệu UART
Hình 17.1. Chân giao tiếp Uart trên Arduino UNO
* 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). Ta 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ộ
147
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.
Example Code Void setup()
{
Serial.begin(9600);// mở cổng giao tiếp và cài đặt dữ liệu }
Void loop() { }
* Nốidây 2 thiếtbị:
Nếu ta 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 vì trên board Arduino đã thực hiện sẵn việc đó, chỉ cần cắm cab USB vào là đƣợc. Nếu ta sử dụng Arduino để giao tiếp với 1 thiết bị, 1 module khác thì tanố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 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ì ta cần thêm các mạch để chuyển đổi điện áp cho phù hợp.
Hình 17.1. giao tiêp giữa 2 thiết bị
* Truyềndữliệu:
Để truyền dữ liệu thì tasử dụng hàm Serial.print(x); trong đó x là cái mà tamuốn in lên ở bất kì kiểu dữ liệu gì cũng đƣợc, rất tiện lợi. Nếu ta muốn truyền
148
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ậndữ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.
+ 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 tasố kí tự (byte) hiện có trong bộ đệm. ==>Ta sử dụng lệnh:
if(Serial.available())
{đọcvàxử lýdữliệu khi códữliệu}
+ Đọc dữ liệu: Để đọc 1byte từ bộ đệm tasử 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ự. Tacó 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 tađọ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 tađọc. Vì vậy ta 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ợ.
- myString.indexOf(val):
Hàm này sẽ giúp ta tìm đƣợc vị trí của 1 ký tự hoặc 1 chuỗi (val) trong 1 chuỗi khác (myString).
- myString.toInt():
Từ trên màn hình Serial Monitor ta 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ì tasử dụng hàm toInt().
- 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à tacần tách ra để sử dụng. Lúc này hàm substring sẽ là trợ thủ đắc lực cho ta.
- myString.toCharArray():
Hàm này giúp tachuyể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 tacó 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. Khi chuyển String
149
thành mảng thì tacó thể sử dụng thêm hàm length() để xác định đƣợc số lƣợng phần tử của mảng (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).
2. Phần cứng
*Chuẩn bị:
- Mạch Arduino (ở đây mình sử dụng Arduino UNO) (Truyền dữ liệu). - Mạch Arduino hoặc Nano,… (ở đây mình sử dụng Arduino UNO) (Nhận dữ liệu).
- Breadboard còn gọi testboard. - Dây cắm test board.
- 1 led đơn. - trở 220Ohm. *Lắp mạch:
150
3. Lập trình và giải thích
* Chương trình ( code) upload cho Arduino Truyền lệnh:
void setup() {
Serial.begin(9600); // Bạn khởi tạo một cổng Serial tại baudrate 9600. }
int Step = 0; void loop() { if (Step == 0) { Serial.println("LED_RED 1"); // Đèn đỏ sáng. 1 == HIGH } else if (Step == 1) { Serial.println("LED_RED 0"); // Đèn đỏ tắt . 0 == LOW }
Step = (Step + 1) % 2; //Step sẽ tuần tự tuần hoàn các giá trị trong khoảng từ 0 -- > 1
delay(500); // Dừng 1/2 giây giữa các lần gửi }
* Chương trình ( code) upload cho Arduino nhận lệnh:
#include <SoftwareSerial.h>
#include <SerialCommand.h> // Khai báo biến sử dụng thƣ viện Serial Command SerialCommand sCmd;
int red = 8; void setup() {
Serial.begin(9600); / /Khởi tạo Serial ở baudrate 9600 . pinMode(red,OUTPUT);
// Một số hàm trong thƣ viện Serial Command
sCmd.addCommand("LED_RED",led_red); // Khi có câu lệnh tên là LED_RED sẽ chạy hàm led_red
}
void loop() { sCmd.readSerial();
//Ta không cần phải thêm bất kỳ dòng code nào trong hàm loop này cả }
// hàm led_red sẽ đƣợc thực thi khi gửi hàm LED_RED void led_red() {
//Đoạn code này dùng để đọc từng tham số. Các tham số mặc định có kiểu dữ liệu là "chuỗi"
151 char *arg;
arg = sCmd.next();
int value = atoi(arg); // Chuyển chuỗi thành số digitalWrite(red,value);
}
Câu hỏi ôn tập
Câu 1: Nêu công dụng của UART ?
Câu 2: Kết nối phần cứng và viết chƣơng trình điều khiển led đơn qua giao tiếp serial giữa Arduino và PC?
Tài liệu tham khảo:
[1]Dự án Giáo dục kỹ thuật và Dạy nghề (VTEP), Tổng cục Dạy Nghề, Hà Nội, 2003
[2]Walter H. Buchbaum. Sc.D, Microprocessor and IC families
[3]HPI Fachbuchreihen Pflaum Verlag Munchen - Mikrocompute Lehrbuch [4] I. Scott Makenzie - The avr Atmega16 microcontroller