lOMoARcPSD| 60776878
TRƯỜNG ĐẠI HỌC KỸ THUẬT - CÔNG NGHỆ CẦN THƠ
KHOA ĐIỆN - ĐIỆN TỬ
-----
-----
BÁO CÁO
THỰC HÀNH
VI ĐIỀU KHIỂN
SINH VIÊN THỰC HIỆN
:
Nhóm:
1
Học kỳ 2
Năm học: 202
4
-202
5
lOMoARcPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 01
Xin cam kết số liệu báo cáo, các câu trả lời do tự cá nhân làm và số liệu ghi nhận được
từ thí nghiệm, không có sao chép của bất kỳ ai. Nếu sự sao chép bất nội dung nào
sẽ nhận điểm 0 (không).
Người cam kết ký và ghi rõ họ tên: ....................................................................................
Bài thực hành số 1:
MÔ PHỎNG VÀ NẠP CHƯƠNG TRÌNH
NỘI DUNG BÁO CÁO
Nội dung 1: Lập trình và nạp chương trình cho Arduino Uno
Yêu cầu 1: Viết chương trình chớp tắt led với thời gian delay 500 ms.
- Nhận xét về kết quả nhận được sau khi nạp chương trình mẫu như sau:
const int led = 13; // Đặt tên chân 13 là "led" void setup() {
pinMode(led, OUTPUT); // Thiết lập chân led là OUTPUT
}
void loop() { digitalWrite(led, HIGH); //
Bật LED delay(500); // Giữ sáng
500ms giây
digitalWrite(led, LOW); // Tắt LED
delay(500); // Giữ tắt 500ms giây
}
-LED trên bo mạch Arduino Uno (chân 13) sẽ chớp tắt liên tục, với chu kỳ sáng trong 500 ms
tắt trong 500 ms. Tổng chu kỳ là 1 giây (1000 ms), LED nhấp nháy với tần suất khoảng 1Hz.
Chương trình đã hoạt động đúng nếu bạn thấy LED cứ 1 giây chớp tắt 1 lần đều đặn.
Chương trình thay đổi thời gian đáp ứng đóng 1 giây, ngắt 2 giây của led:
const int led = 13; // Đặt tên chân 13 là "led"
void setup() {
pinMode(led, OUTPUT); // Thiết lập chân 13 là OUTPUT
}
void loop() {
lOMoARcPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 01
digitalWrite(led, HIGH); // Bật LED
delay(1000); // Giữ sáng 1 giây (1000 ms)
digitalWrite(led, LOW); // Tắt LED
delay(2000); // Giữ tắt 2 giây (2000 ms)
}
-LED trên chân 13 sẽ sáng trong 1 giây, tắt trong 2 giây ,lặp lại liên tục (chu kỳ 3 giây).
Tốc độ nhấp nháy giảm so với ví dụ ban đầu, giúp dễ quan sát hơn.
- Chương trình để 4 led đầu và 4 led sau sáng tắt đối nghịch
nhau: void setup() { pinMode(2, OUTPUT); //Cấu hình chân số 2
là OUTPUT pinMode(3, OUTPUT); //Cấu hình chân số 3 là
OUTPUT pinMode(4, OUTPUT); //Cấu hình chân số 4 là
OUTPUT pinMode(5, OUTPUT); //Cấu hình chân số 5 là
OUTPUT pinMode(6, OUTPUT); //Cấu hình chân số 6 là
OUTPUT pinMode(7, OUTPUT); //Cấu hình chân số 7 là
OUTPUT pinMode(8, OUTPUT); //Cấu hình chân số 8 là
OUTPUT pinMode(9, OUTPUT); //Cấu hình chân số 9 là
OUTPUT
}
void loop() { digitalWrite(2, HIGH); //Bật đèn led chân
số 2 delay(500); //Thời gian trễ 500ms
delay(500);digitalWrite(3, HIGH); //Bật đèn led chân số
3
delay(500);digitalWrite(4, HIGH); //Bật đèn led chân số 4
delay(500);digitalWrite(5, HIGH); //Bật đèn led chân số 5
delay(500);digitalWrite(6, HIGH); //Bật đèn led chân số 6
delay(500);digitalWrite(7, HIGH); //Bật đèn led chân số 7
delay(500);digitalWrite(8, HIGH); //Bật đèn led chân số 8
delay(500);digitalWrite(9, HIGH); //Bật đèn led chân số 9
delay(500);digitalWrite(9, LOW); //Tắt đèn led chân số 9
lOMoARcPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 01
delay(500);digitalWrite(8, LOW); //Tắt đèn led chân số 8
delay(500); digitalWrite(7, LOW); //Tắt đèn led chân số 7
delay(500);digitalWrite(6, LOW); //Tắt đèn led chân số 6
delay(500);digitalWrite(5, LOW); //Tắt đèn led chân số 5
delay(500);digitalWrite(4, LOW); //Tắt đèn led chân số 4
delay(500);digitalWrite(3, LOW); //Tắt đèn led chân số 3
delay(500);digitalWrite(2, LOW); //Tắt đèn led chân số 2
}
-Sinh viên nhập chương trình mẫu thứ 2 vào Arduino IDE kiểm tra hoạt động và cho
nhận xét với code đã nhập ở tiểu mục 2.
byte led[ ] = {2,3,4,5,6,7,8,9}; // Mảng lưu vị trí các chân Digital mà
// các đèn LED sử dụng theo thứ tự từ 1->8 byte TongLed; // Khai báo
biến TongLed cho việc lưu tổng số chân LED
void setup() {
TongLed = sizeof(led); // Kiểm tra độ dài của mảng led for (int
i = 0; i < TongLed; i++) { pinMode(led[i], OUTPUT); // Cấu
hình các chân led là OUTPUT digitalWrite(led[i], LOW); // Mặc
định các đèn LED sẽ tắt }
}
void loop() {
/* Bật lần lượt các đèn LED */ for (int i =
0; i < TongLed; i++) { digitalWrite(led[i],
HIGH); // Bật đèn led
delay(500); // Thời gian trễ giữa các lần là 500ms
}
/* Tắt lần lượt các đèn LED */ for (int i =
0; i < TongLed; i += 1) {
digitalWrite(led[i], LOW); // Tắt đèn led
delay(500); // Thời gian trễ giữa các lần là 500ms
}
}
THỰC HÀNH MỞ RỘNG
Bài 1: Chương trình lập trình điều khiển 8 led sáng tắt theo kiểu ngẫu nhiên như
sau: byte led[] = {2, 3, 4, 5, 6, 7, 8, 9}; // Mảng chứa các chân LED const byte
TongLed = sizeof(led) / sizeof(led[0]); // Tính tổng số LED
void setup() { randomSeed(analogRead(0)); // Tạo seed cho hàm random, dựa
vào nhiễu analog for (int i = 0; i < TongLed; i++) { pinMode(led[i],
lOMoARcPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 01
OUTPUT); // Cấu hình các chân là OUTPUT digitalWrite(led[i], LOW);
// Tắt tất cả LED ban đầu }
}
void loop() { int soLed = random(1, 9); // Số LED sẽ sáng ngẫu
nhiên (1 đến 8)
// Tắt tất cả LED trước khi bật lại ngẫu
nhiên for (int i = 0; i < TongLed; i++) {
digitalWrite(led[i], LOW); }
// Bật ngẫu nhiên một số LED for (int i = 0; i < soLed; i++) { int viTri =
random(0, TongLed); // Chọn ngẫu nhiên một chân trong mảng
digitalWrite(led[viTri], HIGH); // Bật LED tại vị trí đó
}
delay(500); // Giữ trạng thái trong 500ms
}
Bài 2: Chương trình điều khiển độ sáng của led sáng lên dần và tắt dần theo thời gian. int
ledPin = 9; // Chân nối với LED (chân PWM)
void setup() { pinMode(ledPin, OUTPUT); // Cấu hình chân
LED là OUTPUT
}
void loop() { // Sáng dần for (int doSang = 0; doSang <= 255;
doSang++) { analogWrite(ledPin, doSang); // Gửi giá trị PWM
để tăng độ sáng delay(10); // Độ trễ để thấy sự thay đổi dần }
// Tắt dần for (int doSang = 255; doSang >= 0;
doSang--) { analogWrite(ledPin, doSang); // Giảm
độ sáng dần delay(10); // Giữ hiệu ứng mượt
lOMoARcPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 01
}
}
Bài 3: chương trình lập trình điều khiển 8 led sáng tắt luân phiên theo kiểu led sao băng như
sau:
byte led[] = {2, 3, 4, 5, 6, 7, 8, 9}; // Mảng chân LED
const byte TongLed = sizeof(led) / sizeof(led[0]); // Số lượng LED
void setup() { for (int i = 0; i < TongLed; i++) { pinMode(led[i], OUTPUT);
// Cấu hình các chân LED là OUTPUT digitalWrite(led[i], LOW); //
Tắt LED ban đầu }
}
void loop() {
// Di chuyển từ trái sang phải
for (int i = 0; i < TongLed; i++) {
batTatLed(i); }
// Di chuyển từ phải sang trái for (int i = TongLed - 2; i > 0; i--)
{ // Tránh lặp LED đầu và cuối batTatLed(i);
}
}
void batTatLed(int viTri) { digitalWrite(led[viTri],
HIGH); // Bật LED tại vị trí delay(100);
// Dừng 100ms digitalWrite(led[viTri], LOW); //
Tắt LED đó đi
}
lOMoARcPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 02
Bài thực hành số 2:
LẬP TRÌNH PHƯƠNG THỨC GIAO TIẾP UART, I2C, SPI
NỘI DUNG BÁO CÁO
Nội dung 1: Lập trình giao tiếp UART với máy tính
Yêu cầu 1: Viết chương trình gởi dữ liệu từ Arduino lên máy tính hiển thị kết quả gởi thông
qua cửa sổ Arduino IDE.
- Nhận xét về kết quả hoạt động của chương trình mẫu:
void setup() {
Serial.begin(9600); // Khởi tạo giao tiếp Serial ở tốc độ 9600 baud
}
void loop() {
int giaTri = analogRead(A0); // Đọc giá trị điện áp tại chân analog A0
Serial.print("Gia tri cam bien: ");
Serial.println(giaTri); // Gửi giá trị đọc được lên Serial Monitor
delay(1000); // Gửi mỗi 1 giây
}
-Hoạt động ổn định nếu chọn đúng baud rate (9600) trong Serial Monitor. ràng, dễ đọc,
mỗi dòng là một chu kỳ đọc dữ liệu. Mỗi giây một lần, dễ quan sát – có thể điều chỉnh nhanh
hơn nếu cần. Có thể dùng để giám sát cảm biến, gỡ lỗi chương trình.
- Chương trình hiển thị thông tin sinh viên (Họ và tên, MSSV, lớp, khoa) in lên
màn hìn Serial monitor void setup() {
Serial.begin(9600); // Khởi động giao tiếp Serial ở tốc độ 9600 baud
delay(1000); // Đợi 1 giây cho Serial ổn định
// In thông tin sinh viên lên Serial Monitor
Serial.println("Ho va ten: PHAM HO DANG KHOA");
Serial.println("MSSV : CNDD2211066");
Serial.println("Lop : CNDD2211");
Serial.println("Khoa : Dien - Dien Tu");
Yêu cầu 2: Viết chương trình gởi dữ liệu từ Arduino lên máy tính hiển thị kết quả gởi thông
qua cửa sổ Arduino IDE dưới dạng text, số thập phân, số thập lục phân, số bát phân, số nhị
phân.
- Ghi nhận lại kết quả sau 2 vòng chương trình chính như sau:
int giaTri = 123; // Một giá trị ví dụ
void setup() {
lOMoARcPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 02
Serial.begin(9600); // Khởi động Serial
delay(1000); // Đợi Serial ổn định
Serial.println("GIA TRI");
}
void loop() {
// In ra các định dạng khác nhau
Serial.print("Text (chuoi): ");
Serial.println("Gia tri = 123");
Serial.print("Thap phan (DEC): ");
Serial.println(giaTri, DEC);
Serial.print("Thap luc phan (HEX): ");
Serial.println(giaTri, HEX);
Serial.print("Bat phan (OCT): ");
Serial.println(giaTri, OCT);
Serial.print("Nhi phan (BIN): ");
Serial.println(giaTri, BIN);
delay(2000); // Chờ 2 giây rồi lặp lại
}
- Thập phân (DEC): 123
- Thập lục phân (HEX): 7B- Bát phân (OCT): 173
- Nhị phân (BIN): 1111011
Yêu cầu 3: Viết chương trình đọc số gởi từ máy tính xuống Arduino và điều chỉnh thời gian
nhấp nháy tương ứng với số vừa nhập.
int ledPin = 13; int blinkDelay = 500; // Giá
trị mặc định (ms)
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
Serial.println("Nhap mot so (don vi ms) de dieu chinh toc do nhap nhay LED:");
}
lOMoARcPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 02
void loop() {
// Nếu có dữ liệu gửi từ Serial (máy tính)
if (Serial.available() > 0) {
String input = Serial.readStringUntil('\n'); // Đọc đến khi gặp newline
int newDelay = input.toInt(); // Chuyển chuỗi sang số nguyên
// Kiểm tra hợp lệ (số dương)
if (newDelay > 0) {
blinkDelay = newDelay;
Serial.print("Thoi gian nhap nhay moi: ");
Serial.print(blinkDelay);
Serial.println(" ms");
} else {
Serial.println("Gia tri khong hop le. Nhap mot so > 0.");
}
}
// Nhấp nháy LED
digitalWrite(ledPin, HIGH);
delay(blinkDelay);
digitalWrite(ledPin, LOW);
delay(blinkDelay); }
- Nhập số ngẫu nhiên vào kiểm chứng kết quả nhấp nháy trên led tại Pin13, ghi nhận
lại kết quả thu được như sau:
Số nhập vào:
-1000 tương đương 1000 ms LED bật 1 giây, tắt 1 giây (chậm)
-200 tương đương 200 ms LED bật 0.2s, tắt 0.2s (nhanh hơn)
-50 tương đương 50 ms LED nhấp nháy rất nhanh (gần như chớp liên tục) -
Nhập -20 Serial hiển thị “Gia tri khong hop le. Nhap so > 0”.
-Nhập abc Không hợp lệ Tự động chuyển thành 0, báo lỗi như trên
-0 Không hợp lệ Không thay đổi tốc độ
-Chương trình nhận dữ liệu truyền nối tiếp từ máy tính, sao cho số lần nhấp nháy led
tương ứng với số liệu được nhập vào từ máy tính, nếu nhập số 0 thì đèn luôn tắt.
int ledPin = 13; int
blinkCount = 0;
lOMoARcPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 02
void setup() {
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW); // Đảm bảo đèn tắt khi bắt đầu
Serial.begin(9600);
Serial.println("Nhap so lan nhap nhay LED (0 de tat):");
}
void loop() {
if (Serial.available() > 0) {
String input = Serial.readStringUntil('\n');
blinkCount = input.toInt();
if (blinkCount > 0) {
Serial.print("LED se nhap nhay ");
Serial.print(blinkCount);
Serial.println(" lan.");
for (int i = 0; i < blinkCount; i++) {
digitalWrite(ledPin, HIGH);
delay(300); // Bật 300ms
digitalWrite(ledPin, LOW);
delay(300); // Tắt 300ms
}
Serial.println("Hoan thanh. Nhap so moi:");
} else {
digitalWrite(ledPin, LOW); // Tắt đèn nếu nhập 0 hoặc không hợp lệ
Serial.println("LED da tat. Nhap so moi:");
}
}
}
Nội dung 2: Lập trình giao tiếp qua I2C
Yêu cầu 4: Viết chương trình hiển thị LCD 16x2 qua giao tiếp I2C.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // 0x27: địa chỉ I2C; loại LCD 16x2
char Welcome_text[] = "Welcome CTUET"; char
Xin_chao_text[] = "Xin chao cac SV CTUT!";
void setup()
{
lcd.init();
lOMoARcPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 02
lcd.backlight();
lcd.print("Welcome CTUET");
lcd.setCursor(0, 1);
lcd.print("Xin chao cac ban!");
for (int i = 0; i < 3; i++) {
lcd.noDisplay(); // Tắt màn hình và không làm mất ký tự trên
LCD delay(500); // Chờ 0.5 giây lcd.display(); // Hiển thị
màn hình trở lại delay(500); // Chờ 0.5 giây
}
lcd.clear();
}
void loop()
{
lcd.setCursor(0, 0); // Đưa con trỏ về vị trí (0,0)
// In ra giá trị từ chuỗi 1
for (int position_char = 0; position_char < 12; position_char++) {
lcd.print(Welcome_text[position_char]);
delay(100);
}
lcd.setCursor(16, 1); // Đặt con trỏ tới vị trí (16,1)
lcd.autoscroll(); // Cấu hình hiển thị tự cuộn chữ
// In ra giá trị từ chuỗi 2
for (int position_char = 0; position_char < 21; position_char++)
{ lcd.print(Xin_chao_text[position_char]); delay(300);
}
lcd.noAutoscroll(); // Tắt chức năng tự động cuộn
delay(300);
lcd.clear(); // Xóa màn hình cho vòng lặp kế tiếp
}
- Ghi nhận kết quả thu được từ chương trình mẫu:
Kết quả quan sát trên LCD:
LCD hiện:
Welcome CTUET
Xin chao cac ban!
(Nháy 3 lần)
Sau đó: Welcome CTUET hiện từng ký tự (hiệu ứng đánh máy). Dòng 2 cuộn từ phải
sang trái: Xin chao cac SV CTUT! Màn hình xóa và quá trình lặp lại.
lOMoARcPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 02
- Lập trình chương trình hiển thị thông tin sinh viên gồm Họ và tên trên dòng
trên, mã số sinh viên và lớp luân phiên thay đổi ở dòng dưới.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Địa chỉ I2C và loại LCD 16x2
// Thông tin sinh viên char hoTen[] =
"Nguyen Van A"; char maSV[] =
"MSSV: 123456789"; char lop[] =
"Lop: DI22T1";
void setup() {
lcd.init();
lcd.backlight();
// Hiển thị họ và tên sinh viên trên dòng
đầu lcd.setCursor(0, 0); lcd.print(hoTen);
}
void loop() {
// Hiển thị mã số sinh viên ở dòng thứ
hai lcd.setCursor(0, 1);
lcd.print(maSV); delay(2000); // Chờ 2
giây
// Xóa dòng thứ hai trước khi thay nội dung
lcd.setCursor(0, 1); lcd.print(" "); // Xóa
dòng bằng khoảng trắng // Hiển thị lớp học ở dòng
thứ hai lcd.setCursor(0, 1); lcd.print(lop);
delay(2000); // Chờ 2 giây
// Xóa dòng để chuẩn bị vòng lặp tiếp theo
lcd.setCursor(0, 1);
lOMoARcPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 02
lcd.print(" ");
}
lOMoARcPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 04
Bài thực hành số 3:
LẬP TRÌNH ĐỌC TÍN HIỆU SỐ, TÍN HIỆU TƯƠNG TỰ
TÍN HIỆU TỪ CÁC CẢM BIẾN
NỘI DUNG BÁO CÁO
Nội dung 1: Đọc tín hiệu số từ nút nhấn
Yêu cầu 1: Viết chương trình đọc nút nhấn, hiển thị kết quả nhấn nút qua led qua Serial
Monitor.
int button = 11; // Nút nhấn được kết nối với chân 11 của Arduino
int led = 2; // Led được kết nối với chân 2 của Arduino
void setup() {
Serial.begin(9600); // Mở cổng Serial ở baudrate 9600
pinMode(button, INPUT); // Khai báo chân 11 ở trạng thái đọc dữ liệu
pinMode(led, OUTPUT); // Khai báo chân 2 nối led là ngõ ra
}
void loop() { int buttonStatus = digitalRead(button); // Đọc trạng
thái button if (buttonStatus == HIGH) { // Nếu mà button bị
nhấn Serial.println("Nut dang duoc nhan"); // Hiển thị lên Serial
Monitor digitalWrite(led, HIGH); // Đèn led sáng
}
else {
digitalWrite(led, LOW); // Ngược lại button không bị nhấn
Serial.println("Nut chua duoc nhan");
}
delay(200);
}
- Xóa lệnh “delay(200);” trong vòng lập “loop”. Nhấn nút và kết quả như
sau:.
Khi nhấn và giữ nút: Dòng "Nut dang duoc nhan" in liên tục và rất nhanh, gây tràn
màn hình, khó đọc.
Khi không nhấn nút: dòng "Nut chua duoc nhan" cũng in liên tục.
- Nhược điểm của phương pháp dùng hàm “delay()” trong trường hợp
này: Phản hồi chậm với thao tác nhấn nút:
-Vì chương trình chỉ kiểm tra trạng thái nút mỗi 200ms, nên nếu bạn nhấn nhanh rồi
nhả ra (dưới 200ms), Arduino có thể bỏ qua và không phát hiện hành động đó.
-Không thể xử lý nhiều tác vụ cùng lúc:
lOMoARcPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 04
-Trong thời gian delay(200), Arduino không làm gì khác được. Nếu bạn cần thêm xử
lý (hiển thị LCD, đọc cảm biến,...) thì chúng sẽ bị treo lại.
-Không phù hợp cho xử lý phức tạp hoặc đa nhiệm:
-Với các ứng dụng cần đo thời gian thực, phản ứng nhanh hoặc kết hợp nhiều thiết bị,
dùng delay() gây giật lag, kém linh hoạt.
- Nhấn nút và giữ, ghi nhận kết quả hiển thị trên led và trên Serial
Monitor như sau:
Giả sử bạn giữ nút liên tục trong 1 giây, Serial Monitor sẽ hiển thị:
Nut dang duoc nhan
Nut dang duoc nhan
Nut dang duoc nhan
Nut dang duoc nhan
Nut dang duoc nhan
(Ứng với khoảng 5 lần in ra mỗi giây, vì delay = 200ms)
LED sẽ sáng liên tục trong thời gian bạn giữ nút.
Khi nhả nút, Serial bắt đầu in "Nut chua duoc nhan" đều đặn, LED tắt.
-Chương trình lập trình đọc nút nhấn, mỗi lần nhấn thì đổi trạng thái, khi nhất giữ trạng thái
không thai đổi (chọn tác động xung cạnh lên hoặc xung cạnh xuống của nút nhấn) như sau:
int buttonPin = 11; // Nút nhấn kết nối chân 11
int ledPin = 2; // LED kết nối chân 2
bool ledState = false; // Trạng thái LED (true = bật, false = tắt)
bool lastButtonState = HIGH; // Trạng thái trước đó của nút
void setup() {
pinMode(buttonPin, INPUT_PULLUP); // Sử dụng điện trở kéo lên nội
bộ pinMode(ledPin, OUTPUT); digitalWrite(ledPin, ledState); // Đặt
trạng thái ban đầu cho LED
Serial.begin(9600);
}
void loop() { bool currentButtonState =
digitalRead(buttonPin);
// Phát hiện xung cạnh xuống: từ HIGH → LOW
if (lastButtonState == HIGH && currentButtonState == LOW) {
lOMoARcPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 04
ledState = !ledState; // Đảo trạng thái LED
digitalWrite(ledPin, ledState);
Serial.print("Trang thai LED: ");
Serial.println(ledState ? "BAT" : "TAT");
}
lastButtonState = currentButtonState;
delay(50); // Chống dội nút (debounce)
}
Yêu cầu 2: Viết chương trình đọc từ bàn phím nút nhấn dạng ma trận và in phím nhấn
lên cổng serial của Arduino IDE và LCD.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// LCD khai báo
LiquidCrystal_I2C lcd(0x27, 16, 2); // Địa chỉ I2C có thể thay đổi tùy module
const int numRows = 4; // Số hàng của keypad const int
numCols = 4; // Số cột của keypad const int debounceTime =
20; // Thời gian chống dội phím (ms)
// Bản đồ ký tự trên keypad
const char keymap[numRows][numCols] = {
{'7', '8', '9', '/'},
{'4', '5', '6', '*'},
{'1', '2', '3', '-'},
{'C', '0', '=', '+'}
};
// Khai báo chân kết nối hàng và cột const int
rowPins[numRows] = {11, 10, 9, 8}; // Hàng 0 đến 3 const int
colPins[numCols] = {7, 6, 5, 4}; // Cột 0 đến 3
void setup() {
lcd.init();
lcd.backlight();
lcd.setCursor(2, 0);
lcd.print("Welcome CTUET");
lcd.setCursor(0, 1);
lcd.print("Xin moi nhan nut!");
delay(1000); lcd.clear();
lOMoARcPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 04
lcd.setCursor(0, 0);
lcd.print("Phim vua bam la:");
Serial.begin(9600);
// Cấu hình chân hàng for (int row = 0;
row < numRows; row++) {
pinMode(rowPins[row], INPUT);
digitalWrite(rowPins[row], HIGH); // bật trở kéo lên
}
// Cấu hình chân cột
for (int col = 0; col < numCols; col++) {
pinMode(colPins[col], OUTPUT);
digitalWrite(colPins[col], HIGH); // không kích hoạt ban đầu
}
}
void loop() { char key = getKey(); //
Hàm quét keypad
if (key != 0) {
Serial.print("Vua nhan phim: ");
Serial.println(key);
lcd.setCursor(6, 1);
lcd.print(" "); // Xóa ký tự cũ
lcd.setCursor(6, 1);
lcd.print(key); // Hiển thị ký tự mới
}
}
char getKey() {
char key = 0;
for (int col = 0; col < numCols; col++) {
digitalWrite(colPins[col], LOW); // Kích hoạt cột hiện tại
for (int row = 0; row < numRows; row++) {
if (digitalRead(rowPins[row]) == LOW) {
delay(debounceTime); // Chống dội
while (digitalRead(rowPins[row]) == LOW); // Chờ thả phím
key = keymap[row][col]; // Gán ký tự tương ứng
}
}
lOMoARcPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 04
digitalWrite(colPins[col], HIGH); // Vô hiệu hóa cột
}
return key; // Trả về ký tự hoặc 0 nếu không có phím nhấn
}
Ghi nhận kết quả khi nhấn nút theo thứ tự từ trái qua phải và từ trên xuống dưới thu
được kết quả như sau:
Nếu nhấn các nút từ trái qua phải, từ trên xuống dưới, bạn sẽ nhận được chuỗi ký tự:
7 8 9 / ; 4 5 6 * ; 1 2 3 - ; C 0 = +
- Hãy viết chương trình đọc password từ bàn phím. Nhận password 13579. Nếu đúng
password thì nhấn phím = trên bàn phím để tắt mở đèn led tại chân 13. Nếu sai thì đèn
nhấp nháy liên tục. Nhấn phím C để nhập lại password.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // LCD 16x2 với địa chỉ I2C
const int numRows = 4; const
int numCols = 4; const int
debounceTime = 20; const int
ledPin = 13;
const char correctPassword[] = "13579"; char
enteredPassword[10]; // Lưu trữ ký tự nhập
byte passwordIndex = 0; bool
passwordAccepted = false; bool ledState =
false;
const char keymap[numRows][numCols] = {
{'7', '8', '9', '/'},
{'4', '5', '6', '*'},
{'1', '2', '3', '-'},
{'C', '0', '=', '+'}
};
const int rowPins[numRows] = {11, 10, 9, 8};
const int colPins[numCols] = {7, 6, 5, 4};
void setup() {
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
lOMoARcPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 04
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Nhap mat
khau:");
lcd.setCursor(0, 1);
Serial.begin(9600);
for (int row = 0; row < numRows; row++) {
pinMode(rowPins[row], INPUT);
digitalWrite(rowPins[row], HIGH);
}
for (int col = 0; col < numCols; col++) {
pinMode(colPins[col], OUTPUT);
digitalWrite(colPins[col], HIGH);
}
}
void loop() { char
key = getKey();
if (key != 0) {
if (key == 'C') {
clearPassword();
}
else if (!passwordAccepted && key != '=' && passwordIndex <
sizeof(enteredPassword) - 1) {
enteredPassword[passwordIndex++] = key;
lcd.print('*'); // Ẩn ký tự nhập
Serial.print("Nhap: ");
Serial.println(key);
if (passwordIndex == strlen(correctPassword)) {
enteredPassword[passwordIndex] = '\0'; // Kết thúc chuỗi
if (strcmp(enteredPassword, correctPassword) == 0) {
passwordAccepted = true; lcd.clear();
lcd.print("Mat khau dung!");
lcd.setCursor(0, 1);
lcd.print("Nhan '=' bat LED");
delay(1000); lcd.clear();
} else { lcd.clear();
lcd.print("Sai mat khau!");
Serial.println("Sai mat khau!");
passwordIndex = 0;
}
lOMoARcPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 04
}
}
else if (passwordAccepted && key == '=') {
ledState = !ledState;
digitalWrite(ledPin, ledState ? HIGH : LOW);
lcd.setCursor(0, 0);
lcd.print(ledState ? "LED dang bat " : "LED dang tat ");
}
}
// Nếu sai mật khẩu, đèn nhấp nháy liên tục
if (!passwordAccepted && passwordIndex == strlen(correctPassword))
{ digitalWrite(ledPin, HIGH); delay(300); digitalWrite(ledPin,
LOW);
delay(300);
}
}
char getKey() {
char key = 0;
for (int col = 0; col < numCols; col++) {
digitalWrite(colPins[col], LOW);
for (int row = 0; row < numRows; row++) {
if (digitalRead(rowPins[row]) == LOW) {
delay(debounceTime);
while (digitalRead(rowPins[row]) == LOW);
key = keymap[row][col];
}
}
digitalWrite(colPins[col], HIGH);
}
return key;
}
void clearPassword() {
passwordIndex = 0;
passwordAccepted = false;
lcd.clear(); lcd.setCursor(0,
0); lcd.print("Nhap mat
khau:"); lcd.setCursor(0, 1);
Serial.println("Nhap lai mat khau");

Preview text:

lOMoAR cPSD| 60776878
TRƯỜNG ĐẠI HỌC KỸ THUẬT - CÔNG NGHỆ CẦN THƠ
KHOA ĐIỆN - ĐIỆN TỬ ----- -----
BÁO CÁO THỰC HÀNH VI ĐIỀU KHIỂN
SINH VIÊN THỰC HIỆN : Nhóm: 1 Học kỳ 2 Năm học: 202 4 -202 5 lOMoAR cPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 01
Xin cam kết số liệu báo cáo, các câu trả lời là do tự cá nhân làm và số liệu ghi nhận được
từ thí nghiệm, không có sao chép của bất kỳ ai. Nếu có sự sao chép bất kì nội dung nào
sẽ nhận điểm 0 (không).

Người cam kết ký và ghi rõ họ tên: ....................................................................................
Bài thực hành số 1:
MÔ PHỎNG VÀ NẠP CHƯƠNG TRÌNH NỘI DUNG BÁO CÁO
Nội dung 1: Lập trình và nạp chương trình cho Arduino Uno
Yêu cầu 1: Viết chương trình chớp tắt led với thời gian delay 500 ms.
- Nhận xét về kết quả nhận được sau khi nạp chương trình mẫu như sau:
const int led = 13; // Đặt tên chân 13 là "led" void setup() {
pinMode(led, OUTPUT); // Thiết lập chân led là OUTPUT }
void loop() { digitalWrite(led, HIGH); //
Bật LED delay(500); // Giữ sáng 500ms giây
digitalWrite(led, LOW); // Tắt LED
delay(500); // Giữ tắt 500ms giây }
-LED trên bo mạch Arduino Uno (chân 13) sẽ chớp tắt liên tục, với chu kỳ sáng trong 500 ms
tắt trong 500 ms. Tổng chu kỳ là 1 giây (1000 ms), LED nhấp nháy với tần suất khoảng 1Hz.
Chương trình đã hoạt động đúng nếu bạn thấy LED cứ 1 giây chớp tắt 1 lần đều đặn.
Chương trình thay đổi thời gian đáp ứng đóng 1 giây, ngắt 2 giây của led:
const int led = 13; // Đặt tên chân 13 là "led" void setup() {
pinMode(led, OUTPUT); // Thiết lập chân 13 là OUTPUT } void loop() { lOMoAR cPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 01
digitalWrite(led, HIGH); // Bật LED
delay(1000); // Giữ sáng 1 giây (1000 ms)
digitalWrite(led, LOW); // Tắt LED
delay(2000); // Giữ tắt 2 giây (2000 ms) }
-LED trên chân 13 sẽ sáng trong 1 giây, tắt trong 2 giây ,lặp lại liên tục (chu kỳ 3 giây).
Tốc độ nhấp nháy giảm so với ví dụ ban đầu, giúp dễ quan sát hơn. -
Chương trình để 4 led đầu và 4 led sau sáng tắt đối nghịch
nhau: void setup() { pinMode(2, OUTPUT); //Cấu hình chân số 2
là OUTPUT pinMode(3, OUTPUT); //Cấu hình chân số 3 là
OUTPUT pinMode(4, OUTPUT); //Cấu hình chân số 4 là
OUTPUT pinMode(5, OUTPUT); //Cấu hình chân số 5 là
OUTPUT pinMode(6, OUTPUT); //Cấu hình chân số 6 là
OUTPUT pinMode(7, OUTPUT); //Cấu hình chân số 7 là
OUTPUT pinMode(8, OUTPUT); //Cấu hình chân số 8 là
OUTPUT pinMode(9, OUTPUT); //Cấu hình chân số 9 là OUTPUT }
void loop() { digitalWrite(2, HIGH); //Bật đèn led chân
số 2 delay(500); //Thời gian trễ 500ms
delay(500);digitalWrite(3, HIGH); //Bật đèn led chân số 3
delay(500);digitalWrite(4, HIGH); //Bật đèn led chân số 4
delay(500);digitalWrite(5, HIGH); //Bật đèn led chân số 5
delay(500);digitalWrite(6, HIGH); //Bật đèn led chân số 6
delay(500);digitalWrite(7, HIGH); //Bật đèn led chân số 7
delay(500);digitalWrite(8, HIGH); //Bật đèn led chân số 8
delay(500);digitalWrite(9, HIGH); //Bật đèn led chân số 9
delay(500);digitalWrite(9, LOW); //Tắt đèn led chân số 9 lOMoAR cPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 01
delay(500);digitalWrite(8, LOW); //Tắt đèn led chân số 8
delay(500); digitalWrite(7, LOW); //Tắt đèn led chân số 7
delay(500);digitalWrite(6, LOW); //Tắt đèn led chân số 6
delay(500);digitalWrite(5, LOW); //Tắt đèn led chân số 5
delay(500);digitalWrite(4, LOW); //Tắt đèn led chân số 4
delay(500);digitalWrite(3, LOW); //Tắt đèn led chân số 3
delay(500);digitalWrite(2, LOW); //Tắt đèn led chân số 2 }
-Sinh viên nhập chương trình mẫu thứ 2 vào Arduino IDE kiểm tra hoạt động và cho
nhận xét với code đã nhập ở tiểu mục 2.
byte led[ ] = {2,3,4,5,6,7,8,9}; // Mảng lưu vị trí các chân Digital mà
// các đèn LED sử dụng theo thứ tự từ 1->8 byte TongLed; // Khai báo
biến TongLed cho việc lưu tổng số chân LED void setup() {
TongLed = sizeof(led); // Kiểm tra độ dài của mảng led for (int
i = 0; i < TongLed; i++) { pinMode(led[i], OUTPUT); // Cấu
hình các chân led là OUTPUT digitalWrite(led[i], LOW); // Mặc
định các đèn LED sẽ tắt } } void loop() {
/* Bật lần lượt các đèn LED */ for (int i =
0; i < TongLed; i++) { digitalWrite(led[i], HIGH); // Bật đèn led
delay(500); // Thời gian trễ giữa các lần là 500ms }
/* Tắt lần lượt các đèn LED */ for (int i = 0; i < TongLed; i += 1) {
digitalWrite(led[i], LOW); // Tắt đèn led
delay(500); // Thời gian trễ giữa các lần là 500ms } }
THỰC HÀNH MỞ RỘNG
Bài 1: Chương trình lập trình điều khiển 8 led sáng tắt theo kiểu ngẫu nhiên như
sau: byte led[] = {2, 3, 4, 5, 6, 7, 8, 9}; // Mảng chứa các chân LED const byte
TongLed = sizeof(led) / sizeof(led[0]); // Tính tổng số LED
void setup() { randomSeed(analogRead(0)); // Tạo seed cho hàm random, dựa
vào nhiễu analog for (int i = 0; i < TongLed; i++) { pinMode(led[i], lOMoAR cPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 01
OUTPUT); // Cấu hình các chân là OUTPUT digitalWrite(led[i], LOW);
// Tắt tất cả LED ban đầu } }
void loop() { int soLed = random(1, 9); // Số LED sẽ sáng ngẫu nhiên (1 đến 8)
// Tắt tất cả LED trước khi bật lại ngẫu
nhiên for (int i = 0; i < TongLed; i++) { digitalWrite(led[i], LOW); }
// Bật ngẫu nhiên một số LED for (int i = 0; i < soLed; i++) { int viTri =
random(0, TongLed); // Chọn ngẫu nhiên một chân trong mảng
digitalWrite(led[viTri], HIGH); // Bật LED tại vị trí đó }
delay(500); // Giữ trạng thái trong 500ms }
Bài 2: Chương trình điều khiển độ sáng của led sáng lên dần và tắt dần theo thời gian. int
ledPin = 9; // Chân nối với LED (chân PWM)
void setup() { pinMode(ledPin, OUTPUT); // Cấu hình chân LED là OUTPUT }
void loop() { // Sáng dần for (int doSang = 0; doSang <= 255;
doSang++) { analogWrite(ledPin, doSang); // Gửi giá trị PWM
để tăng độ sáng delay(10); // Độ trễ để thấy sự thay đổi dần }
// Tắt dần for (int doSang = 255; doSang >= 0;
doSang--) { analogWrite(ledPin, doSang); // Giảm
độ sáng dần delay(10); // Giữ hiệu ứng mượt lOMoAR cPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 01 } }
Bài 3: chương trình lập trình điều khiển 8 led sáng tắt luân phiên theo kiểu led sao băng như sau:
byte led[] = {2, 3, 4, 5, 6, 7, 8, 9}; // Mảng chân LED
const byte TongLed = sizeof(led) / sizeof(led[0]); // Số lượng LED
void setup() { for (int i = 0; i < TongLed; i++) { pinMode(led[i], OUTPUT);
// Cấu hình các chân LED là OUTPUT digitalWrite(led[i], LOW); // Tắt LED ban đầu } } void loop() {
// Di chuyển từ trái sang phải
for (int i = 0; i < TongLed; i++) { batTatLed(i); }
// Di chuyển từ phải sang trái for (int i = TongLed - 2; i > 0; i--)
{ // Tránh lặp LED đầu và cuối batTatLed(i); } }
void batTatLed(int viTri) { digitalWrite(led[viTri],
HIGH); // Bật LED tại vị trí delay(100);
// Dừng 100ms digitalWrite(led[viTri], LOW); // Tắt LED đó đi } lOMoAR cPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 02
Bài thực hành số 2:
LẬP TRÌNH PHƯƠNG THỨC GIAO TIẾP UART, I2C, SPI NỘI DUNG BÁO CÁO
Nội dung 1: Lập trình giao tiếp UART với máy tính
Yêu cầu 1: Viết chương trình gởi dữ liệu từ Arduino lên máy tính và hiển thị kết quả gởi thông
qua cửa sổ Arduino IDE.
- Nhận xét về kết quả hoạt động của chương trình mẫu: void setup() {
Serial.begin(9600); // Khởi tạo giao tiếp Serial ở tốc độ 9600 baud } void loop() {
int giaTri = analogRead(A0); // Đọc giá trị điện áp tại chân analog A0
Serial.print("Gia tri cam bien: ");
Serial.println(giaTri); // Gửi giá trị đọc được lên Serial Monitor
delay(1000); // Gửi mỗi 1 giây }
-Hoạt động ổn định nếu chọn đúng baud rate (9600) trong Serial Monitor. Rõ ràng, dễ đọc,
mỗi dòng là một chu kỳ đọc dữ liệu. Mỗi giây một lần, dễ quan sát – có thể điều chỉnh nhanh
hơn nếu cần. Có thể dùng để giám sát cảm biến, gỡ lỗi chương trình.
- Chương trình hiển thị thông tin sinh viên (Họ và tên, MSSV, lớp, khoa) in lên
màn hìn Serial monitor void setup() {
Serial.begin(9600); // Khởi động giao tiếp Serial ở tốc độ 9600 baud
delay(1000); // Đợi 1 giây cho Serial ổn định
// In thông tin sinh viên lên Serial Monitor
Serial.println("Ho va ten: PHAM HO DANG KHOA");
Serial.println("MSSV : CNDD2211066");
Serial.println("Lop : CNDD2211");
Serial.println("Khoa : Dien - Dien Tu");
Yêu cầu 2: Viết chương trình gởi dữ liệu từ Arduino lên máy tính và hiển thị kết quả gởi thông
qua cửa sổ Arduino IDE dưới dạng text, số thập phân, số thập lục phân, số bát phân, số nhị phân.
- Ghi nhận lại kết quả sau 2 vòng chương trình chính như sau:
int giaTri = 123; // Một giá trị ví dụ void setup() { lOMoAR cPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 02
Serial.begin(9600); // Khởi động Serial
delay(1000); // Đợi Serial ổn định Serial.println("GIA TRI"); } void loop() {
// In ra các định dạng khác nhau
Serial.print("Text (chuoi): ");
Serial.println("Gia tri = 123");
Serial.print("Thap phan (DEC): "); Serial.println(giaTri, DEC);
Serial.print("Thap luc phan (HEX): "); Serial.println(giaTri, HEX);
Serial.print("Bat phan (OCT): "); Serial.println(giaTri, OCT);
Serial.print("Nhi phan (BIN): "); Serial.println(giaTri, BIN);
delay(2000); // Chờ 2 giây rồi lặp lại } - Thập phân (DEC): 123 -
Thập lục phân (HEX): 7B- Bát phân (OCT): 173 - Nhị phân (BIN): 1111011
Yêu cầu 3: Viết chương trình đọc số gởi từ máy tính xuống Arduino và điều chỉnh thời gian
nhấp nháy tương ứng với số vừa nhập.
int ledPin = 13; int blinkDelay = 500; // Giá trị mặc định (ms) void setup() { pinMode(ledPin, OUTPUT); Serial.begin(9600);
Serial.println("Nhap mot so (don vi ms) de dieu chinh toc do nhap nhay LED:"); } lOMoAR cPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 02 void loop() {
// Nếu có dữ liệu gửi từ Serial (máy tính)
if (Serial.available() > 0) {
String input = Serial.readStringUntil('\n'); // Đọc đến khi gặp newline
int newDelay = input.toInt(); // Chuyển chuỗi sang số nguyên
// Kiểm tra hợp lệ (số dương) if (newDelay > 0) { blinkDelay = newDelay;
Serial.print("Thoi gian nhap nhay moi: "); Serial.print(blinkDelay); Serial.println(" ms"); } else {
Serial.println("Gia tri khong hop le. Nhap mot so > 0."); } } // Nhấp nháy LED digitalWrite(ledPin, HIGH); delay(blinkDelay); digitalWrite(ledPin, LOW); delay(blinkDelay); }
- Nhập số ngẫu nhiên vào kiểm chứng kết quả nhấp nháy trên led tại Pin13, ghi nhận
lại kết quả thu được như sau: Số nhập vào:
-1000 tương đương 1000 ms LED bật 1 giây, tắt 1 giây (chậm)
-200 tương đương 200 ms LED bật 0.2s, tắt 0.2s (nhanh hơn)
-50 tương đương 50 ms LED nhấp nháy rất nhanh (gần như chớp liên tục) -
Nhập -20 Serial hiển thị “Gia tri khong hop le. Nhap so > 0”.
-Nhập abc Không hợp lệ Tự động chuyển thành 0, báo lỗi như trên
-0 Không hợp lệ Không thay đổi tốc độ
-Chương trình nhận dữ liệu truyền nối tiếp từ máy tính, sao cho số lần nhấp nháy led
tương ứng với số liệu được nhập vào từ máy tính, nếu nhập số 0 thì đèn luôn tắt. int ledPin = 13; int blinkCount = 0; lOMoAR cPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 02 void setup() { pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW); // Đảm bảo đèn tắt khi bắt đầu Serial.begin(9600);
Serial.println("Nhap so lan nhap nhay LED (0 de tat):"); } void loop() {
if (Serial.available() > 0) {
String input = Serial.readStringUntil('\n'); blinkCount = input.toInt(); if (blinkCount > 0) {
Serial.print("LED se nhap nhay "); Serial.print(blinkCount); Serial.println(" lan.");
for (int i = 0; i < blinkCount; i++) { digitalWrite(ledPin, HIGH); delay(300); // Bật 300ms digitalWrite(ledPin, LOW); delay(300); // Tắt 300ms }
Serial.println("Hoan thanh. Nhap so moi:"); } else {
digitalWrite(ledPin, LOW); // Tắt đèn nếu nhập 0 hoặc không hợp lệ
Serial.println("LED da tat. Nhap so moi:"); } } } 
Nội dung 2: Lập trình giao tiếp qua I2C
Yêu cầu 4: Viết chương trình hiển thị LCD 16x2 qua giao tiếp I2C. #include #include
LiquidCrystal_I2C lcd(0x27, 16, 2); // 0x27: địa chỉ I2C; loại LCD 16x2
char Welcome_text[] = "Welcome CTUET"; char
Xin_chao_text[] = "Xin chao cac SV CTUT!"; void setup() { lcd.init(); lOMoAR cPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 02 lcd.backlight(); lcd.print("Welcome CTUET"); lcd.setCursor(0, 1);
lcd.print("Xin chao cac ban!");
for (int i = 0; i < 3; i++) {
lcd.noDisplay(); // Tắt màn hình và không làm mất ký tự trên
LCD delay(500); // Chờ 0.5 giây lcd.display(); // Hiển thị
màn hình trở lại delay(500); // Chờ 0.5 giây } lcd.clear(); } void loop() {
lcd.setCursor(0, 0); // Đưa con trỏ về vị trí (0,0)
// In ra giá trị từ chuỗi 1
for (int position_char = 0; position_char < 12; position_char++) {
lcd.print(Welcome_text[position_char]); delay(100); }
lcd.setCursor(16, 1); // Đặt con trỏ tới vị trí (16,1)
lcd.autoscroll(); // Cấu hình hiển thị tự cuộn chữ
// In ra giá trị từ chuỗi 2
for (int position_char = 0; position_char < 21; position_char++)
{ lcd.print(Xin_chao_text[position_char]); delay(300); }
lcd.noAutoscroll(); // Tắt chức năng tự động cuộn delay(300);
lcd.clear(); // Xóa màn hình cho vòng lặp kế tiếp }
- Ghi nhận kết quả thu được từ chương trình mẫu:
Kết quả quan sát trên LCD: LCD hiện: Welcome CTUET Xin chao cac ban! (Nháy 3 lần)
Sau đó: Welcome CTUET hiện từng ký tự (hiệu ứng đánh máy). Dòng 2 cuộn từ phải
sang trái: Xin chao cac SV CTUT! Màn hình xóa và quá trình lặp lại. lOMoAR cPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 02
- Lập trình chương trình hiển thị thông tin sinh viên gồm Họ và tên trên dòng
trên, mã số sinh viên và lớp luân phiên thay đổi ở dòng dưới. #include #include
LiquidCrystal_I2C lcd(0x27, 16, 2); // Địa chỉ I2C và loại LCD 16x2
// Thông tin sinh viên char hoTen[] = "Nguyen Van A"; char maSV[] =
"MSSV: 123456789"; char lop[] = "Lop: DI22T1"; void setup() { lcd.init(); lcd.backlight();
// Hiển thị họ và tên sinh viên trên dòng
đầu lcd.setCursor(0, 0); lcd.print(hoTen); } void loop() {
// Hiển thị mã số sinh viên ở dòng thứ hai lcd.setCursor(0, 1);
lcd.print(maSV); delay(2000); // Chờ 2 giây
// Xóa dòng thứ hai trước khi thay nội dung
lcd.setCursor(0, 1); lcd.print(" "); // Xóa
dòng bằng khoảng trắng // Hiển thị lớp học ở dòng
thứ hai lcd.setCursor(0, 1); lcd.print(lop); delay(2000); // Chờ 2 giây
// Xóa dòng để chuẩn bị vòng lặp tiếp theo lcd.setCursor(0, 1); lOMoAR cPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 02 lcd.print(" "); } lOMoAR cPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 04
Bài thực hành số 3:
LẬP TRÌNH ĐỌC TÍN HIỆU SỐ, TÍN HIỆU TƯƠNG TỰ VÀ
TÍN HIỆU TỪ CÁC CẢM BIẾN NỘI DUNG BÁO CÁO
Nội dung 1: Đọc tín hiệu số từ nút nhấn
Yêu cầu 1: Viết chương trình đọc nút nhấn, hiển thị kết quả nhấn nút qua led và qua Serial Monitor.
int button = 11; // Nút nhấn được kết nối với chân 11 của Arduino
int led = 2; // Led được kết nối với chân 2 của Arduino void setup() {
Serial.begin(9600); // Mở cổng Serial ở baudrate 9600
pinMode(button, INPUT); // Khai báo chân 11 ở trạng thái đọc dữ liệu
pinMode(led, OUTPUT); // Khai báo chân 2 nối led là ngõ ra }
void loop() { int buttonStatus = digitalRead(button); // Đọc trạng
thái button if (buttonStatus == HIGH) { // Nếu mà button bị
nhấn Serial.println("Nut dang duoc nhan"); // Hiển thị lên Serial
Monitor digitalWrite(led, HIGH); // Đèn led sáng } else {
digitalWrite(led, LOW); // Ngược lại button không bị nhấn
Serial.println("Nut chua duoc nhan"); } delay(200); } -
Xóa lệnh “delay(200);” trong vòng lập “loop”. Nhấn nút và kết quả như sau:.
Khi nhấn và giữ nút: Dòng "Nut dang duoc nhan" in liên tục và rất nhanh, gây tràn màn hình, khó đọc.
Khi không nhấn nút: dòng "Nut chua duoc nhan" cũng in liên tục. -
Nhược điểm của phương pháp dùng hàm “delay()” trong trường hợp
này: Phản hồi chậm với thao tác nhấn nút:
-Vì chương trình chỉ kiểm tra trạng thái nút mỗi 200ms, nên nếu bạn nhấn nhanh rồi
nhả ra (dưới 200ms), Arduino có thể bỏ qua và không phát hiện hành động đó.
-Không thể xử lý nhiều tác vụ cùng lúc: lOMoAR cPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 04
-Trong thời gian delay(200), Arduino không làm gì khác được. Nếu bạn cần thêm xử
lý (hiển thị LCD, đọc cảm biến,...) thì chúng sẽ bị treo lại.
-Không phù hợp cho xử lý phức tạp hoặc đa nhiệm:
-Với các ứng dụng cần đo thời gian thực, phản ứng nhanh hoặc kết hợp nhiều thiết bị,
dùng delay() gây giật lag, kém linh hoạt. -
Nhấn nút và giữ, ghi nhận kết quả hiển thị trên led và trên Serial Monitor như sau:
Giả sử bạn giữ nút liên tục trong 1 giây, Serial Monitor sẽ hiển thị: Nut dang duoc nhan Nut dang duoc nhan Nut dang duoc nhan Nut dang duoc nhan Nut dang duoc nhan
(Ứng với khoảng 5 lần in ra mỗi giây, vì delay = 200ms)
LED sẽ sáng liên tục trong thời gian bạn giữ nút.
Khi nhả nút, Serial bắt đầu in "Nut chua duoc nhan" đều đặn, LED tắt.
-Chương trình lập trình đọc nút nhấn, mỗi lần nhấn thì đổi trạng thái, khi nhất giữ trạng thái
không thai đổi (chọn tác động xung cạnh lên hoặc xung cạnh xuống của nút nhấn) như sau:
int buttonPin = 11; // Nút nhấn kết nối chân 11
int ledPin = 2; // LED kết nối chân 2
bool ledState = false; // Trạng thái LED (true = bật, false = tắt)
bool lastButtonState = HIGH; // Trạng thái trước đó của nút void setup() {
pinMode(buttonPin, INPUT_PULLUP); // Sử dụng điện trở kéo lên nội
bộ pinMode(ledPin, OUTPUT); digitalWrite(ledPin, ledState); // Đặt
trạng thái ban đầu cho LED Serial.begin(9600); }
void loop() { bool currentButtonState = digitalRead(buttonPin);
// Phát hiện xung cạnh xuống: từ HIGH → LOW
if (lastButtonState == HIGH && currentButtonState == LOW) { lOMoAR cPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 04
ledState = !ledState; // Đảo trạng thái LED
digitalWrite(ledPin, ledState);
Serial.print("Trang thai LED: ");
Serial.println(ledState ? "BAT" : "TAT"); }
lastButtonState = currentButtonState;
delay(50); // Chống dội nút (debounce) }
Yêu cầu 2: Viết chương trình đọc từ bàn phím nút nhấn dạng ma trận và in phím nhấn
lên cổng serial của Arduino IDE và LCD.
#include #include // LCD khai báo
LiquidCrystal_I2C lcd(0x27, 16, 2); // Địa chỉ I2C có thể thay đổi tùy module
const int numRows = 4; // Số hàng của keypad const int
numCols = 4; // Số cột của keypad const int debounceTime =
20; // Thời gian chống dội phím (ms)
// Bản đồ ký tự trên keypad
const char keymap[numRows][numCols] = { {'7', '8', '9', '/'}, {'4', '5', '6', '*'}, {'1', '2', '3', '-'}, {'C', '0', '=', '+'} };
// Khai báo chân kết nối hàng và cột const int
rowPins[numRows] = {11, 10, 9, 8}; // Hàng 0 đến 3 const int
colPins[numCols] = {7, 6, 5, 4}; // Cột 0 đến 3 void setup() { lcd.init(); lcd.backlight(); lcd.setCursor(2, 0); lcd.print("Welcome CTUET"); lcd.setCursor(0, 1);
lcd.print("Xin moi nhan nut!"); delay(1000); lcd.clear(); lOMoAR cPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 04 lcd.setCursor(0, 0);
lcd.print("Phim vua bam la:"); Serial.begin(9600);
// Cấu hình chân hàng for (int row = 0; row < numRows; row++) { pinMode(rowPins[row], INPUT);
digitalWrite(rowPins[row], HIGH); // bật trở kéo lên } // Cấu hình chân cột
for (int col = 0; col < numCols; col++) {
pinMode(colPins[col], OUTPUT);
digitalWrite(colPins[col], HIGH); // không kích hoạt ban đầu } }
void loop() { char key = getKey(); // Hàm quét keypad if (key != 0) {
Serial.print("Vua nhan phim: "); Serial.println(key); lcd.setCursor(6, 1);
lcd.print(" "); // Xóa ký tự cũ lcd.setCursor(6, 1);
lcd.print(key); // Hiển thị ký tự mới } } char getKey() { char key = 0;
for (int col = 0; col < numCols; col++) {
digitalWrite(colPins[col], LOW); // Kích hoạt cột hiện tại
for (int row = 0; row < numRows; row++) {
if (digitalRead(rowPins[row]) == LOW) {
delay(debounceTime); // Chống dội
while (digitalRead(rowPins[row]) == LOW); // Chờ thả phím
key = keymap[row][col]; // Gán ký tự tương ứng } } lOMoAR cPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 04
digitalWrite(colPins[col], HIGH); // Vô hiệu hóa cột }
return key; // Trả về ký tự hoặc 0 nếu không có phím nhấn }
Ghi nhận kết quả khi nhấn nút theo thứ tự từ trái qua phải và từ trên xuống dưới thu
được kết quả như sau:
Nếu nhấn các nút từ trái qua phải, từ trên xuống dưới, bạn sẽ nhận được chuỗi ký tự:
7 8 9 / ; 4 5 6 * ; 1 2 3 - ; C 0 = +
- Hãy viết chương trình đọc password từ bàn phím. Nhận password là 13579. Nếu đúng
password thì nhấn phím = trên bàn phím để tắt và mở đèn led tại chân 13. Nếu sai thì đèn
nhấp nháy liên tục. Nhấn phím C để nhập lại password. #include #include
LiquidCrystal_I2C lcd(0x27, 16, 2); // LCD 16x2 với địa chỉ I2C const int numRows = 4; const int numCols = 4; const int debounceTime = 20; const int ledPin = 13;
const char correctPassword[] = "13579"; char
enteredPassword[10]; // Lưu trữ ký tự nhập byte passwordIndex = 0; bool
passwordAccepted = false; bool ledState = false;
const char keymap[numRows][numCols] = { {'7', '8', '9', '/'}, {'4', '5', '6', '*'}, {'1', '2', '3', '-'}, {'C', '0', '=', '+'} };
const int rowPins[numRows] = {11, 10, 9, 8};
const int colPins[numCols] = {7, 6, 5, 4}; void setup() { pinMode(ledPin, OUTPUT); digitalWrite(ledPin, LOW); lOMoAR cPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 04 lcd.init(); lcd.backlight(); lcd.setCursor(0, 0); lcd.print("Nhap mat khau:"); lcd.setCursor(0, 1); Serial.begin(9600);
for (int row = 0; row < numRows; row++) { pinMode(rowPins[row], INPUT);
digitalWrite(rowPins[row], HIGH); }
for (int col = 0; col < numCols; col++) {
pinMode(colPins[col], OUTPUT);
digitalWrite(colPins[col], HIGH); } } void loop() { char key = getKey(); if (key != 0) { if (key == 'C') { clearPassword(); }
else if (!passwordAccepted && key != '=' && passwordIndex <
sizeof(enteredPassword) - 1) {
enteredPassword[passwordIndex++] = key;
lcd.print('*'); // Ẩn ký tự nhập Serial.print("Nhap: "); Serial.println(key);
if (passwordIndex == strlen(correctPassword)) {
enteredPassword[passwordIndex] = '\0'; // Kết thúc chuỗi
if (strcmp(enteredPassword, correctPassword) == 0) {
passwordAccepted = true; lcd.clear(); lcd.print("Mat khau dung!"); lcd.setCursor(0, 1);
lcd.print("Nhan '=' bat LED"); delay(1000); lcd.clear(); } else { lcd.clear(); lcd.print("Sai mat khau!");
Serial.println("Sai mat khau!"); passwordIndex = 0; } lOMoAR cPSD| 60776878
Báo cáo thực hành môn Vi điều khiển Bài 04 } }
else if (passwordAccepted && key == '=') { ledState = !ledState;
digitalWrite(ledPin, ledState ? HIGH : LOW); lcd.setCursor(0, 0);
lcd.print(ledState ? "LED dang bat " : "LED dang tat "); } }
// Nếu sai mật khẩu, đèn nhấp nháy liên tục
if (!passwordAccepted && passwordIndex == strlen(correctPassword))
{ digitalWrite(ledPin, HIGH); delay(300); digitalWrite(ledPin, LOW); delay(300); } } char getKey() { char key = 0;
for (int col = 0; col < numCols; col++) {
digitalWrite(colPins[col], LOW);
for (int row = 0; row < numRows; row++) {
if (digitalRead(rowPins[row]) == LOW) { delay(debounceTime);
while (digitalRead(rowPins[row]) == LOW); key = keymap[row][col]; } }
digitalWrite(colPins[col], HIGH); } return key; } void clearPassword() { passwordIndex = 0; passwordAccepted = false;
lcd.clear(); lcd.setCursor(0, 0); lcd.print("Nhap mat khau:"); lcd.setCursor(0, 1);
Serial.println("Nhap lai mat khau");