You are on page 1of 96

BỘ CÔNG THƯƠNG

TRƯỜNG ĐẠI HỌC CÔNG THƯƠNG TP. HỒ CHÍ MINH

THIẾT KẾ HỆ THỐNG NHÚNG


Tài liệu dùng cho hệ Đại học chính quy

THÀNH PHỐ HỒ CHÍ MINH - NĂM 2023

-1-
THIẾT KẾ HỆ THỐNG NHÚNG
Tài liệu dùng cho hệ Đại học chính quy

(Lưu hành nội bộ)

THÀNH PHỐ HỒ CHÍ MINH - NĂM 2023

-2-
MỤC LỤC
Bài 1. Giới thiệu kit thực hành và lập trình điều khiển LED đơn
1.1. Giới thiệu Arduino
1.2. Cài đặt chương trình IDE Arduino
1.3. Lập trình hiển thị LED đơn
Bài 2. Lập trình đọc giá trị tương tự
2.1. Lâp trình đọc giá trị tương tự cơ bản
2.2. Lâp trình đọc giá trị tương tự phát cảnh báo; tích hợp buzzer , LED
Bài 3. Lập trình giao tiếp nút nhấn và bàn phím
3.1. Lập trình giao tiếp nút nhấn
3.2. Lập trình giao tiếp bàn phím
Bài 4. Lập trình hiển thị giá trị trên LED 7 đoạn
4.1. Lập trình giao tiếp module MAX7219 cơ bản
4.2. Lập trình giao tiếp module MAX7219 ứng dụng đồng hồ đếm lên
4.3. Lập trình giao tiếp module MAX7219 ứng dụng đồng hồ đếm xuống
Bài 5. Lập trình hiển thị giá trị trên LCD
5.1. Lập trình giao tiếp module LCD 2004 cơ bản
5.2. Lập trình giao tiếp module LCD 2004 ứng dụng đồng hồ đếm lên
5.3. Lập trình giao tiếp module LCD 2004 ứng dụng đồng hồ đếm xuống
Bài 6: Lập trình giao tiếp khối cảm biến
6.1. Cảm biến MQ-2
6.2. Cảm biến MQ-7
6.3. Cảm biến MQ-135
Bài 7. Lập trình thu thập và hiển thị giá trị cảm biến
7.1. Cảm biến AM-2315
7.2. Cảm biến AM-312
7.3. Cảm biến TCS3200
Bài 8. Lập trình điều khiển động cơ
8.1. Điều khiển động cơ Servo
8.2. Điều khiển động cơ DC
8.3. Điều khiển động cơ bước
Bài 9. Lập trình giao tiếp khối truyền nhận
9.1. Lập trình giao tiếp nối tiếp điều khiển relay từ màn hình Serial Monitor
9.2. Lập trình giao tiếp nối tiếp điều khiển relay hiển thị trạng thái trên LCD
9.3. Lập trình giao tiếp nối kết nối mạch đọc RFID
9.4. Lập trình giao tiếp module RF UART cơ bản
Bài 10. Lập trình giao tiếp module Sim, Bluetooth
10.1. Lập trình giao tiếp module Sim
10.2. Lập trình giao tiếp module Bluetooth
Bài 11: Lập trình giao tiếp robot dò line
11.1. Lập trình giao tiếp robot cơ bản

-3-
11.2. Lập trình giao tiếp robot dò line
Bài 12. Lập trình giao tiếp robot thu thập dữ liệu cảm biến
12.1. Lập trình giao tiếp robot thu thập giá trị khoảng cách
12.2. Lập trình giao tiếp robot thu thập giá trị gia tốc

-4-
Trường ĐH Công thương BÀI 1:
TP.HCM GIỚI THIỆU KIT THỰC HÀNH
Khoa CN Điện - Điện tử
VÀ LẬP TRINH GIAO TIẾP
Bộ môn: Điện tử
KHỐI HIỂN THI

A. MỤC TIÊU
Học xong bài này sinh viên có khả năng:
- Nắm được các thành phần của kit TH Thiết kế hệ thống nhúng, chức năng và hoạt
động của từng thành phần, sự giao tiếp của chúng với nhau trong kit.
- Nắm được sơ đồ phần cứng khối xuất nhập cơ bản và biết kết nối giữa khối CPU và
các ngoại vi.
- Biết cách biên dịch, biết cách sửa lỗi chương trình.
B. NỘI DUNG THỰC HÀNH
1.1. Arduino
Arduino là một bo mạch vi điều khiển do một nhóm giáo sư và sinh viên Ý thiết kế
và đưa ra đầu tiên vào năm 2005. Mạch Arduino được sử dụng để cảm nhận và điều
khiển nhiều đối tượng khác nhau. Nó có thể thực hiện nhiều nhiệm vụ từ lấy tín hiệu từ
cảm biến đến điều khiển đèn, động cơ, và nhiều đối tượng khác. Ngoài ra mạch còn có
khả năng liên kết với nhiều module khác nhau như module đọc thẻ từ, ethernet shield,
sim900A, ….để tăng khả ứng dụng của mạch.
Phần cứng bao gồm một board mạch nguồn mở được thiết kế trên nền tảng vi xử lý
AVR Atmel 8bit, hoặc ARM, Atmel 32-bit,…. Hiện phần cứng của Arduino có tất cả 6
phiên bản, Tuy nhiên phiên bản thường được sử dụng nhiều nhất là Arduino Uno và
Arduino Mega. Arduino Uno được sử dụng rất rộng rãi trên thế giới, rất nhiều ví dụ trên
youtube hoặc các trang hướng dẫn về Arduino sử dụng mạch này.
Phần mềm để lập trình cho mạch Arduino là phần mềm IDE. Đây là phần mềm mã
nguồn mở, và có thể được download từ trang web của Arduino: www.arduino.cc.

-5-
Hình 1.1: Board Arduino Mega thực tế

1.1.1. CÁP USB


Dây cáp thường được bán kèm theo bo, dây cáp dùng để cắm vào máy tính để nạp
chương trình cho bo và dây đồng thời cũng lấy nguồn từ nguồn usb của máy tính để cho
bo hoạt động.
Ngoài ra cáp USB còn được dùng để truyền dữ liệu từ bo Arduino lên máy tính. Dây
cáp có 2 đầu, đầu 1A được dùng để cắm vào cổng USB trên bo Arduino, đầu 1B dùng để
cắm vào cổng USB trên máy tính.
1.1.2. IC FTDI USB
IC này được lập trình như một bộ chuyển đổi USB-to-Serial dùng để giao tiếp với
máy tính thông qua giao thức Serial (dùng cổng COM).
1.1.3. Cổng nguồn ngoài
Cổng nguồn ngoài nhằm sử dụng nguồn điện bên ngoài như pin, bình acquy hay các
adapter cho bo Arduino hoạt động. Nguồn điện cấp vào cổng này là nguồn DC có hiệu
điện thế từ 6V đến 20V, tuy nhiên hiệu điện thế tốt nhất mà nhà sản xuất khuyên dùng là
từ 7 đến 12V.
1.1.4. Cổng USB
Cổng USB trên bo Arduino dùng để kết nối với cáp USB.
1.1.5. Nút reset
Nút reset được sử dụng để reset lại chương trình đang chạy. Đôi khi chương trình
chạy gặp lỗi, người dùng có thể reset lại chương trình.
1.1.6. ICSP
ICSP là chữ viết tắt của In-Circuit Serial Programming. Các chân này thường ít được
sử trong các dự án về Arduino.

-6-
1.1.7. Chân xuất tín hiệu ra
Có tất cả 14 chân xuất tín hiệu ra trong Arduino Uno, những chân có dấu ~ là những
chân có thể băm xung (PWM), tức có thể điều khiển tốc độ động cơ hoặc độ sáng của đèn.
1.1.8. IC ATmega
Là linh hồn của bo mạch Arduino Uno, IC này được sử dụng trong việc thu thập dữ
liệu từ cảm biến, xử lý dữ liệu, xuất tín hiệu ra,…
1.1.9. Chân ICSP của Atmega
Các chân ICSP của ATmega 328 được sử dụng cho các giao tiếp SPI (Serial
Peripheral Interface), một số ứng dụng của Arduino có sử dụng chân này, ví dụ như sử
dụng module RFID RC522 với Arduino hay Ethernet Shield với Arduino.
1.1.10. Chân lấy tín hiệu Analog
Các chân này lấy tín hiệu Analog (tín hiệu tương tự) từ cảm biến để IC Atmega 328
xử lý. Có tất cả 6 chân lấy tín hiệu Analog, từ A0 đến A5.
1.1.11. Chân cấp nguồn cho cảm biến
Các chân này dùng để cấp nguồn cho các thiết bị bên ngoài như role, cảm biến, RC
servo,…trên khu vực này có sẵn các chân GND (chân nối đất, chân âm), chân 5V, chân
3.3V như được thể hiện ở hình 2. Nhờ những chân này mà người sử dụng không cần thiết
bị biến đổi điện khi cấp nguồn cho cảm biến, role, rc servo,…Ngoài ra trên khu vực này
còn có chân Vin và chân reset, chân IOREF. Tuy nhiên các chân này thường ít được sử
dụng nên trong tài liệu này xin không đi sâu về nó.
1.1.12. Các linh kiện khác trên board Arduino
Ngoài các linh kiện đã liệt kê bên trên, Arduino còn 1 số linh kiện đáng chú ý khác.
Trên bo có tất cả 4 đèn led, bao gồm 1 led nguồn (led ON nhằm cho biết boa đã được cấp
nguồn), 2 led Tx và Rx, 1 led L. Các led Tx và Rx sẽ nhấp nháy khi có dữ liệu truyền từ
board lên máy tính hoặc ngược lại thông qua cổng USB. Led L được được kết nối với
chân số 13. Led này được gọi là led on board (tức led trên bo), led này giúp người dùng
có thể thực hành các bài đơn giản mà không cần dùng thêm led ngoài.
1.2. Cài đặt chương trình IDE Arduino
Vào trang chủ của Arduino: www.arduino.cc

-7-
Hình 1.2: Trang chủ của Arduino trên Google
Click vào tab SOFTWARE

Hình 1.3: Giao diện của trang chủ Arduino


Chọn hệ điều hành

Hình 1.4: Giao diện của phần Software

-8-
Có 2 tùy chọn cho hệ điều hành Windows là Windows installer và Windows zip file
for non admin install. Tùy chọn thứ nhất dùng cho người là admin của máy, tùy chọn thứ
2 cho người không phải admin của máy. Thông thường đa số chọn tùy chọn thứ nhất, tức
Windows installer.
Arduino có đưa ra 2 lựa chọn, bao gồm chỉ download về (just download) và
download về cùng quyên góp (contribute and download), như được thể hiện ở hình 6.
Arduino mong muốn người dùng nếu có điều kiện hãy quyên góp ủng hộ hãng, mức
quyên góp thấp nhất là 3USD.

Hình 1.5: Giao diện trang download IDE Arduino


Sau khi download IDE Arduino về, tiến hành cài đặt:

Hình 1.6: Giao diện File IDE Arduino khi download

Một thông báo có thể sẽ được hiện lên với hàng chữ: “do you want to run this file?”, tức
là bạn có muốn chạy file này không? Người dùng click và run (chạy) để cài chương trình.

-9-
Hình 1.7: Giao diện thông báo cài đặt IDE Arduino
Một thông báo về các điều khoản khi sử dụng phần mềm sẽ hiện ra. Người dùng nhấn
vào I Agree (tôi đồng ý), để tiếp tục cài đặt chương trình.

Hình 1.8: Giao diện thông báo điều khoản cài đặt IDE Arduino
Một màn hình để người dùng lựa chọn việc cài đặt các phần liên quan được hiện ra,
như ở hình 1.9. Các bạn có thể để nguyên như vậy và bấm Next để tiếp tục quá trình cài
đặt.

Hình 1.9: Giao diện cấu hình cài đặt IDE Arduino
Phần mềm sẽ yêu cầu bạn chọn vị trí để cài đặt. Các bạn có thể để nơi cài đặt mặc định
như phần mềm đưa ra, không thay đổi gì rồi bấm Install (Cài đặt).

-10-
Hình 1.10: Giao diện thông báo chọn đường cài đặt IDE Arduino
Màn hình thể hiện việc cài đặt sẽ xuất hiện, người dùng có thể nhấp vào “Show
detail” để xem chi tiết quá trình cài đặt.

Hình 1.11: Giao diện tiến hành cài đặt IDE Arduino
Trong quá trình cài đặt một số phiên bản sẽ hỏi có cài driver USB cho phần mềm
IDE không, như hình bên dưới, người dùng nên tíc chọn vào ô vuông “Always trust
software from “Arduino LLC””, sau đó bấm Install (Cài đặt) để cái đặt driver USB. Cần
phải cài driver này thì chương trình mới nhận cổng USB của mạch Arduino.

Hình 1.12: Giao diện thiết lập driver USB cho IDE Arduino
Sau khi việc cài đặt hoàn thành, trên màn hình sẽ xuất hiện dòng chữ Completed (Đã
hoàn thành), lúc này người dùng nhấn nút Close (đóng) để hoàn tất quá trình cài đặt và
bây giờ có thể sử dụng phần mềm. Biểu tượng của phần mềm sẽ xuất hiện trên màn hình

-11-
Desktop và bây giờ người dùng chỉ việc nhấp đúp vào nó để sử dụng như các phần mềm
khác.

Hình 1.13: Giao diện cài đặt IDE Arduino hoàn thiện
1.3. Giao diện làm việc của IDE Arduino

Hình 1.14: Giao diện khởi động IDE Arduino


Phần này nói về giao diện của phần mền IDE, hình bên dưới thể hiện những phần cơ
bản của giao diện. Người dùng có thể tìm hiểu sâu hơn về giao diện này, tuy nhiên đây là
phần cơ bản nhất và thường dùng nhất để có thể học nhanh Arduino, khi có thời gian các
bạn có thể tìm hiểu thêm các bài viết về nó trên arduino.cc hoặc google,… Các chức năng
cơ bản của các biểu tượng trên phần mềm được trình bày chi tiết ở các phần bên dưới.
Giao diện của phần mềm IDE có nhiều phần, tuy nhiên chúng ta chú ý đến những
phần quan trọng như được nêu ra trong hình trên.
1.3.1. Nút kiểm tra
Dùng để kiểm tra xem chương trình được viết có lỗi không. Nếu chương trình bị lỗi
thì phần mềm sẽ hiển thị thông tin lỗi ở vùng số 5.
1.3.2. Nút nạp chương trình
Dùng để nạp chương trình được viết xuống mạch Arduino. Trong quá trình nạp,
chương trình sẽ được kiểm tra lỗi trước sau đó mới thực hiện nạp xuống mạch Arduino.

-12-
1.3.3. Serial
Hiển thị màn hình giao tiếp với máy tính. Khi nhấp vào biểu tượng cái kính lúp thì
phần giao tiếp với máy tính sẽ được mở ra. Phần này sẽ hiển thị các thông số mà người
dùng muốn đưa lên màn hình. Muốn đưa lên màn hình phải có lệnh Serial.print() mới có
thể đưa thông số cần hiển thị lên màn hình.
1.3.4. Vùng lập trình
Vùng này để người lập trình thực hiện việc lập trình cho chương trình của mình.
1.3.5. Vùng thông báo thông tin
Có chức năng thông báo các thông tin lỗi của chương trình hoặc các vấn đề liên quan đến
chương trình được lập.

Hình 1.15: Giao diện vùng cửa sổ làm việc IDE Arduino
1.3.6. Sử dụng một số menu thông dụng trên phần mềm IDE
Có vài menu trong phần mềm IDE, tuy nhiên thông dụng nhất vẫn là menu File,
ngoài những tính năng như mở một file mới hay lưu một file, phần menu này có một mục
đáng chú ý là Example.
Phần Example (ví dụ) đưa ra các ví dụ sẵn để người lập trình có thể tham khảo, giảm
bớt thời gian lập trình.
Hình 1.16 bên dưới thể hiện việc chọn một ví dụ cho led chớp tắt (blink) để nạp cho
mạch Arduino. Ví dụ về led chớp tắt này thường được dùng để kiểm tra bo khi mới mua
về.
Một menu thường được sử dụng khác là menu Tools. Khi mới kết nối bo Arduino
với máy tính ta click vào Tools->board để chọn loại board sử dụng.

-13-
Phần mềm chọn sẵn kiểu bo là bo Arduino Uno, nếu người dùng dùng kiểu bo khác
thì chọn kiểu bo đang dùng.

Hình 1.16: Giao diện mở các bài mẫu tích hợp trên IDE Arduino

Hình 1.17: Giao diện cấu hình board sử dụng trên IDE Arduino
Bên cạnh việc chọn bo thì một phần quan trọng nữa là chọn cổng COM. Hình bên
dưới minh họa cho việc chọn cổng COM. Khi lần đầu gắn mạch Arduino vào máy tính,
người sử dụng cần nhấn chọn cổng COM bằng cách vào Tools -> Serial Port (một số
phiên bản dùng từ Port) sau đó nhấn chọn cổng COM, ví dụ như COM1. Những lần sau
khi đưa chính board Arduino đó vào máy tính thì không cần chọn cổng COM, nếu đưa bo
Arduino khác vào máy thì cần phải chọn lại cổng COM, quy trình thực hiện cũng tương
tự.

-14-
Hình 1.18: Giao diện cấu hình cổng giao tiếp board trên IDE Arduino
Sau khi thực hiện các bước trên xong, người dùng sẽ bắt tay vào việc lập trình. Phần
kế tiếp sẽ trình bày cấu trúc của một chương trình trong phần mềm IDE.
1.4. Cấu trúc chương trình trong IDE Arduino
Phần này sẽ trình bày cấu trúc của một chương trình trong IDE, đồng thời giải thích
một số lệnh thường được sử dụng để thuận tiện cho người dùng.
1.4.1. Khai báo biến
Đây là phần khai báo kiểu biến, tên các biến, định nghĩa các chân trên board một số
kiểu khai báo biến thông dụng:
* #define được đặt trước hàm void setup()

Hình 1.19: Giao diện một bài cơ bản trên IDE Arduino
Nghĩa của từ define là định nghĩa, hàm #define có tác dụng định nghĩa, hay còn gọi
là gán, tức là gán một chân, một ngõ ra nào đó với 1 cái tên. Ví dụ #define led 13
Chú ý: sau #define thì không có dấu “,” (dấy phẩy)
* Khai báo các kiểu biến khác như: int (kiểu số nguyên), float,…
Các bạn có thể tham khảo thêm các kiểu biến cũng như công dụng tại arduino.cc
1.4.2. Thiết lập void setup()
Dùng để thiết lập các giá trị biến ban đầu, chế độ hoạt động của các chân vào ra
void setup()
-15-
{
// code thiết lập được viết ở đây
}
Cấu trúc của 1 chương trình có ký hiệu xoắn mở và ký hiệu xoắn đóng ở đầu và ở
cuối, nếu thiếu phần này khi kiểm tra chương trình thì chương trình sẽ báo lỗi.
Ngoài ra chương trinh setup cũng thiết lập các tốc độ truyền dữ liệu nối tiếp, khai
báo gán chân cho các phần cứng cùng thư viên sử dụng.
Bảng 1.1: Các hàm hay sử dụng khi thiết lập
Dùng để truyền dữ liệu từ board Arduino lên
Serial.begin(9600);
máy tính.
pinMode(biến, kiểu vào hoặc ra);
Dùng để xác định kiểu chân là vào hay ra
Ví dụ: pinMode(PIN, INPUT);
1.4.3. Vòng lặp
Dùng để viết các lệnh trong chương trình để mạch Arduino thực hiện các nhiệm vụ
mà chúng ta mong muốn, thường bắt đầu bằng:
void loop()
{
// code chương trình chính được viết ở đây
}
Một số câu lệnh, cấu trúc thường gặp:
Bảng 1.2: Một số câu lệnh thường gặp
Ký hiệu, câu lệnh Ý nghĩa
Dấu // dùng để giải thích, khi nội dung giải thích nằm
// trên 1 dòng, khi kiểm tra chương trình thì phần kiểm tra
sẽ bỏ qua phần này, không kiểm tra,
/* Ký hiệu này cũng dùng để giải thích, nhưng giải thích
…. dành cho 1 đoạn, tức có thể xuống dòng được
*/
Define nghĩa là định nghĩa, xác định. Câu lệnh này nhằm
#define biến chân
gán tên 1 biến vào 1 chân nào đó. Ví dụ #define led 13
Dùng để tắt, mở 1 chân ra. Cú pháp của nó là
digitalWrite(chân,trạng thái chân);. Ở đây trạng thái
digitalWrite(chân, trạng
chân có thể là HIGH hoặc LOW. Ví dụ:
thái);
digital(led,HIGH); , hoặc digital(led,LOW); . Chú dấu
chấm phẩy đằng sau câu lệnh.
analogWrite(chân, Có ý nghĩa dùng để băm xung (PWM), thường dùng để
giá trị); điều khiển tốc độ động cơ, độ sáng led,..
Read nghĩa là đọc, lệnh này dùng để đọc giá trị digital tại
digitalRead(chân);
chân muốn đọc
Read nghĩa là đọc, lệnh này dùng để đọc giá trị analog
analogRead(chân);
tại chân muốn đọc
Delay nghĩa là chờ, trì hoãn, duy trì. Lệnh này dùng để
delay(thời gian);
duy trì trạng thái đang thực hiện chờ một thời gian. Thời

-16-
gian ở đây được tính bằng mili giây, 1 giây bằng 1 ngàn
mili giây.

if() if nghĩa là nếu, sau if là dấu (), bên trong dấu ngoặc là
{ một biểu thứ so sánh. Ví dụ trong bài về cảm biến độ
Các ẩm đất (phần 5) thì: if (giatriAnalog>500) //nếu giá trị
câulệnh; đọc được của biến giatriAnalog lớn hơn 500
} {
else digitalWrite(Led,HIGH); //Ra lệnh cho led sáng
{ delay(1000);//chờ 1s
Các câu lệnh; }
} else nghĩa là ngược lại
Serial.print(); In ra màn hình máy tính, lệnh này in không xuống dòng
In ra màn hình máy tính, in xong xuống dòng, giá trị tiếp
Serial.println();
theo sẽ được in ở dòng kế tiếp
1.5. Giới thiệu Kit
1.5.1 Module xử lý trung tâm

Hình 1.19a: Module xử lý trung tâm


1.5.2. Module cảm biến

Hình 1.19b: Module cảm biến

-17-
1.5.3. Module động cơ

Hình 1.19c: Module động cơ


1.5.4. Module truyền nhận

Hình 1.19d: Module truyền nhận


1.5.5. Module hiển thị
- Màn hình cảm ứng HDMI 7 inch
- Màn hình OLED 0.96 inch giao tiếp I2C
- Màn hình LCD 20x04 giao tiếp I2C

-18-
Hình 1.19e: Module hiển thị

Hình 1.19f : Mô hình Robot 1

-19-
Hình 1.19g: Mô hình Robot 2
1.6. Lập trình điều khiển LED đơn
Bảng 1.3: Chức năng điều khiển LED đơn
Sơ đồ mạch Code
 PIN 8 =‘1’ → LED ON digitalWrite(8, HIGH); delay(1000;
 PIN 8 =‘0’ → LED OFF digitalWrite(8, LOW); delay(1000;

 PIN 8 =‘0’ → LED ON digitalWrite(8, LOW); delay(1000;


 PIN 8 =‘1’ → LED OFF digitalWrite(8, HIGH); delay(1000;

Bài 1.1: Cho sơ đồ kết nối LED đơn với Arduino như hình 1.20. Viết chương trình điều
khiển LED đơn nhấp nháy.

-20-
Hình 1.20: Kết nối led đơn với Arduino

 Chương trình tham khảo


void setup()
{
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever


void loop()
{
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}

Hình 1.21: Giao diện mở bài mẫu Blink


1.7. Lập trình đọc giá trị tương tự
1.7.1. Lập trình đọc giá trị tương tự cơ bản
Bài 1.2: Cho sơ đồ kết nối biến trở với Arduino như hình 1.22. Viết chương trình đọc giá
trị Analo từ biến trở và hiển thị thông số lên Serial Monitor.

-21-
Hình 1.22: Kết nối biến trở với Arduino
 Chương trình tham khảo
int value, voltage;
void setup()
{
// put your setup code here, to run once:
Serial.begin(9600);
}

void loop()
{
// put your main code here, to run repeatedly:
value = analogRead(A0);
Serial.println(value);
voltage = map(value,0,1023,0,5000);
Serial.println(voltage);
Serial.println();
delay(200);
}
Bài 1.3: Cho sơ đồ kết nối mạch như hình 1.22. Viết chương trình đọc giá trị analog từ
biến trở, giao tiếp và hiển thị LCD 2004 ở bảng 1.4.
Bảng 1.4: Thông tin hiển thị LCD 2004
Add1 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E OF 10 11 12 13
R1 D A I H O C C O N G T H U O N G
Add2 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53
R2 K H O A D I E N - D I E N T U
Add3 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27
R3 T K H E T H O N G N H U N G !
Add4 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67
R4 V a l u e : V o l t a g e :
 Chương trình tham khảo
#include<Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
int Value, Voltage;
void setup()
{
// put your setup code here, to run once:
lcd.init();
lcd.backlight();
lcd.setCursor(1,0);
lcd.print("DAI HOC CONG THUONG");

-22-
lcd.setCursor(2,1);
lcd.print("KHOA DIEN-DIEN TU");
lcd.setCursor(1,2);
lcd.print("TK HE THONG NHUNG!");
lcd.setCursor(0,3);
lcd.print("Value:");
lcd.setCursor(9,3);
lcd.print("Voltage:");
}
void loop()
{
// put your main code here, to run repeatedly:
value = analogRead(A0);
lcd.setCursor(6,3);
lcd.print(value);
voltage = map(value,0,1023,0,5000);
lcd.setCursor(17,3);
lcd.print(Voltage);
}
1.7.2. Lập trình đọc giá trị tương tự phát cảnh báo, tích hợp buzzer , LED
Bài 1.4: Cho sơ đồ kết nối mạch như hình 1.23. Viết chương trình đọc giá trị analog từ
biến trở và cảnh báo ra Buzzer.

Hình 1.23: Kết nối biến trở và Buzzer với Arduino


 Chương trình tham khảo
int sensorPin = A0; // select the input pin for the potentiometer
int buzzerPin = 10; // select the pin for the LED
int sensorValue = 0; // variable to store the value coming from the sensor
void setup()
{
// declare the ledPin as an OUTPUT:
pinMode(buzzerPin, OUTPUT);
}
void loop()
{
// read the value from the sensor:
sensorValue = analogRead(sensorPin);
// turn the ledPin on
digitalWrite(buzzerPin, HIGH);
// stop the program for <sensorValue> milliseconds:
delay(sensorValue);
// turn the ledPin off:
digitalWrite(buzzerPin, LOW);

-23-
// stop the program for for <sensorValue> milliseconds:
delay(sensorValue);
}

Bài 1.5: Cho sơ đồ kết nối biến trở với Arduino như hình 1.24. Viết chương trình đọc giá
trị Analog từ biến trở.

Hình 1.24: Kết nối biến trở với Arduino


 Chương trình tham khảo
int sensorPin = A0; // select the input pin for the potentiometer
int ledPin = 13; // select the pin for the LED
int sensorValue = 0; // variable to store the value coming from the sensor
void setup()
{
// declare the ledPin as an OUTPUT:
pinMode(ledPin, OUTPUT);
}
void loop()
{
// read the value from the sensor:
sensorValue = analogRead(sensorPin);
// turn the ledPin on
digitalWrite(ledPin, HIGH);
// stop the program for <sensorValue> milliseconds:
delay(sensorValue);
// turn the ledPin off:
digitalWrite(ledPin, LOW);
// stop the program for for <sensorValue> milliseconds:
delay(sensorValue);
}

Hình 1.25: Giao diện mở bài mẫu AnalogInput


-24-
1.7.3. Đọc dữ liệu từ cổng nối tiếp
Bài 1.6: Viết chương trình đọc dữ liệu từ cổng nối tiếp.
 Chương trình tham khảo
String inputString = ""; // a String to hold incoming data
bool stringComplete = false; // whether the string is complete
void setup()
{
// initialize serial:
Serial.begin(9600);
// reserve 200 bytes for the inputString:
inputString.reserve(200);
}
void loop()
{
// print the string when a newline arrives:
if (stringComplete)
{
Serial.println(inputString);
// clear the string:
inputString = "";
stringComplete = false;
}
}
/*
SerialEvent occurs whenever a new data comes in the hardware serial RX. This
routine is run between each time loop() runs, so using delay inside loop can
delay response. Multiple bytes of data may be available.
*/
void serialEvent()
{
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag so the main loop can
// do something about it:
if (inChar == '\n')
{
stringComplete = true;
}
}
}

-25-
Hình 1.26: Giao diện mở bài mẫu SerialEvent

1.8. Lập trình giao tiếp nút nhấn và bàn phím


1.8.1. Ứng dụng giao tiếp nút nhấn - Bàn phím
Nút nhấn, bàn phím dùng để giao tiếp giữa con người và mạch điện tử để điều khiển,
ví dụ: bàn phím máy tính, bàn phím điện thoại, bàn phím máy bán xăng dầu dùng nhập số
tiền cần bán, số lít cần bán, … máy giặt tự động có bàn phím để chỉnh chế độ giặt, chọn
mực nước …
Có 2 dạng giao tiếp vi điều khiển với bàn phím, nút nhấn:
 Hệ thống ít phím: ví dụ điều khiển LED, động cơ bằng 3 phím: start, stop, inv, đồng
hồ có 3 đến 4 phím để chỉnh thời gian.
 Hệ thống nhiều phím: bàn phím máy tính, bàn phím điện thoại, …
1.8.2. Lập trình giao tiếp nút nhấn
Để hiểu giao tiếp vi điều khiển với bàn phím ta khảo sát các bài ứng dụng theo sau.
Bài 1.7: Cho sơ đồ kết nối mạch điều khiển LED đơn sử dụng nút nhấn như vẽ. Viết
chương trình điều khiển LED đơn.

Hình 1.27: Sơ đồ kết nối mạch điều khiển LED đơn sử dụng nút nhấn
 Chương trình tham khảo

-26-
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin
// variables will change:
int buttonState = 0; // variable for reading the pushbutton status
void setup()
{
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}
void loop()
{
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (buttonState == HIGH)
{ // turn LED on:
digitalWrite(ledPin, HIGH);
}
else
{ // turn LED off:
digitalWrite(ledPin, LOW);
}
}

Hình 1.28: Giao diện mở bài mẫu Button


1.8.3. Lập trình giao tiếp bàn phím
Với cách 1 thì mỗi phím sử dụng 1 ngõ vào để kết nối, 16 phím sẽ dùng 16 ngõ vào
như vậy sẽ dùng rất nhiều đường tín hiệu để giao tiếp, cách kết nối dùng ít tín hiệu hơn là
kiểu ma trận phím.
Cách kết nối dạng ma trận thì 16 phím chỉ dùng 8 tín hiệu: 4 cho hàng và 4 cho cột -
gọi là ma trận 4×4 sẽ được 16 phím, ma trận 8×8 sẽ được 64 phím.
Tổng quát ma trận bàn phím m×n thì số đường tín hiệu bằng “m+n”, số phím bằng
“m×n”
 Ưu điểm: Cách kết nối theo dạng ma trận là tiết kiệm đường điều khiển.
 Khuyết điểm: Chương trình phức tạp.
 Khảo sát ma trận bàn phím 4x4 = 16 phím

-27-
Sơ đồ mạch bàn phím như hình 3.2

Hình 1.29: Bàn phím ma trận 4x4


Trong ma trận 4×4 thì có 4 hàng và 4 cột, hàng được chọn là tín hiệu vào - cột được
chọn là tín hiệu ra, hàng thì treo lên nguồn Vcc qua điện trở nên mức logic của hàng luôn
là mức 1.
Các phím nhấn thường hở nên 4 hàng luôn ở mức 1 hay H3H2H1H0 =1111.
Cột là tín hiệu ra nên chúng ta điều khiển xuất dữ liệu ra cột tùy ý.
Để phân biệt các phím thì mỗi phím có 1 tên được đánh theo số thập lục phân từ ‘0’
đến ‘F’.
Để xem có phím nào nhấn hay không ta tiến hành quét từng cột bằng cách cho 1 cột
ở mức 0, 3 cột còn lại ở mức 1 và kiểm tra tất cả các hàng, nếu tất cả các hàng vẫn ở mức
logic 1 tức là không có nhấn phím, nếu có 1 hàng xuống mức 0 thì đã có nhấn phím. Cụ
thể như sau:
 Quét cột thứ 0
Xuất dữ liệu ra cột là: C3C2C1C0 =1110 như hình 3.2, kiểm tra hàng nào bằng không?
 Nếu bằng H0 = 0 thì đã nhấn phím số ‘0’.
 Nếu bằng H1 = 0 thì đã nhấn phím số ‘1’.
 Nếu bằng H2 = 0 thì đã nhấn phím số ‘2’.
 Nếu bằng H3 = 0 thì đã nhấn phím số ‘3’.
 Nếu không có phím nhấn nào ở cột C0 được nhấn thì phải quét cột tiếp theo.
 Quét cột thứ 1
Xuất dữ liệu ra cột là: C3C2C1C0 =1101 như hình 3.3, kiểm tra hàng nào bằng không?
 Nếu bằng H0 = 0 thì đã nhấn phím số ‘4’.
 Nếu bằng H1 = 0 thì đã nhấn phím số ‘5’.
 Nếu bằng H2 = 0 thì đã nhấn phím số ‘6’.
 Nếu bằng H3 = 0 thì đã nhấn phím số ‘7’.
 Nếu không có phím nhấn nào ở cột C1 được nhấn thì phải quét cột tiếp theo.

-28-
Hình 1.30: Bàn phím ma trận 4×4 với cột C1=0
 Quét cột thứ 2
Xuất dữ liệu ra cột là: C3C2C1C0 =1011 như hình 3.4, kiểm tra hàng nào bằng không?
 Nếu bằng H0 = 0 thì đã nhấn phím số ‘8’.
 Nếu bằng H1 = 0 thì đã nhấn phím số ‘9’.
 Nếu bằng H2 = 0 thì đã nhấn phím số ‘A’.
 Nếu bằng H3 = 0 thì đã nhấn phím số ‘B’.
 Nếu không có phím nhấn nào ở cột C2 được nhấn thì phải quét cột tiếp theo.

Hình 1.31: Bàn phím ma trận 4×4 với cột C2 = 0


 Quét cột thứ 3
Xuất dữ liệu ra cột là: C3C2C1C0 =0111 như hình 3.5, kiểm tra hàng nào bằng không?
 Nếu bằng H0 = 0 thì đã nhấn phím số ‘C’.
 Nếu bằng H1 = 0 thì đã nhấn phím số ‘D’.
 Nếu bằng H2 = 0 thì đã nhấn phím số ‘E’.
 Nếu bằng H3 = 0 thì đã nhấn phím số ‘F’.
 Nếu không có phím nhấn nào ở cột C3 đến đây xem như kết thúc.

Hình 1.32: Bàn phím ma trận 4×4 với cột C3 = 0


-29-
Tên các phím để chúng ta phân biệt, còn chương trình phân biệt các phím bằng mã,
mỗi phím có 1 mã phím do phần mềm lập trình xây dựng, để đơn giản mỗi phím được đặt
mã như sau:
Phím số ‘0’ có mã là 00H, phím số ‘1’ có mã là 01H, … phím ‘F’ có mã là 0FH.
Bài 1.8: Cho sơ đồ kết nối như hình 1.33. Viết chương trình giao tiếp bàn phím (ma trận
4x4) và hiển thị lên Serial Monitor và LCD cho ở bảng 1.5
Bảng 1.5: Thông tin hiển thị LCD 2004
Add1 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E OF 10 11 12 13
R1 D A I H O C C O N G T H U O N G
Add2 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53
R2 K H O A D I E N - D I E N T U
Add3 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27
R3 T K H E T H O N G N H U N G !
Add4 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67
R4 K E Y P A D

Hình 1.33: Sơ đồ mạch kết nối


 Chương trình tham khảo
#include <Keypad.h>
const byte rows = 4;
const byte columns = 4;
char keys[rows][columns]={
{'1', '2', '3' , 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'},
};
byte rowPins[rows] = {2, 3, 4, 5};
byte columnPins[columns] = {6, 7, 8, 9};
Keypad customKeypad = Keypad(makeKeymap(keys), rowPins, columnPins, rows, columns);
void setup()
{
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop()
{
// put your main code here, to run repeatedly:
char customKey = customKeypad.getKey();
if(customKey){Serial.println(customKey);}
}
 Chương trình tham khảo
#include <Wire.h>

-30-
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
LiquidCrystal_I2C lcd(0x27,20,4);
const byte rows = 4;
const byte columns = 4;
char keys[rows][columns]={
{'1', '2', '3' , 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'},
};
byte rowPins[rows] = {2, 3, 4, 5};
byte columnPins[columns] = {6, 7, 8, 9};
Keypad customKeypad = Keypad(makeKeymap(keys), rowPins, columnPins, rows, columns);
void setup()
{
// put your setup code here, to run once:
Serial.begin(9600);
lcd.init();
lcd.backlight();
}
void loop()
{
// put your main code here, to run repeatedly:
char customKey = customKeypad.getKey();
lcd.setCursor(1,0);
lcd.print("DH CONG THUONG");
lcd.setCursor(3,1);
lcd.print("KHOA DIEN-DIEN TU");
lcd.setCursor(1,2);
lcd.print("TK HE THONG NHUNG!");
lcd.setCursor(6,3);
lcd.print("KEYPAD");
if(customKey)
{
Serial.println(customKey);
lcd.setCursor(13,1);
lcd.print(customKey);
}
}
1.9. Lập trình hiển thị giá trị trên LED 7 đoạn
1.9.1. Ứng dụng điều khiển LED 7 đoạn
LED 7 đoạn là một thiết bị điện tử dùng để hiển thị ánh sáng. Đầu ra hiển thị có thể
dưới dạng hình ảnh hoặc văn bản hoặc dạng số. LED 7 đoạn được sử dụng rộng rãi trong
đồng hồ kỹ thuật số, máy tính cơ bản, đồng hồ đo điện tử và các thiết bị điện tử hiển thị
khác thông tin số.
 LED 7 đoạn có 2 loại

Hình 1.34: Hình dáng của LED 7 đoạn

-31-
(a) (b)
Hình 1.35: Cấu tạo LED 7 đoạn (a) Anode chung (b) Cathode chung
 Bảng mã LED 7 đoạn
Bảng 1.6: Bảng mã LED 7 đoạn Anode chung và Cathode chung
Binary Hexadecimal Hexadecimal
Decimal
dp g f e d c b a (Anode common) (Cathode common)
0 1 1 0 0 0 0 0 0 0xC0 0x3F
1 1 1 1 1 1 0 0 1 0xF9 0x06
2 1 0 1 0 0 1 0 0 0xA4 0x5B
3 1 0 1 1 0 0 0 0 0xB0 0X4F
4 1 0 0 1 1 0 0 1 0x99 0x66
5 1 0 0 1 0 0 1 0 0x92 0x6D
6 1 0 0 0 0 0 1 0 0x82 0x7D
7 1 1 1 1 1 0 0 0 0xF8 0x07
8 1 0 0 0 0 0 0 0 0x80 0x7F
9 1 0 0 1 0 0 0 0 0x90 0x6F
10 1 0 0 0 1 0 0 0 0x88 0x77
11 1 0 0 0 0 0 1 1 0x83 0x7C
12 1 1 0 0 0 1 1 0 0xC6 0x39
13 1 0 1 0 0 0 0 1 0xA1 0x5E
14 1 0 0 0 0 1 1 0 0x86 0x79
15 1 0 0 0 1 1 1 0 0x8E 0x71
1.9.2. Lập trình giao tiếp module MAX7219 cơ bản
Bài 1.9: Cho sơ đồ kết nối mạch điều khiển LED 7 đoạn như vẽ. Viết chương trình điều
khiển LED 7 đoạn hiển thị từ 0 - 7.

Hình 1.36: Sơ đồ kết nối mạch


 Chương trình tham khảo
#include<LedControl.h>
LedControl segment = LedControl{12, 11, 10, 1};//LedControl(int dataPin, int clkPin, int
loadPin, int numberDevice);
void setup()
{
// put your setup code here, to run once:
segment.shutdown(0, false); //int addr: 0->n-1, True: LED OFF, False: LED ON
segment.setIntensity(0, 15);
segment.clearDisplay(0);
}

-32-
void loop()
{
// put your main code here, to run repeatedly:
int i;
//Hien thi tu 0-7
for(i=0;i<8;i++)
{
segment.setDigit(0, i, i, 0);
}
}
 Thiết lập các tham số
Cú pháp: LedControl(int dataPin, int clkPin, int csPin, int numDevices=1);
 int dataPin: 12 Pin
 int clkPin: 11 Pin
 int csPin: 10 Pin
 int numberDevices: 1
Cú pháp: shutdown(int addr, bool status);
 int addr: 0
 bool status: false
Cú pháp: setIntensity(int addr, int intensity);
 int addr: 0
 int intensity: 15
Cú pháp: clearDisplay(0);
Cú pháp: setDigit(int addr, int digit, byte value, boolean dp);
 int addr: 0
 int digit: i
 byte value: i
 boolean dp: 0
Bài 1.10: Cho sơ đồ kết nối mạch điều khiển LED 7 đoạn như 1.36. Viết chương trình hiển thị
ký tự lên LED 7 đoạn.
 Chương trình tham khảo
#include<LedControl.h>
LedControl segment = LedControl{12, 11, 10, 1};//LedControl(data pin, clk pin, load pin,
nemberDevice);
void setup()
{
// put your setup code here, to run once:
segment.shutdown(0, false); //int addr: 0->n-1, True: LED OFF, False: LED ON
segment.setIntensity(0, 15);
segment.clearDisplay(0);
}
void loop()
{
// put your main code here, to run repeatedly:
int i;
//Hien thi ky tu A
for(i=0;i<8;i++)
{

-33-
segment.setChar(0, i, 'A', 0);
}
}
Bài 1.11: Cho sơ đồ kết nối mạch điều khiển LED 7 đoạn như 1.36. Viết chương trình hiển thị
từ 0-9 lên LED 7 đoạn.
 Chương trình tham khảo
#include<LedControl.h>
LedControl segment = LedControl{12, 11, 10, 1};//LedControl(data pin, clk pin, load pin,
nemberDevice);
void setup()
{
// put your setup code here, to run once:
segment.shutdown(0, false); //int addr: 0->n-1, True: LED OFF, False: LED ON
segment.setIntensity(0, 15);
segment.clearDisplay(0);
}
void loop()
{
// put your main code here, to run repeatedly:
int i,j;
for(i=0;i<=9;i++)
{
for(j=0;j<8;j++)
{
segment.setDigit(0, j, i, 0);
}
delay(1000);
}
}
Bài 1.12: Cho sơ đồ kết nối mạch điều khiển LED 7 đoạn như 1.37. Viết chương trình đếm lên
từ 0-9999 hiển thị LED 7 đoạn.
 Chương trình tham khảo
#include<LedControl.h>
LedControl segment = LedControl{12, 11, 10, 1};//LedControl(data pin, clk pin, load pin,
nemberDevice);
void setup()
{
// put your setup code here, to run once:
segment.shutdown(0, false); //int addr: 0->n-1, True: LED OFF, False: LED ON
segment.setIntensity(0, 15);
segment.clearDisplay(0);
}
void loop()
{
// put your main code here, to run repeatedly:
int i,j;
for(i=0;i<=9999;i++)
{
int a=i/1000;
int b=(i%1000)/100;
int c=(i%100)/10;
int d=i%10;
for(j=0;j<20;j++)
{
segment.setDigit(0, 0, d, 0);delay(10);
segment.setDigit(0, 1, c, 0);delay(10);
segment.setDigit(0, 2, b, 0);delay(10);
segment.setDigit(0, 3, a, 0);delay(10);
}
}

-34-
}
1.9.3. Lập trình giao tiếp module MAX7219 ứng dụng đồng hồ đếm lên
Bài 1.13: Cho sơ đồ kết nối mạch điều khiển LED 7 đoạn như 1.36. Viết chương trình
ứng dụng đồng hồ đếm lên.
 Chương trình tham khảo
#include<LedControl.h>
LedControl segment = LedControl{12, 11, 10, 1};//LedControl(data pin, clk pin, load pin,
nemberDevice);
int s=0;
void setup()
{
// put your setup code here, to run once:
segment.shutdown(0, false); //int addr: 0->n-1, True: LED OFF, False: LED ON
segment.setIntensity(0, 15);
segment.clearDisplay(0);
}
void loop()
{
// put your main code here, to run repeatedly:
int phut, giay;
giay=s%60; phut=s/60;
segment.setDigit(0, 0, giay%10, 0);delay(10);
segment.setDigit(0, 1, giay/10, 0);delay(10);
segment.setDigit(0, 2, phut%10, 0);delay(10);
segment.setDigit(0, 3, phut/10, 0);delay(10);
delay(1000);s+=1;
}
1.9.4. Lập trình giao tiếp module MAX7219 ứng dụng đồng hồ đếm xuống
Bài 1.14: Cho sơ đồ kết nối mạch điều khiển LED 7 đoạn như 1.36. Viết chương trình ứng dụng
đồng hồ đếm xuống.
 Chương trình tham khảo
#include<LedControl.h>
LedControl segment = LedControl{12, 11, 10, 1};//LedControl(data pin, clk pin, load pin,
nemberDevice);
void setup()
{
// put your setup code here, to run once:
segment.shutdown(0, false); //int addr: 0->n-1, True: LED OFF, False: LED ON
segment.setIntensity(0, 15);
segment.clearDisplay(0);
}
void loop()
{
// put your main code here, to run repeatedly:
for(m=59;m>=0;m--)
{
segment.setDigit(0, 2, m%10, 0);
segment.setDigit(0, 3, m/10, 0);
for(s=59;s>=0;s--)
{
segment.setDigit(0, 0, s%10, 0);
segment.setDigit(0, 1, s/10, 0);
delay(1000);
}
}
}
1.10. Lập trình hiển thị giá trị trên LCD

-35-
1.10.1. Giao tiếp I2C
I2C là giao thức truyền thông nối tiếp đồng bộ phổ biến hiện nay, được sử dụng rộng
rãi trong việc kết nối nhiều IC với nhau, hay kết nối giữa IC và các ngoại vi với tốc độ
thấp như kết nối OLED, LCD bằng I2C.
Giao tiếp I2C sử dụng 2 chân để kết nối là SCL (Serial Clock Line) và SDA (Serial
Data Line). Chân SCL có tác dụng để đồng bộ hóa giữa các thiết bị khi truyền dữ liệu,
còn chân SDA dùng truyền dữ liệu.

Hình 1.37: Cấu tạo giao tiếp I2C


 Giao tiếp I2C bao gồm quá trình truyền nhận dữ liệu giữa các thiết bị Master -
Slaver.
 Thiết bị Master là 1 vi điều khiển, nó có nhiệm vụ điều khiển đường tín hiệu SCL
và gửi nhận dữ liệu hay lệnh thông qua đường SDA đến các thiết bị khác.
 2 đường Bus SCL và SDA đều hoạt động ở chế độ Open Drain, có điện trở từ
4.7kΩ - 10kΩ kéo lên nguồn để 2 đường Bus SCL và SDA để giữ mặc định ở mức
logic cao (mức ‘1’).
 Khung truyền I2C
Read/ ACK/ ACK/ ACK/
Start Address Data Data Stop
Write NACK NACK NACK
Condition Frame Frame 1 Frame 2 Condition
bit bit bit bit
Hình 1.38: Khung truyền của I2C
Bảng 1.7: Chức năng các khối của khung truyền I2C
Ký hiệu Chức năng
SDA line chuyển từ một điện áp mức cao xuống một điện áp mức
Start Condition
thấp trước khi SCL line chuyển từ cao xuống thấp
Address Frame Địa chỉ vật lý gán cho các Slave (7 bits or 10 bits)
Xác định quá trình là truyền hay nhận dữ liệu từ thiết bị Master
Read/ Write bit - ‘0’: Master gửi dữ liệu đi
- ‘1’: Master nhận dữ liệu về
ACK/ NACK bit So sánh bit địa chỉ vật lý của thiết bị so với địa chỉ được gửi đến

-36-
- ‘0’: Địa chỉ Slave trùng với đại chỉ Master
- ‘1’: Địa chỉ Slave không trùng với đại chỉ Master (mặc định:
‘1’)
Frame dữ liệu (8 bits): Thiết lập bởi thiết bị gửi truyền (Master) đến
thiết bị nhận (Slave); 8 bits dữ liệu này được gửi đi, lập tức 1 bit
ACK/NACK được gửi ngay theo sau để xác nhận rằng thiết bị nhận
Data Frame
đã nhận được dữ liệu thành công hay chưa?
- ACK/NACK bit = ‘0’: Slave nhận dữ liệu thành công
- ACK/NACK bit =‘1’: Slave nhận dữ liệu không thành công
SDA line chuyển từ một điện áp mức thấp lên một điện áp mức cao
Stop Condition
sau khi SCL line chuyển từ thấp đến cao

Hình 1.39: Gán địa chỉ vật lý cho các Slave


 Quá trình truyền dữ liệu
 B1: Thiết bị Master gửi đi 1 xung Start bằng cách kéo 2 đường SDA, SCL từ mức
locgic ‘1’ -> ‘0’.
 B2: Master gửi đi 7 bit địa chỉ tới Slave muốn giao tiếp cùng với bit Read/Write.
 B3: Slave sẽ so sánh địa chỉ vật lý với địa chỉ vừa được gửi tới.
- Nếu trùng khớp, Slave sẽ xác nhận bằng cách kéo đường SDA xuống mức logic
‘0’ và set bit ACK/NACK bằng mức logic ‘0’.
- Nếu không trùng khớp thì đường SDA và bit ACK/NACK đều mặc định bằng mức
logic‘1’.
 B4: Thiết bị Master sẽ gửi hoặc nhận khung bit dữ liệu.
- Nếu Master gửi dữ liệu đến Slave thì bit Read/Write ở mức logic ‘0’.
- Nếu Master nhận dữ liệu thì bit Read/Write ở mức logic ‘1’.
 B5: Frame dữ liệu đã được truyền đi thành công, bit ACK/NACK được set thành
mức logic ‘0’ để báo hiệu cho Master tiếp tục.

-37-
 B6: Tất cả dữ liệu đã được gửi đến Slave thành công, Master sẽ phát 1 tín hiệu
Stop để báo cho các Slave biết quá trình truyền đã kết thúc bằng cách chuyển lần
lượt các đường SCL, SDA từ mức logic ‘0’ lên mức logic ‘1’.
1.10.2. Lập trình giao tiếp module LCD 2004 cơ bản
Bài 1.15: Cho sơ đồ kết nối mạch như hình 1.40. Viết chương trình hiển thị các thông tin
cho ở bảng 1.8
Bảng 1.8: Thông tin hiển thị LCD 2004
Add1 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E OF 10 11 12 13
R1 D A I H O C C O N G T H U O N G
Add2 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53
R2 H U F I 2 0 2 4
Add3 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27
R3 K H O A D I E N - D I E N T U
Add4 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67
R4 T K H E T H O N G N H U N G !

Hình 1.40: Sơ đồ kết nối mạch


 Chương trình tham khảo
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line
display

void setup()
{
lcd.init(); // initialize the lcd
lcd.init();
// Print a message to the LCD.
lcd.backlight();
lcd.setCursor(1,0);
lcd.print("DAI HOC CONG THUONG");
lcd.setCursor(5,1);
lcd.print("HUFI 2024");
lcd.setCursor(2,2);
lcd.print("KHOA DIEN-DIEN TU");
lcd.setCursor(1,3);
lcd.print("TK HE THONG NHUNG!");
}
void loop()
{
}
1.10.3. Lập trình giao tiếp module LCD 2004 ứng dụng đồng hồ đếm lên
Bài 1.16: Cho sơ đồ kết nối mạch như hình 1.40. Viết chương trình ứng dụng đồng hồ đếm lên
cho ở bảng 1.9.
Bảng 1.9: Thông tin hiển thị LCD 2004

-38-
Add1 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E OF 10 11 12 13
R1 D A I H O C C O N G T H U O N G
Add2 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53
R2 K H O A D I E N - D I E N T U
Add3 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27
R3 T K H E T H O N G N H U N G !
Add4 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67
R4 R T C C O U N T - U P :
 Chương trình tham khảo
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
int s,m;
void setup()
{
// put your setup code here, to run once:
int m=0;
Serial.begin(9600);
lcd.init();
lcd.backlight();
lcd.setCursor(1,0);
lcd.print("DAI HOC CONG THUONG");
lcd.setCursor(2,1);
lcd.print("KHOA DIEN-DIEN TU");
lcd.setCursor(1,2);
lcd.print("TK HE THONG NHUNG!");
lcd.setCursor(1,3);
lcd.print("RTC COUNT-UP");
lcd.setCursor(14,3);
lcd.print(m/10);
lcd.print(m%10);
lcd.setCursor(16,3);
lcd.print(":");
}
void loop() {
// put your main code here, to run repeatedly:
for(s=0;s<60;s++)
{
lcd.setCursor(17,3);
lcd.print(s/10);
lcd.print(s%10);
Serial.println(s);
delay(1000);}
m+=1;
if(m<60){
lcd.setCursor(14,3);
lcd.print(m/10);
lcd.print(m%10);
lcd.setCursor(16,3);
lcd.print(":");
Serial.println(m);}
}
1.10.4. Lập trình giao tiếp module LCD 2004 ứng dụng đồng hồ đếm xuống
Bài 1.17: Cho sơ đồ kết nối mạch như hình 1.40. Viết chương trình ứng dụng đồng hồ
đếm xuống cho ở bảng 1.10.
Bảng 1.10: Thông tin hiển thị LCD 2004
Add1 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E OF 10 11 12 13
R1 D A I H O C C O N G T H U O N G
Add2 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53
R2 K H O A D I E N - D I E N T U

-39-
Add3 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27
R3 T K H E T H O N G N H U N G !
Add4 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67
R4 R T C C O U N T - D O W N :
 Chương trình tham khảo
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F,16,2);
int s,m;
void setup()
{
// put your setup code here, to run once:
int m=59;
Serial.begin(9600);
lcd.init();
lcd.backlight();
lcd.setCursor(1,0);
lcd.print("DAI HOC CONG THUONG");
lcd.setCursor(2,1);
lcd.print("KHOA DIEN-DIEN TU");
lcd.setCursor(1,2);
lcd.print("TK HE THONG NHUNG!");
lcd.setCursor(0,3);
lcd.print("RTC COUNT-DOWN");
lcd.setCursor(15,3);
lcd.print(m/10);
lcd.print(m%10);
lcd.setCursor(17,3);
lcd.print(":");
Serial.println(s);
Serial.println(m);
}
void loop() {
// put your main code here, to run repeatedly:
for(m=59;m>=0;m--)
{
lcd.setCursor(17,3);
lcd.print(":");
lcd.setCursor(15,3);
lcd.print(m/10);
lcd.print(m%10);
Serial.println(m);
for(s=59;s>=0;s--)
{
lcd.setCursor(18,3);
lcd.print(s/10);
lcd.print(s%10);
Serial.println(s);
delay(1000);
}
}
1.10.5. Lập trình hiển thị trên LCD OLED
 Module LCD OLED SSD1306 128X64 0.96 inch
 Màn hình LCD OLED SSD1306 với kích thước 0.96 inch, cho khả năng hiển thị
hình ảnh tốt với khung hình 128x64 pixel.
 LCD OLED SSD1306 còn tương thích với hầu hết các vi điều khiển hiện nay
thông qua giao tiếp I2C & SPI.

-40-
 Màn hình sử dụng driver SSD1306 cùng thiết kế nhỏ gọn sẽ giúp bạn phát triển
các sản phẩm DIY hoặc các ứng dụng khác một cách nhanh chóng.
 Cấu tạo module LCD OLED SSD1306

Hình 1.41: Module LCD OLED SSD1306


Bảng 1.11: Chức năng các chân của module LCD OLED SSD1306
SSD1306 PIN Chức năng
GND Cấp nguồn GND (0 V)
VCC Cấp nguồn VCC (3.3 V - 5 V)
SCL Serial Clock line
SDA Serial Data Line
 Thông số kĩ thuật
 Driver: SSD1306
 Tương thích với Arduino, 51 Series, MSP430 Series, STM32 / 2, CSR IC,…
 Tiêu thụ điện năng thấp: 0.08W (fullscreen)
 Có thể điều chỉnh độ sáng và độ tương phản
 Chuẩn giao tiếp: I2C (thông qua 2 chân SCL, SDA)
 Điện áp hoạt động: 3.3V-5V DC
 Nhiệt đô hoạt động: -30℃-70℃
 Kích thước màn hình: 0.96 inch (128x64 pixel)
 Kích thước module: 26.70* 19.26* 1.85mm (1.030.760.07 inch)
 Một số lệnh giao tiếp với module LCD OLED SSD1306
 display.clearDisplay(); //– all pixels are off
 display.drawPixel(x,y, color); //– plot a pixel in the x,y coordinates
 display.setTextSize(n); //– set the font size, supports sizes from 1 to 8
 display.setCursor(x,y); //– set the coordinates to start writing text
 display.print(“message”); //– print the characters at location x,y
 display.display(); //– call this method for the changes to make effect

-41-
Bài 1.18: Cho sơ đồ kết nối mạch như hình 1.42. Viết chương trình hiển thị thông tin lên
module LCD OLED

Hình 1.42: Kết nối module LCD OLED với Arduino


 Chương trình tham khảo
#include <Wire.h>
#include <SSD1306Ascii.h>
#include <SSD1306AsciiWire.h>
// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C
SSD1306AsciiWire oled;
void setup()
{
// put your setup code here, to run once:
Wire.begin();
oled.begin(&Adafruit128x64, I2C_ADDRESS);
oled.set400kHz();
oled.setFont(Adafruit5x7);
uint32_t m = micros();
oled.clear();
oled.println("Hello world!");
oled.println();
//oled.set2X();
oled.println("Lop thiet ke");
oled.println();
//oled.set2X();
oled.println("He thong nhung");
oled.println();
//oled.set2X();
oled.println("HUFI");
}
void loop()
{
// put your main code here, to run repeatedly:
}
 LCD OLED SSD1327 128x128 1.5 inch
 Màn hình LCD OLED SSD1327 với kích thước 1.5 inch, cho khả năng hiển thị
hình ảnh tốt với khung hình 128x128 pixel.
 LCD OLED SSD1327 còn tương thích với hầu hết các vi điều khiển hiện nay
thông qua giao tiếp I2C & SPI.

-42-
 Màn hình sử dụng driver SSD1327 cùng thiết kế nhỏ gọn sẽ giúp bạn phát triển
các sản phẩm DIY hoặc các ứng dụng khác một cách nhanh chóng.
 Cấu tạo module LCD OLED SSD1327

Hình 1.43: Module LCD OLED SSD1327


Bảng 1.12: Chức năng các chân của module LCD OLED SSD1327
SSD1327 PIN Chức năng
VCC Power (3.3 V - 5 V)
GND GND (0 V)
DIN Input Data
CLK Clock Input
CS Chip Select, Active (Logic Level = ‘0’)
DC Data/Command selection (High for data, Low for command)
RST Reset, Active (Logic Level = ‘0’)
 Thông số kĩ thuật
 Driver: SSD1327
 Giao tiếp: SPI/I2C
 Màu hiển thị: Trắng
 Thang màu xám: 16
 Độ phân giải: 128x128
 Góc nhìn: >160°
 Điện áp hoạt động: 3.3V / 5V
 Kích thước: 44.5 x 37 (mm)

-43-
Trường ĐH Công thương
BÀI 2:
TP.HCM
LẬP TRINH GIAO TIẾP
Khoa: CN Điện – Điện tử
Bộ môn: Điện tử KHỐI CẢM BIẾN

A. MỤC TIÊU
Học xong bài này sinh viên có khả năng:
- Nắm được các thành phần của kit TH Thiết kế hệ thống nhúng, chức năng và hoạt
động của từng thành phần, sự giao tiếp của chúng với nhau trong kit.
- Nắm được sơ đồ phần cứng khối xuất nhập cơ bản và biết kết nối giữa khối CPU và
các ngoại vi.
- Biết cách biên dịch, biết cách sửa lỗi chương trình.
B. NỘI DUNG THỰC HÀNH
3.1. Cảm biến MQ-2
 Module cảm biến khí Gas MQ-2
 Sử dụng phần tử SnO2 có độ dẫn điện thấp hơn trong không khí sạch, khi khí dễ
cháy tồn tại, cảm biến có độ dẫn điện cao hơn, nồng độ chất dễ cháy càng cao thì
độ dẫn điện của SnO2 sẽ càng cao và được tương ứng chuyển đổi thành mức tín
hiệu điện.
 Cảm biến khí có độ nhạy cao với LPG, Propane và Hydrogen, mê-tan (CH4) và
hơi dễ bắt lửa khác, với chi phí thấp và phù hợp cho các ứng dụng khác nhau.
 Cảm biến xuất ra cả hai dạng tín hiệu là Analog và Digital, tín hiệu Digital có thể
điều chỉnh mức báo bằng biến trở.
 Cấu tạo module cảm biến khí Gas - MQ2

Hình 3.1: Module cảm biến khí Gas - MQ2

-44-
Bảng 3.1: Chúc năng các chân của module cảm biến khí Gas - MQ2
PIN MQ2 Chức năng
VCC Power: 5V
GND GND
D Digital Output
A Analog Output
Bài 2.1: Cho sơ đồ kết nối như hình 2.1. Viết chương trình đọc tín hiệu từ module cảm
biến khí Gas MQ - 2 và hiển thị giá trị lên Serial Monitor
 Sơ đồ kết nối

Hình 2.1: Sơ đồ kết nối Arduino với module cảm biến MQ - 2


 Chương trình tham khảo
// cam bien MQ2 GAS
const int AOUTpin=A0;
int value;
void setup()
{
Serial.begin(9600);
}

void loop()
{
value= analogRead(AOUTpin);

Serial.print("GAS value: ");


Serial.println(value);

delay(1000);
}
2.2. Cảm biến MQ-7
 Module cảm biến khí CO MQ-7
 Cảm biến bán dẫn có giá rẻ có khả năng phát hiện khí carbon monoxide có nồng
độ từ 10 đến 1000 ppm. Vật liệu tạo ra cảm biến là từ chất SnO2, có độ dẫn điện
thấp trong không khí sạch.

-45-
 Có độ nhạy cao và thời gian đáp ứng nhanh. Có 2 dạng tín hiệu ngõ ra là analog và
digital. Cảm biến có thể hoạt động được ở nhiệt độ từ: -20 độ C đến 50 độ C và
tiêu thụ dòng khoảng 150mA tại 5V. Tuổi thọ cao, chi phí thấp.
 Thông số kỹ thuật
 Điện áp cung cấp: 3 ~ 5V DC.
 Sử dụng chip so sánh LM393 và MQ-7.
 Hai dạng tín hiệu đầu ra (digital và analog).
 Tín hiệu analog từ 0~5V.
 Dải phát hiện từ 10 đến 1000ppm.
 Công suất tiêu thụ: khoảng 350mW.
 Nhiệt độ hoạt động: -10 0C đến 50 0C.
 Kích thước: 33 x 20 x 16mm.
Bài 2.2: Cho sơ đồ kết nối như hình 2.2. Viết chương trình đọc tín hiệu từ module cảm
biến khí CO MQ - 7 và hiển thị giá trị lên Serial Monitor.
 Sơ đồ kết nối

Hình 2.2: Sơ đồ kết nối Arduino với cảm biến MQ – 7


 Chương trình tham khảo
/*
* Kết nối:
* MQ7 Arduino
* VCC GND
* GND VCC
* A0 A0
* D0 8
*/
const int AOUTpin=A0;
const int DOUTpin=8;
int value;
void setup()
{
Serial.begin(9600);
pinMode(DOUTpin, INPUT);
}
-46-
void loop()
{
value= analogRead(AOUTpin);
limit= digitalRead(DOUTpin);
Serial.print("CO value: ");
Serial.println(value);
Serial.print("Limit: ");
Serial.print(limit);
delay(1000);
}
2.3. Cảm biến MQ-135
 Module cảm biến chất lượng không khí MQ-135
Dùng trong các thiết bị kiểm tra chất lượng không khí bên trong cao ốc, văn phòng,
thích hợp để phát hiện NH3, NOx, Ancol, Benzen, khói, CO2,…
 Thông số kỹ thuật
 Điện áp nguồn: 5 VDC
 Điện áp của heater: 5V ± 0.1 AC/DC
 Điện trở tải: thay đổi được (2kΩ - 47kΩ)
 Điện trở của heater: 33Ω ± 5%
 Công suất tiêu thụ của heater: ít hơn 800mW
 Khoảng phát hiện: 10 - 300 ppm NH3, 10 - 1000 ppm Benzene, 10 - 300 Alcol
 Kích thước: 32mm*20mm
 Khoảng đo rộng
 Bền, tuổi thọ cao
 Phát hiện nhanh, độ nhạy cao
 Mạch đơn giản
Bài 2.3: Cho sơ đồ kết nối như hình 2.3. Viết chương trình đọc tín hiệu từ module cảm
biến khí không khi MQ - 135 và hiển thị giá trị lên Serial Monitor.

Hình 2.3: Sơ đồ kết nối Arduino với module cảm biến MQ – 135
 Chương trình tham khảo

-47-
/*
* Kết nối:
* MQ135 Arduino
* VCC GND
* GND VCC
* A0 A0
* D0 8
*/

// cam bien MQ135 chat luong khong khi


const int AOUTpin=A0;
int value;

void setup()
{
Serial.begin(9600);

void loop()
{
value= analogRead(AOUTpin);

Serial.print("KK value: ");


Serial.println(value);

delay(1000);
}
2.4. Cảm biến AM-2315
 Module cảm biến nhiệt độ độ ẩm AM-2315
 Sử dụng để đo nhiệt độ và độ ẩm với chuẩn giao tiếp I2C rất dễ dàng để kết nối và
giao tiếp với vi điều khiển, có thiết kế chuyên nghiệp, chất lượng linh kiện và gia
công tốt, độ bền cao.
 Dòng điện tối đa khi sử dụng: 10mA. Kích thước: đường kính 16mm, dài 98mm,
có 4 dây tín hiệu dài 20 inch.
 Thông số kỹ thuật
 Điện áp hoạt động: 3.5V ~ 5.5V.
 Dòng điện tối đa khi sử dụng: 10mA.
 Đọc độ ẩm: từ 0 - 100 % sai số 2%.
 Nhiệt độ: -20 0C ~ 80 0C sai số 0.1 0C.
 Kích thước: đường kính 16mm, dài 98mm.
 4 dây tín hiệu dài 20 inch
 Khối lượng: 82.64g
-48-
 Địa chỉ I2C: 05C
Bài 2.4: Cho sơ đồ mạch như hình 2.4. Viết chương trình đọc tín hiệu từ cảm biến AM-
2315 và hiển thị giá trị lên Serial Monitor.
 Sơ đồ kết nối

Hình 2.4: Sơ đồ kết nối Arduino với module cảm biến MQ – 2315
 Chương trình tham khảo
#include <Wire.h>
#include <Adafruit_AM2315.h>

Adafruit_AM2315 am2315;

void setup() {
Serial.begin(9600);
Serial.println("AM2315 Test!");

if (! am2315.begin()) {
Serial.println("Sensor not found, check wiring & pullups!");
while (1);
}
}

void loop() {
Serial.print("Hum: "); Serial.println(am2315.readHumidity());
Serial.print("Temp: "); Serial.println(am2315.readTemperature());
delay(1000);
}
2.5. Cảm biến AM-312
 Module cảm biến PIR AM-312
 Cảm biến thân nhiệt chuyển động PIR (Passive infrared sensor) AM-312 có thiết
kế rất nhỏ gọn, được sử dụng để phát hiện chuyển động của các vật thể phát ra bức
xạ hồng ngoại: con người, con vật, các vật phát nhiệt,…
 Cảm biến thân nhiệt chuyển động PIR HC-SR505 sẽ xuất ra tín hiệu mức cao
(High) khi phát hiện vật thể nhiệt chuyển động trong vùng quét, tín hiệu này sau
đó sẽ được giữ ở mức cao trong khoảng thời gian trễ T sau khi kích hoạt, lúc này
-49-
nếu cảm biến vẫn bắt được tín hiệu sẽ vẫn duy trì chân tín hiệu mức cao trong thời
gian trễ T, chỉ khi trong khoảng thời gian trễ T mà cảm biến không bắt được tín
hiệu thì chân tín hiệu cảm biến mới trở về mức thấp (Low).

Hình 2.5: Module cảm biến PIR AM 312


Bảng 2.2: Chức năng các chân của module cảm biến PIR AM-312
PIN Chức năng
VCC Power 5VDC
OUT Digital PIN
- Mức logic ‘1’: vật thể có thân nhiệt chuyển động
- Mức logic ‘0’: không có vật thể
GND GND
 Thông số kỹ thuật
 Điện áp hoạt động: 2.7VDC - 12 VDC
 Static power consumption: < 0.1mA
 Delay time: 2 seconds
 The blocking time: 2 seconds
 Trigger: can be repeated
 Sensing range: 3 meters, ≤ 100 degree cone angle
 Working temperature: - 20 ℃ - +60 ℃
 PCB Dimensions: 10mm x 8mm
 Total size: Approx. 12mm x 25 mm
 Module Lens: Small lens
Bài 2.5: Cho sơ đồ mạch như hình 2.5. Viết chương trình đọc tín hiệu từ cảm biến AM-
312 và hiển thị giá trị lên Serial Monitor
 Sơ đồ kết nối

Hình 2.6: Sơ đồ kết nối Arduino với module PIR AM 312


-50-
 Chương trình tham khảo
/*
* Kết nối:
* VCC ----- 5V (Arduino)
* OUT ----- 3 (Arduino)
* GND ----- GND (Arduino)
*/

void setup()
{
Serial.begin(9600);
}

void loop()
{
Serial.println(digitalRead(3));
delay(1000);
}
2.6. Cảm biến TCS-3200
 Module cảm biến màu sắc TCS-3200
Cảm biến màu sắc TCS3200 Color Sensor được sử dụng để nhận biết màu sắc bằng
cách đo phản xạ 3 màu sắc cơ bản từ vật thể là đỏ, xanh lá và xanh dương từ đó xuất ra
tần số xung tương ứng với 3 màu này qua các chân tín hiệu, đo 3 tần số xung này và qua
1 vài bước chuyển đổi nhất định là bạn sẽ có đươc thông tin của màu sắc của vật thể cần
đo.

Hình 2.7: Module cảm biến màu sắc TCS-3200


Bảng 2.3: Chức năng các chân của module cảm biến màu sắc TCS-3200
STT PIN Function
1 S0 Pins are used to select the frequency scaling
2 S1 Pins are used to select the frequency scaling
OE is the Output Enable pin. This pin is rarely used
3 OE and on most modules is permanently enabled. If not
already enabled then pull it LOW
4 GND Ground
5 S3 Pins are used to select the color array
6 S2 Pins are used to select the color array
-51-
7 OUT OUT pin is a TTL level square wave
Pin supplies power to the module. Connect it to the
8 VCC
2.7V to 5.5V power supply
Bảng 2.4: To choose different types of photodiodes
S3 S2 Photodiode type

0 0 Red

0 1 Clear (No filter)

1 0 Blue

1 1 Green

Bảng 2.5: To choose different scaling the output frequency


S1 S0 Output frequency scaling

0 0 Power down

0 1 20%

1 0 2%

1 1 100%
Bài 2.6: Cho sơ đồ mạch như hình 2.8. Viết chương trình đọc tín hiệu từ module cảm
biến TCS-3200 và hiển thị giá trị lên Serial Monitor
 Sơ đồ kết nối

Hình 2.8: Sơ đồ kết nối Arduino với module cảm biến TCS-3200
 Chương trình tham khảo
/*
// TCS230 color recognition sensor
// Sensor connection pins to Arduino are shown in comments
// project ket hop Thay Huy, co the hoc 5 mau, cho phep phat hien mau da hoc, thiet
lap muc 0 o ngo ra
Color Sensor Arduino
-52-
----------- --------
VCC 5V
GND GND
s0 8
s1 9
s2 12
s3 11
OUT 10
OE GND
*/
#include <EEPROM.h>
const int s0 = 8;
const int s1 = 9;
const int s2 = 12;
const int s3 = 11;
const int out = 10;

int led=13;
int buttonPin=A2;

// Variables
int red = 0;
int green = 0;
int blue = 0;
void color()
{
digitalWrite(s2, LOW);
digitalWrite(s3, LOW);
//count OUT, pRed, RED
red = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
digitalWrite(s3, HIGH);
//count OUT, pBLUE, BLUE
green = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
digitalWrite(s2, HIGH);
//count OUT, pGreen, GREEN
blue = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
}
void setup()
{
// xoa_eeprom();
Serial.begin(9600);
pinMode(s0, OUTPUT);
pinMode(s1, OUTPUT);
pinMode(s2, OUTPUT);
pinMode(s3, OUTPUT);
pinMode(out, INPUT);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(led, OUTPUT);

-53-
digitalWrite(s0, HIGH);
digitalWrite(s1, HIGH);

void loop()
{
color();

Serial.println("ban dang doc gia tri mau ");


Serial.print(" R: ");
Serial.print(red, DEC);
Serial.print(" G: ");
Serial.print(green, DEC);
Serial.print(" B: ");
Serial.print(blue, DEC);
Serial.println();
delay(2000); }

-54-
Trường ĐH Công thương
BÀI 3:
TP.HCM
LẬP TRINH THU THẬP VÀ HIỂN THI
Khoa: CN Điện – Điện tử
Bộ môn: Điện Tử GIÁ TRI CẢM BIẾN

A. MỤC TIÊU
Học xong bài này sinh viên có khả năng:
- Nắm được các thành phần của kit TH Thiết kế hệ thống nhúng, chức năng và hoạt
động của từng thành phần, sự giao tiếp của chúng với nhau trong kit.
- Nắm được sơ đồ phần cứng khối xuất nhập cơ bản và biết kết nối giữa khối CPU và
các ngoại vi.
- Biết cách biên dịch, biết cách sửa lỗi chương trình.
B. NỘI DUNG THỰC HÀNH
3.1. Thu thập giá trị cảm biến MQ-2
Bài 3.1: Cho sơ đồ kết nối như hình 3.1. Viết chương trình đọc tín hiệu từ cảm biến khí
Gas MQ - 2 và hiển thị thông tin lên LCD cho ở bảng 3.1
Bảng 3.1: Thông tin hiển thị LCD 2004
Add1 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E OF 10 11 12 13
R1 D A I H O C C O N G T H U O N G
Add2 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53
R2 K H O A D I E N - D I E N T U
Add3 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27
R3 T K H E T H O N G N H U N G !
Add4 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67
R4 G A S V a l u e :

 Sơ đồ mạch kết nối

Hình 3.1: Sơ đồ kết nối Arduino với cảm biến MQ - 2


 Chương trình tham khảo giao tiếp với LCD 2004 (Analog)
#include <Wire.h>

-55-
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
int AoutPin = A0;
int value;
void setup()
{
// put your setup code here, to run once:
pinMode(AoutPin, INPUT);
lcd.init();
lcd.backlight();
Serial.begin(9600);
lcd.setCursor(1,0);
lcd.print("DAI HOC CONG THUONG");
lcd.setCursor(2,1);
lcd.print("KHOA DIEN-DIEN TU");
lcd.setCursor(1,2);
lcd.print("TK HE THONG NHUNG!");
lcd.setCursor(2,3);
lcd.print("GAS Value:");
}

void loop()
{
// put your main code here, to run repeatedly:
value = analogRead(AoutPin);
Serial.println(value);
lcd.setCursor(13,3);
lcd.print(value);
delay(1000);
}

 Chương trình tham khảo giao tiếp với LCD 2004 (Digital)
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
int DoutPin = 8;
int value;
void setup()
{
// put your setup code here, to run once:
pinMode(DoutPin, INPUT);
lcd.init();
lcd.backlight();
Serial.begin(9600);
lcd.setCursor(1,0);
lcd.print("DAI HOC CONG THUONG");
lcd.setCursor(2,1);
lcd.print("KHOA DIEN-DIEN TU");
lcd.setCursor(1,2);
lcd.prihnt("TK HE THONG NHUNG!");
lcd.setCursor(2,3);
lcd.print("GAS Value:");
}
void loop()
{
// put your main code here, to run repeatedly:
value = digitalRead(DoutPin);
Serial.println(value);
lcd.setCursor(13,3);
lcd.print(value);
delay(1000);
}
Bài 3.2: Viết chương trình đọc tín hiệu từ cảm biến khí Gas MQ - 2 và hiển thị thông tin
lên LCD OLED.
-56-
 Chương trình tham khảo giao tiếp với LCD OLED (Analog)
#include <Wire.h>
#include <SSD1306Ascii.h>
#include <SSD1306AsciiWire.h>
// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C
SSD1306AsciiWire oled;
int AoutPin = A0;
int value;
void setup()
{
// put your setup code here, to run once:
Wire.begin();
oled.begin(&Adafruit128x64, I2C_ADDRESS);
oled.set400kHz();
oled.setFont(Adafruit5x7);
uint32_t m = micros();
pinMode(AoutPin, INPUT);
oled.clear();
oled.println("Hello world!");
oled.println();
//oled.set2X();
oled.println("Lop thiet ke");
oled.println();
//oled.set2X();
oled.println("He thong nhung");
oled.println();
//oled.set2X();
oled.println("HUFI");
delay(5000);
oled.clear();
oled.println("KHOA DIEN-DIEN TU");
oled.println();
oled.println("GAS Value:");
oled.println();
}

void loop()
{
// put your main code here, to run repeatedly:
value = analogRead(AoutPin);
oled.clear();
oled.set1X();
oled.println("KHOA DIEN-DIEN TU");
oled.println();
oled.println("GAS Value:");
oled.println();
oled.set2X();
oled.print("");
oled.println(value);
delay(1000);
}

 Chương trình tham khảo giao tiếp với LCD OLED (Digital)
#include <Wire.h>
#include <SSD1306Ascii.h>
#include <SSD1306AsciiWire.h>
// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C
SSD1306AsciiWire oled;
int DoutPin = 8;
int value;
void setup()
{

-57-
// put your setup code here, to run once:
Wire.begin();
oled.begin(&Adafruit128x64, I2C_ADDRESS);
oled.set400kHz();
oled.setFont(Adafruit5x7);
uint32_t m = micros();
pinMode(DoutPin, INPUT);
oled.clear();
oled.println("Hello world!");
oled.println();
//oled.set2X();
oled.println("Lop thiet ke");
oled.println();
//oled.set2X();
oled.println("He thong nhung");
oled.println();
//oled.set2X();
oled.println("HUFI");
delay(5000);
oled.clear();
oled.println("KHOA DIEN-DIEN TU");
oled.println();
oled.println("GAS Value:");
oled.println();
}

void loop()
{
// put your main code here, to run repeatedly:
value = digitalRead(DoutPin);
oled.clear();
oled.set1X();
oled.println("KHOA DIEN-DIEN TU");
oled.println();
oled.println("GAS Value:");
oled.println();
oled.set2X();
oled.print("");
oled.println(value);
delay(1000);
}
3.2. Cảm biến MQ-7
Bài 3.3: Cho sơ đồ kết nối như hình 3.2. Viết chương trình đọc tín hiệu từ cảm biến khí
CO MQ - 7 và hiển thị thông tin lên LCD cho ở bảng 3.2
Bảng 3.2: Thông tin hiển thị LCD 2004
Add1 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E OF 10 11 12 13
R1 D A I H O C C O N G T H U O N G
Add2 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53
R2 K H O A D I E N - D I E N T U
Add3 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27
R3 T K H E T H O N G N H U N G !
Add4 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67
R4 C O V a l u e :

 Sơ đồ mạch kết nối

-58-
Hình 3.2: Sơ đồ kết nối Arduino với cảm biến MQ - 7
 Chương trình tham khảo giao tiếp với LCD 2004 (Analog)
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
int AoutPin = A0;
int value;
void setup()
{
// put your setup code here, to run once:
pinMode(AoutPin, INPUT);
lcd.init();
lcd.backlight();
Serial.begin(9600);
lcd.setCursor(1,0);
lcd.print("DAI HOC CONG THUONG");
lcd.setCursor(2,1);
lcd.print("KHOA DIEN-DIEN TU");
lcd.setCursor(1,2);
lcd.print("TK HE THONG NHUNG!");
lcd.setCursor(3,3);
lcd.print("CO Value:");
}
void loop()
{
// put your main code here, to run repeatedly:
value = analogRead(AoutPin);
Serial.println(value);
lcd.setCursor(13,3);
lcd.print(value);
delay(1000);
}

 Chương trình tham khảo giao tiếp với LCD 2004 (Digital)
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
int DoutPin = 8;
int value;
void setup()
{
// put your setup code here, to run once:

-59-
pinMode(DoutPin, INPUT);
lcd.init();
lcd.backlight();
Serial.begin(9600);
lcd.setCursor(1,0);
lcd.print("DAI HOC CONG THUONG");
lcd.setCursor(2,1);
lcd.print("KHOA DIEN-DIEN TU");
lcd.setCursor(1,2);
lcd.prihnt("TK HE THONG NHUNG!");
lcd.setCursor(3,3);
lcd.print("CO Value:");
}
void loop()
{
// put your main code here, to run repeatedly:
value = digitalRead(DoutPin);
Serial.println(value);
lcd.setCursor(13,3);
lcd.print(value);
delay(1000);
}
Bài 3.4: Viết chương trình đọc tín hiệu từ cảm biến khí CO MQ - 7 và hiển thị thông tin
lên LCD OLED.
 Chương trình tham khảo giao tiếp với LCD OLED (Analog)
#include <Wire.h>
#include <SSD1306Ascii.h>
#include <SSD1306AsciiWire.h>
// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C
SSD1306AsciiWire oled;
int AoutPin = A0;
int value;
void setup()
{
// put your setup code here, to run once:
Wire.begin();
oled.begin(&Adafruit128x64, I2C_ADDRESS);
oled.set400kHz();
oled.setFont(Adafruit5x7);
uint32_t m = micros();
pinMode(AoutPin, INPUT);
oled.clear();
oled.println("Hello world!");
oled.println();
//oled.set2X();
oled.println("Lop thiet ke");
oled.println();
//oled.set2X();
oled.println("He thong nhung");
oled.println();
//oled.set2X();
oled.println("HUFI");
delay(5000);
oled.clear();
oled.println("KHOA DIEN-DIEN TU");
oled.println();
oled.println("GAS Value:");
oled.println();
}

void loop()

-60-
{
// put your main code here, to run repeatedly:
value = analogRead(AoutPin);
oled.clear();
oled.set1X();
oled.println("KHOA DIEN-DIEN TU");
oled.println();
oled.println("GAS Value:");
oled.println();
oled.set2X();
oled.print("");
oled.println(value);
delay(1000);
}

 Chương trình tham khảo giao tiếp với LCD OLED (Digital)
#include <Wire.h>
#include <SSD1306Ascii.h>
#include <SSD1306AsciiWire.h>
// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C
SSD1306AsciiWire oled;
int DoutPin = 8;
int value;
void setup()
{
// put your setup code here, to run once:
Wire.begin();
oled.begin(&Adafruit128x64, I2C_ADDRESS);
oled.set400kHz();
oled.setFont(Adafruit5x7);
uint32_t m = micros();
pinMode(DoutPin, INPUT);
oled.clear();
oled.println("Hello world!");
oled.println();
//oled.set2X();
oled.println("Lop thiet ke");
oled.println();
//oled.set2X();
oled.println("He thong nhung");
oled.println();
//oled.set2X();
oled.println("HUFI");
delay(5000);
oled.clear();
oled.println("KHOA DIEN-DIEN TU");
oled.println();
oled.println("GAS Value:");
oled.println();
}

void loop()
{
// put your main code here, to run repeatedly:
value = digitalRead(DoutPin);
oled.clear();
oled.set1X();
oled.println("KHOA DIEN-DIEN TU");
oled.println();
oled.println("GAS Value:");
oled.println();
oled.set2X();
oled.print("");
oled.println(value);

-61-
delay(1000);
}

3.3. Cảm biến MQ-135


Bài 3.5: Cho sơ đồ kết nối như hình 3.3. Viết chương trình đọc tín hiệu từ module cảm
biến không khí MQ - 135 và hiển thị thông tin lên LCD cho ở bảng 3.3
Bảng 3.3: Thông tin hiển thị LCD 2004
Add1 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E OF 10 11 12 13
R1 D A I H O C C O N G T H U O N G
Add2 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53
R2 K H O A D I E N - D I E N T U
Add3 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27
R3 T K H E T H O N G N H U N G !
Add4 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67
R4 G I A T R I K K :

 Sơ đồ mạch kết nối

Hình 3.3: Sơ đồ kết nối Arduino với cảm biến MQ - 135


 Chương trình tham khảo giao tiếp với LCD 2004 (Analog)
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
int AoutPin = A0;
int value;
void setup()
{
// put your setup code here, to run once:
pinMode(AoutPin, INPUT);
lcd.init();
lcd.backlight();
Serial.begin(9600);
lcd.setCursor(1,0);
lcd.print("DAI HOC CONG THUONG");
lcd.setCursor(2,1);
lcd.print("KHOA DIEN-DIEN TU");
lcd.setCursor(1,2);
lcd.print("TK HE THONG NHUNG!");
lcd.setCursor(1,3);
lcd.print("GIA TRI KK:");

-62-
}
void loop()
{
// put your main code here, to run repeatedly:
value = analogRead(AoutPin);
Serial.println(value);
lcd.setCursor(13,3);
lcd.print(value);
delay(1000);
}

 Chương trình tham khảo giao tiếp với LCD 2004 (Digital)
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
int DoutPin = 8;
int value;
void setup()
{
// put your setup code here, to run once:
pinMode(DoutPin, INPUT);
lcd.init();
lcd.backlight();
Serial.begin(9600);
lcd.setCursor(1,0);
lcd.print("DAI HOC CONG THUONG");
lcd.setCursor(2,1);
lcd.print("KHOA DIEN-DIEN TU");
lcd.setCursor(1,2);
lcd.prihnt("TK HE THONG NHUNG!");
lcd.setCursor(1,3);
lcd.print("GIA TRI KK:");
}
void loop()
{
// put your main code here, to run repeatedly:
value = digitalRead(DoutPin);
Serial.println(value);
lcd.setCursor(13,3);
lcd.print(value);
delay(1000);
}

Bài 3.6: Viết chương trình đọc tín hiệu từ module cảm biến không khi MQ - 135 và hiển
thị thông tin lên LCD OLED.
 Chương trình tham khảo giao tiếp với LCD OLED (Analog)
#include <Wire.h>
#include <SSD1306Ascii.h>
#include <SSD1306AsciiWire.h>
// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C
SSD1306AsciiWire oled;
int AoutPin = A0;
int value;
void setup()
{
// put your setup code here, to run once:
Wire.begin();
oled.begin(&Adafruit128x64, I2C_ADDRESS);
oled.set400kHz();
oled.setFont(Adafruit5x7);
uint32_t m = micros();
pinMode(AoutPin, INPUT);
oled.clear();

-63-
oled.println("Hello world!");
oled.println();
//oled.set2X();
oled.println("Lop thiet ke");
oled.println();
//oled.set2X();
oled.println("He thong nhung");
oled.println();
//oled.set2X();
oled.println("HUFI");
delay(5000);
oled.clear();
oled.println("KHOA DIEN-DIEN TU");
oled.println();
oled.println("GIA TRI KK:");
oled.println();
}

void loop()
{
// put your main code here, to run repeatedly:
value = analogRead(AoutPin);
oled.clear();
oled.set1X();
oled.println("KHOA DIEN-DIEN TU");
oled.println();
oled.println("GIA TRI KK:");
oled.println();
oled.set2X();
oled.print("");
oled.println(value);
delay(1000);
}

 Chương trình tham khảo giao tiếp với LCD OLED (Digital)
#include <Wire.h>
#include <SSD1306Ascii.h>
#include <SSD1306AsciiWire.h>
// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C
SSD1306AsciiWire oled;
int DoutPin = 8;
int value;
void setup()
{
// put your setup code here, to run once:
Wire.begin();
oled.begin(&Adafruit128x64, I2C_ADDRESS);
oled.set400kHz();
oled.setFont(Adafruit5x7);
uint32_t m = micros();
pinMode(DoutPin, INPUT);
oled.clear();
oled.println("Hello world!");
oled.println();
//oled.set2X();
oled.println("Lop thiet ke");
oled.println();
//oled.set2X();
oled.println("He thong nhung");
oled.println();
//oled.set2X();
oled.println("HUFI");
delay(5000);
oled.clear();

-64-
oled.println("KHOA DIEN-DIEN TU");
oled.println();
oled.println("GIA TRI KK:");
oled.println();
}

void loop()
{
// put your main code here, to run repeatedly:
value = digitalRead(DoutPin);
oled.clear();
oled.set1X();
oled.println("KHOA DIEN-DIEN TU");
oled.println();
oled.println("GIA TRI KK:");
oled.println();
oled.set2X();
oled.print("");
oled.println(value);
delay(1000);
}

3.4. Cảm biến AM-2315


Bài 3.7: Cho sơ đồ mạch như hình 3.4. Viết chương trình đọc tín hiệu từ module cảm
biến AM-2315 và hiển thị thông số đọc lên LCD
 Sơ đồ kết nối

Hình 3.4 Sơ đồ kết nối Arduino với module cảm biến AM - 2315

 Chương trình tham khảo kết nối LCD 20x04


#include <Wire.h>
#include <Adafruit_AM2315.h>
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4); // 0x27 là địa chỉ của lcd 16x2
// cam bien AM3215 voi LCD 20x04

Adafruit_AM2315 am2315;
// dia chi AM2315 la 0x5C
void setup() {
Serial.begin(9600);
Serial.println("AM2315 Test!");
Wire.begin();
Wire.beginTransmission(0x5C);// địa chỉ của ds1307
-65-
// Wire.write(0x07); //
// Wire.write(0x10); //
// Wire.endTransmission();
if (! am2315.begin()) {
Serial.println("Sensor not found, check wiring & pullups!");
while (1);
}
lcd.init(); // initialize the lcd
lcd.init();
// Print a message to the LCD.
lcd.backlight();
lcd.setCursor(3,0);
lcd.print(" HELLO WORLD !");
lcd.setCursor(2,2);
lcd.print("TK HE THONG NHUNG");
lcd.setCursor(2,1);
lcd.print("SENSOR AM 2315");
delay(5000);
}

void loop() {
Serial.print("Hum: "); Serial.println(am2315.readHumidity());
Serial.print("Temp: "); Serial.println(am2315.readTemperature());
lcd.setCursor(0,2);
lcd.print(" Hum: ");
lcd.setCursor(8,2);
lcd.print(am2315.readHumidity());
lcd.setCursor(0,3);
lcd.print(" Temp: ");
lcd.setCursor(8,3);
lcd.print(am2315.readTemperature());
delay(1000);
} #include <Wire.h>
#include <Adafruit_AM2315.h>
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4); // 0x27 là địa chỉ của lcd 16x2
// cam bien AM3215 voi LCD 20x04
Adafruit_AM2315 am2315;
// dia chi AM2315 la 0x5C
void setup() {
Serial.begin(9600);
Serial.println("AM2315 Test!");
Wire.begin();
Wire.beginTransmission(0x5C);// địa chỉ của ds1307
// Wire.write(0x07); //
// Wire.write(0x10); //
// Wire.endTransmission();
if (! am2315.begin()) {
-66-
Serial.println("Sensor not found, check wiring & pullups!");
while (1);
}
lcd.init(); // initialize the lcd
lcd.init();
// Print a message to the LCD.
lcd.backlight();
lcd.setCursor(3,0);
lcd.print(" HELLO WORLD !");
lcd.setCursor(2,2);
lcd.print("TK HE THONG NHUNG");
lcd.setCursor(2,1);
lcd.print("SENSOR AM 2315");
delay(5000);
}

void loop() {
Serial.print("Hum: "); Serial.println(am2315.readHumidity());
Serial.print("Temp: "); Serial.println(am2315.readTemperature());
lcd.setCursor(0,2);
lcd.print(" Hum: ");
lcd.setCursor(8,2);
lcd.print(am2315.readHumidity());
lcd.setCursor(0,3);
lcd.print(" Temp: ");
lcd.setCursor(8,3);
lcd.print(am2315.readTemperature());
delay(1000);
}
 Chương trình tham khảo kết nối LCD OLED
#include <Wire.h>
#include <Adafruit_AM2315.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C

SSD1306AsciiWire oled;
// cam bien AM3215 voi LCD OLED
Adafruit_AM2315 am2315;
// dia chi AM2315 la 0x5C
void setup() {
Serial.begin(9600);
Serial.println("AM2315 Test!");
Wire.begin();
Wire.beginTransmission(0x5C);// địa chỉ của ds1307
// Wire.write(0x07); //
// Wire.write(0x10); //
// Wire.endTransmission();
if (! am2315.begin()) {
-67-
Serial.println("Sensor not found, check wiring & pullups!");
while (1);
}
oled.begin(&Adafruit128x64, I2C_ADDRESS);
oled.set400kHz();
oled.setFont(Adafruit5x7);
Serial.begin(9600);

uint32_t m = micros();
oled.clear();
oled.println(" Hello world!");
oled.println();
//oled.set2X();
oled.println(" Lop thiet ke");
oled.println();
//oled.set2X();
oled.println(" He thong nhung");
oled.println();
//oled.set2X();
oled.println(" HUFI");
delay(5000);
oled.clear();
oled.println(" Dien - Dien tu");
oled.println();
//oled.set2X();
oled.println(" CAM BIEN AM-2315:");
oled.println();
delay(5000);
}

void loop() {
Serial.print("Hum: "); Serial.println(am2315.readHumidity());
Serial.print("Temp: "); Serial.println(am2315.readTemperature());
oled.clear();
oled.set1X();
oled.println(" Dien - Dien tu");
oled.println();

oled.println(" CAM BIEN AM - 2315: ");


oled.println(" ");
oled.set2X();
oled.print(" Hum: ");
oled.println(int(am2315.readHumidity()));
oled.print(" Temp: ");
oled.println(int(am2315.readTemperature()));
delay(1000);
}
3.5. Cảm biến AM-312

-68-
Bài 3.8: Cho sơ đồ mạch như hình 3.5. Viết chương trình đọc tín hiệu từ module cảm
biến AM-312 và hiển thị thông số đọc lên LCD
 Sơ đồ kết nối

Hình 3.5: Sơ đồ kết nối Arduino với cảm biến AM-312


 Chương trình tham kết nối LCD 20x04
* Kết nối cam bien AM-312 va LCD 20x04
* VCC ----- 5V (Arduino)
* OUT ----- 3 (Arduino)
* GND ----- GND (Arduino)
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and
2 line display
int sensor=3;
void setup()
{
Serial.begin(9600);
lcd.init(); // initialize the lcd
lcd.init();
// Print a message to the LCD.
lcd.backlight();
lcd.setCursor(3,0);
lcd.print(" HELLO WORLD !");
lcd.setCursor(2,2);
lcd.print("TK HE THONG NHUNG");
lcd.setCursor(2,1);
lcd.print("SENSOR AM 312");
pinMode(sensor,INPUT_PULLUP);
}
void loop()
{
Serial.println(digitalRead(3));
if (digitalRead(sensor)==HIGH)
{
lcd.setCursor(2,3);
lcd.print("CO CHUYEN DONG ");
}
else if (digitalRead(sensor)==LOW)

-69-
{
lcd.setCursor(2,3);
lcd.print("HET CHUYEN DONG ");
}
delay(1000);
}
 Chương trình tham kết nối LCD OLED
/*
* Kết nốicam bien AM-312 va LCD OLED
* VCC ----- 5V (Arduino)
* OUT ----- 3 (Arduino)
* GND ----- GND (Arduino)
*/
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C

SSD1306AsciiWire oled;
int sensor=3;
void setup()
{
Wire.begin();
oled.begin(&Adafruit128x64, I2C_ADDRESS);
oled.set400kHz();
oled.setFont(Adafruit5x7);
Serial.begin(9600);
uint32_t m = micros();
oled.clear();
oled.println(" Hello world!");
oled.println();
//oled.set2X();
oled.println(" Lop thiet ke");
oled.println();
//oled.set2X();
oled.println(" He thong nhung");
oled.println();
//oled.set2X();
oled.println(" HUFI");
delay(5000);
oled.clear();
oled.println(" Dien - Dien tu");
oled.println();
//oled.set2X();
oled.println("cam bien chuyen dong:");
oled.println();
}
void loop()
{
-70-
Serial.println(digitalRead(3));
if (digitalRead(sensor)==HIGH)
{
oled.clear();
oled.set1X();
oled.println(" Dien - Dien tu");
oled.println();
//oled.set2X();
oled.println(" CAM BIEN CHUYEN DONG: ");
oled.println();
oled.set2X();
oled.print(" ");
oled.println(" CO");
delay(1000); }
else if (digitalRead(sensor)==LOW) {
oled.clear();
oled.set1X();
oled.println(" Dien - Dien tu");
oled.println();
//oled.set2X();
oled.println(" CAM BIEN CHUYEN DONG: ");
oled.println();
oled.set2X();
oled.print(" ");
oled.println(" KHONG ");
delay(1000); }
delay(1000);}
3.6. Cảm biến TCS3200
Bài 3.9: Cho sơ đồ mạch như hình 3.5. Viết chương trình đọc tín hiệu từ module cảm
biến TCS-3200 và hiển thị thông số đọc lên LCD
 Sơ đồ kết nối

Hình 3.6: Sơ đồ kết nối Arduino với module cảm biến TCS 3200
 Chương trình tham khảo

-71-
/*
// TCS230 color recognition sensor
// Sensor connection pins to Arduino are shown in comments
// project ket hop Thay Huy, co the hoc 5 mau, cho phep phat hien mau da hoc, thiet
lap muc 0 o ngo ra
Color Sensor Arduino
----------- --------
VCC 5V
GND GND
s0 8
s1 9
s2 12
s3 11
OUT 10
OE GND
*/
#include <EEPROM.h>
const int s0 = 8;
const int s1 = 9;
const int s2 = 12;
const int s3 = 11;
const int out = 10;

int led=13;
int buttonPin=A2;

// Variables
int red = 0;
int green = 0;
int blue = 0;
void color()
{
digitalWrite(s2, LOW);
digitalWrite(s3, LOW);
//count OUT, pRed, RED
red = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
digitalWrite(s3, HIGH);
//count OUT, pBLUE, BLUE
green = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
digitalWrite(s2, HIGH);
//count OUT, pGreen, GREEN
blue = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
}
void setup()
{
// xoa_eeprom();
Serial.begin(9600);
pinMode(s0, OUTPUT);
pinMode(s1, OUTPUT);
-72-
pinMode(s2, OUTPUT);
pinMode(s3, OUTPUT);
pinMode(out, INPUT);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(led, OUTPUT);

digitalWrite(s0, HIGH);
digitalWrite(s1, HIGH);
}
void loop()
{
color();

Serial.println("ban dang doc gia tri mau ");


Serial.print(" R: ");
Serial.print(red, DEC);
Serial.print(" G: ");
Serial.print(green, DEC);
Serial.print(" B: ");
Serial.print(blue, DEC);
Serial.println();
delay(2000);

-73-
Trường ĐH Công thương
TP.HCM BÀI 4:
Khoa: CN Điện – Điện tử LẬP TRINH ĐIỀU KHIỂN ĐỘNG CƠ
Bộ môn: Điện tử
A. MỤC TIÊU
Học xong bài này sinh viên có khả năng:
- Nắm được các thành phần của kit TH Thiết kế hệ thống nhúng, chức năng và hoạt
động của từng thành phần, sự giao tiếp của chúng với nhau trong kit.
- Nắm được sơ đồ phần cứng khối xuất nhập cơ bản và biết kết nối giữa khối CPU và
các ngoại vi.
- Biết cách biên dịch, biết cách sửa lỗi chương trình.
B. NỘI DUNG THỰC HÀNH
4.1. Điều khiển động cơ Servo
 Động cơ servo SG90
Có kích thước nhỏ, là loại được sử dụng nhiều nhất để làm các mô hình nhỏ hoặc các
cơ cấu kéo không cần đến lực nặng.
Động cơ servo SG90 180 độ có tốc độ phản ứng nhanh, các bánh răng được làm
bằng nhựa nên cần lưu ý khi nâng tải nặng vì có thể làm hư bánh răng, động cơ RC Servo
9G có tích hợp sẵn Driver điều khiển động cơ bên trong nên có thể dễ dàng điều khiển
góc quay bằng phương pháp điều độ rộng xung PWM.
 Thông số kỹ thuật
 Điện áp hoạt động: 4.8-5VDC
 Tốc độ: 0.12 sec/ 60 deg (4.8VDC)
 Lực kéo: 1.6 Kg.cm
 Kích thước: 21x12x22mm
 Trọng lượng: 9g.
Bài 4.1: Cho sơ đồ kết nối như hình 4.1. Viết chương trình điều khiển động cơ servo.
 Sơ đồ kết nối

Hình 4.1: Sơ đồ mạch Arduino điều khiển động cơ Servo


-74-
 Chương trình tham khảo
// Include the Servo library
#include <Servo.h>
// Declare the Servo pin
int servoPin = 9;
// Create a servo object
Servo Servo1;
void setup() {
// We need to attach the servo to the used pin number
Servo1.attach(servoPin);
}
void loop(){
// Make servo go to 0 degrees
Servo1.write(0);
delay(1000);
// Make servo go to 90 degrees
Servo1.write(90);
delay(1000);
// Make servo go to 180 degrees
Servo1.write(180);
delay(1000);
}
Bài 4.2: Cho sơ đồ kết nối như hình 4.1. Viết chương trình điều khiển động cơ servo
quay từ 00 đến 1800 và ngược lại từ 1800 về 00.
 Chương trình tham khảo
#include<Servo.h>
Servo servo_test;
int angle = 0;
void setup()
{
// put your setup code here, to run once:
servo_test.attach(9);
}

void loop()
{
// put your main code here, to run repeatedly:
for(angle=0;angle<180;angle += 1)
{
servo_test.write(angle);
delay(15);
}
delay(1000);
for(angle=180;angle>=1;angle -= 5)
{
servo_test.write(angle);
delay(5);
}
delay(1000);
}
Bài 4.3: Cho sơ đồ kết nối như hình 4.2. Viết chương trình Arduino sẽ đọc điện áp trên
chân giữa của biến trở và điều chỉnh vị trí của trục động cơ Servo.
 Sơ đồ kết nối mạch

-75-
Hình 4.2: Sơ đồ mạch Arduino đọc điện áp và điều khiển vị trí trục động cơ Servo
 Chương trình tham khảo
#include<Servo.h>
Servo servo_test;
int vrPin = A0;
int angle = 0;
void setup()
{
// put your setup code here, to run once:
servo_test.attach(9);
}
void loop()
{
// put your main code here, to run repeatedly:
angle = analogRead(vrPin);
angle = map(angle, 0, 1023, 0, 179);
servo_test.write(angle);
delay(5);
}

4.2. Điều khiển động cơ DC


 Module điều khiển động cơ L298N - cầu H để điều khiển động cơ DC

Hình 4.3: Module điều khiển động cơ L298N


Bảng 4.1: Chức năng các chân của module L298N

-76-
PIN Chức năng
Pin powers the IC’s internal H-Bridge, which drives the motors.
VCC
Power This pin accepts input voltages ranging from 5 to 12V
Pins GND GND is the common ground pin
VS is used to power the logic circuitry within the L298N IC, and
VS
can range between 5V and 7V.
Output OUT1 and The output channels of the L298N motor driver, OUT1 and OUT2
Pins OUT2 for motor A
OUT3 and The output channels of the L298N motor driver, OUT3 and OUT4
OUT4 for motor B
Direction IN1 & IN2 The IN1 & IN2 pins control the spinning direction of motor A
Control
Pins IN3 & IN4 The IN3 & IN4 pins control the spinning direction of motor B
ENA The speed control pin ENA is used to turn on/off the motors and
Speed control their speed.
Control ENB The speed control pin ENB is used to turn on/off the motors and
Pins control their speed.
Bảng 4.2: Bảng hoạt động của động cơ DC
Input2 Input1 Spinning Direction
0 0 Motor OFF
0 1 Forward
1 0 Backward
1 1 Motor OFF
Bài 4.4: Cho sơ đồ mạch như hình 4.4. Viết chương trình điều khiển tốc độ và hướng
quay của động cơ DC.
 Sơ đồ kết nối

Hình 4.4: Sơ đồ kết nối Arduino điều khiển động cơ DC


 Chương trình tham khảo
//Motor A connections

-77-
int ENA = 9;
int IN1 = 8;
int IN2 = 7;
//Motor B connections
int ENB = 3;
int IN3 = 4;
int IN4 = 5;
void setup()
{
// Set all the motor control
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
// Turn OFF motors - Initial
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
}

void loop()
{
// put your main code here, to run repeatedly:
directioncontrol();
delay(1000);
speedcontrol();
delay(1000);
}
void directioncontrol()
{
//Set motors to maximum speed
//For PWM maximum possible values are 0-255
analogWrite(ENA, 255);
analogWrite(ENB, 255);
//Turn on motor A & B
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
delay(2000);
//Now change motor directions
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
delay(2000);
//Turn off motors
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
}
void speedcontrol()
{
//Turn on motors
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
// Accelerate from zero to maximum speed
for(int i=0; i<256;i++)
{

-78-
analogWrite(ENA,i);
analogWrite(ENB,i);
delay(20);
}
// Decelerate from maximum speed to zero
for(int i = 255; i >= 0; --i)
{
analogWrite(ENA,i);
analogWrite(ENB,i);
delay(20);
}
// Now turn off motors
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
}

 Chương trình tham khảo


#define IN1 7
#define IN2 6
#define IN3 5
#define IN4 4
#define MAX_SPEED 255 //từ 0-255
#define MIN_SPEED 0
void setup()
{
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
}

void motor_1_Dung() {
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
}

void motor_2_Dung() {
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
}

void motor_1_Tien(int speed) { //speed: từ 0 - MAX_SPEED


speed = constrain(speed, MIN_SPEED, MAX_SPEED);//đảm báo giá trị nằm trong
một khoảng từ 0 - MAX_SPEED - http://arduino.vn/reference/constrain
digitalWrite(IN1, HIGH);// chân này không có PWM
analogWrite(IN2, 255 - speed);
}

void motor_1_Lui(int speed) {


speed = constrain(speed, MIN_SPEED, MAX_SPEED);//đảm báo giá trị nằm trong
một khoảng từ 0 - MAX_SPEED - http://arduino.vn/reference/constrain
digitalWrite(IN1, LOW);// chân này không có PWM

-79-
analogWrite(IN2, speed);
}

void motor_2_Tien(int speed) { //speed: từ 0 - MAX_SPEED


speed = constrain(speed, MIN_SPEED, MAX_SPEED);//đảm báo giá trị nằm trong
một khoảng từ 0 - MAX_SPEED - http://arduino.vn/reference/constrain
analogWrite(IN3, speed);
digitalWrite(IN4, LOW);// chân này không có PWM
}

void motor_2_Lui(int speed) {


speed = constrain(speed, MIN_SPEED, MAX_SPEED);//đảm báo giá trị nằm trong
một khoảng từ 0 - MAX_SPEED - http://arduino.vn/reference/constrain
analogWrite(IN4, 255 - speed);
digitalWrite(IN3, HIGH);// chân này không có PWM
}

void loop()
{
motor_1_Tien(MAX_SPEED); // motor 1 tiến
delay(5000);//tiến 5 s
motor_2_Lui(MAX_SPEED); //motor 2 lùi
// motor 1 vẫn tiến
delay(2000);//tiến 2 s
motor_1_Dung();
motor_2_Dung();
delay(10000);//dừng 10s
}
4.3. Điều khiển động cơ bước

 Sơ đồ kết nối

-80-
Hình 4.3 Sơ đồ kết nối Arduino điều khiển động cơ Servo
Chương trình tham khảo điều khiển động cơ bước :
// chuong trinh dieu khien dong co buoc su dung tb6600
// cac chan pul+, en+, dir+ duoc noi nguon san
const int ena = 2; //habilita o motor
const int dir = 3; //determina a direção
const int pul = 4; //executa um passo
const int intervalo = 350; //intervalo entre as
// mudanças de estado do pulso
boolean pulso = LOW; //estado do pulso

void setup()
{
pinMode(ena, OUTPUT);
pinMode(dir, OUTPUT);
pinMode(pul, OUTPUT);
digitalWrite(ena, HIGH); //habilita em low invertida
digitalWrite(dir, HIGH); // low CW / high CCW
digitalWrite(pul, LOW); //borda de descida
}
void loop()
{
pulso = !pulso; //inverte o estado da variável
digitalWrite(pul, pulso); //atribui o novo estado à porta
delayMicroseconds(intervalo);
}
delay(2000);
}
4.1 Xây dựng ứng dụng ghép nối hệ thống cảm biến điều khiển valve
4.1.1 Hệ thống thu thập nồng đồ khí GAS – cảnh báo – điều khiển valve xử lý
-81-
a. Thiết lập lưu đồ giải thuật
b. Viết chương trình thực thi
c. Tối ưu hóa chương trình
4.1.2 Hệ thống thu thập dữ liệu màu dùng TCS3200 –điều khiển valve xử lý (hệ
thống trộn)
a. Thiết lập lưu đồ giải thuật
b. Viết chương trình thực thi
c. Tối ưu hóa chương trình

-82-
Trường ĐH Công thương
BÀI 5:
TP.HCM
LẬP TRINH GIAO TIẾP
Khoa: CN Điện – Điện tử
Bộ môn: Điện tử KHỐI TRUYỀN NHẬN

A. MỤC TIÊU
Học xong bài này sinh viên có khả năng:
- Nắm được các thành phần của kit TH Thiết kế hệ thống nhúng, chức năng và hoạt
động của từng thành phần, sự giao tiếp của chúng với nhau trong kit.
- Nắm được sơ đồ phần cứng khối xuất nhập cơ bản và biết kết nối giữa khối CPU và
các ngoại vi.
- Biết cách biên dịch, biết cách sửa lỗi chương trình. Viết được chương trình, biên dịch,
để thu thập và hiển thị giá trị cảm biến qua RF, Bluetooth, Module Sim.
B. NỘI DUNG THỰC HÀNH
5.1. Lập trình giao tiếp nối tiếp điều khiển relay từ màn hình Serial
Hình ảnh kết nối:

Hình 5.1: Kết nối Arduino với Relay


Chương trình tham khảo:
String inputString = ""; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
int re_1 = 11;
int re_2 = 10;
int re_3 = 9;
-83-
int re_4 = 8;
int codulieu;
void setup() {
pinMode(re_1, OUTPUT);
pinMode(re_2, OUTPUT);
pinMode(re_3, OUTPUT);
pinMode(re_4, OUTPUT);
digitalWrite(re_1, HIGH);
digitalWrite(re_2, HIGH); digitalWrite(re_3, HIGH);
digitalWrite(re_4, HIGH); codulieu==0;
Serial.begin(9600);
inputString.reserve(200);
Serial.println("testing"); }
void loop() {
if (stringComplete) {
inputString = "";
stringComplete = false; }
if (codulieu==1)
{
if (inputString =="1") {
digitalWrite(re_1, !digitalRead(re_1)); }
else if (inputString =="2") {
digitalWrite(re_2, !digitalRead(re_2)); }
else if (inputString =="3") {
digitalWrite(re_3, !digitalRead(re_3)); }
else if (inputString =="4") {
digitalWrite(re_4, !digitalRead(re_4)); }
else Serial.println("ky tu truyen khong hop le");
inputString = "";
codulieu=0; }}
void serialEvent() {
while (Serial.available()) { codulieu=1;
char inChar = (char)Serial.read();
inputString += inChar;
if (inChar == '¥n') {
stringComplete = true; } }}
-84-
5.2. Lập trình giao tiếp nối tiếp điều khiển relay hiển thị trạng thái relay trên
LCD
Hình ảnh kết nối:

Hình 5.2 Kết nối relay và LCD với Arduino


Chương trình tham khảo:
/*
* Hi-Tech UART
* BOARD RELAY tich cuc muc 0
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3f,20,4); // set the LCD address to 0x27 for a 16 chars and 2
line display
String inputString = ""; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
int re_1 = 11;
int re_2 = 10;
int re_3 = 9;
int re_4 = 8;
int codulieu;
-85-
void setup()
{
Serial.begin(9600);
pinMode(re_1, OUTPUT);
pinMode(re_2, OUTPUT);
pinMode(re_3, OUTPUT);
pinMode(re_4, OUTPUT);
digitalWrite(re_1, HIGH);
digitalWrite(re_2, HIGH);
digitalWrite(re_3, HIGH);
digitalWrite(re_4, HIGH);
codulieu==0;

// reserve 200 bytes for the inputString:


inputString.reserve(200);
Serial.println("testing");
lcd.init(); // initialize the lcd
lcd.init();
// Print a message to the LCD.
lcd.backlight();
lcd.setCursor(3,0);
lcd.print("Arduino Hi-tech");
lcd.setCursor(0,1);
lcd.print(" 0904792430 ");
lcd.setCursor(2,2);
lcd.print(" LCD 2004 Relay");
i=20;
}
void loop() {
// print the string when a newline arrives:
if (stringComplete) {
inputString = "";
stringComplete = false;
}
if (codulieu==1)
{
-86-
if (inputString =="1")
{
digitalWrite(re_1, !digitalRead(re_1));
lcd.setCursor(2,3);
lcd.print(" Relay 1 duoc tac dong "); }
else if (inputString =="2")
{
digitalWrite(re_2, !digitalRead(re_2));
lcd.setCursor(2,3);
lcd.print(" Relay 2 duoc tac dong ");
//Serial.println("tat led"); }
else if (inputString =="3")
{
digitalWrite(re_3, !digitalRead(re_3));
lcd.setCursor(2,3);
lcd.print(" Relay 3 duoc tac dong ");
//Serial.println("tat led"); }
else if (inputString =="4")
{
digitalWrite(re_4, !digitalRead(re_4));
lcd.setCursor(2,3);
lcd.print(" Relay 1 duoc tac dong ");
//Serial.println("tat led"); }
else Serial.println("ky tu truyen khong hop le");
inputString = "";
codulieu=0; }}
void serialEvent() {
while (Serial.available()) {
codulieu=1;
char inChar = (char)Serial.read();
inputString += inChar;
if (inChar == '¥n') {
stringComplete = true; }
}
}

-87-
5.3. Lập trình giao tiếp kết nối mạch đọc RFID
Hình ảnh thực tế:

Hình 5.3 Module đọc thẻ RFID 125KHZ


Hình ảnh kết nối:

Hình 5.4: Kết nối mạch đọc thẻ RFID với ARduino
Chương trình tham khảo:
#include <SoftwareSerial.h>
int val = 0; char code[12];
int bytesread = 0; int i;
SoftwareSerial RFID(2, 3); // RX and TX
void setup() {
Serial.begin(9600); // Hardware serial for Monitor 2400bps
pinMode(13,OUTPUT); digitalWrite(13, LOW); // Activate the RFID reader
RFID.begin(9600); Serial.println("testing"); }
void loop() {
if (RFID.available() >0)
{ i = RFID.read();

-88-
5.4 Truyền dữ liệu không dây qua RF cơ bản
Hình ảnh thực tế:

Hình 5.5: Module nhận dữ liệu RF


Hình ảnh kết nối:

Hình 5.6: Kết nối module RF nhận với Arduino


Chương trình tham khảo:
#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
void setup() {
Serial.begin(9600);
mySwitch.enableReceive(0); // Receiver on interrupt 0 => that is pin #2
}
void loop() {
if (mySwitch.available()) {
int value = mySwitch.getReceivedValue();
if (value == 0) {

-89-
Serial.print("Unknown encoding");
} else {
Serial.print("Received ");
Serial.print( mySwitch.getReceivedValue() );
Serial.print(" / ");
Serial.print( mySwitch.getReceivedBitlength() );
Serial.print("bit ");
Serial.print("Protocol: ");
Serial.println( mySwitch.getReceivedProtocol() );
}
mySwitch.resetAvailable();
}}
5.5. Truyền dữ liệu không dây qua module RF tích hợp UART
Hình ảnh thực tế:

Hình 5.7: Module RF chuẩn UART (500m)


Hình ảnh kết nối:

Hình 5.8: Kết nối module RF chuẩn UART với Arduino


Chương trình tham khảo:
/* ARDUINO HI-TECH
* chuong trinh buoi hoc 7_2
-90-
* truyen nhan nhieu noi dung
* dinh dia chi cac noi dung cung truyen, giai quyet dia chi
* ket noi UART ao
* ung dung giao tiep RF UART, SIM, GPS,,,,
*/
#include <Arduino.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
const int NUMBER_OF_FIELDS = 5; // how many comma-separated fields we expect
int fieldIndex = 0; // the current field being received
int values[NUMBER_OF_FIELDS]; // array holding values for all the fields
// The amount of time (in milliseconds) between tests
#define TEST_DELAY 2000
uint8_t data[4] ;
int codulieu;
String inString = ""; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
int led = 13;
void setup()
{
pinMode(led, OUTPUT);
Serial.begin(9600);
mySerial.begin(9600);
digitalWrite(led,LOW);
Serial.println("Lop hoc Arduino Hi-tech");
}
void loop()
{
if( mySerial.available()) {
for(fieldIndex = 0; fieldIndex < 5; fieldIndex ++)
{
values[fieldIndex] = mySerial.parseInt(); // get a numeric value
}
Serial.print("values[0]:");
Serial.println(values[0]);
Serial.print("values[1]:");
-91-
Serial.println(values[1]);
Serial.print("values[2]:");
Serial.println(values[2]);
Serial.print("values[3]:");
Serial.println(values[3]);
Serial.print("values[4]:");
Serial.println(values[4]);
if (values[0]==1) {Serial.println(" da truyen dung dia chi");}
fieldIndex = 0; // ready to start over
}
}

-92-
Trường ĐH Công thương BÀI 6:
TP.HCM LÀM QUEN VỚI
Khoa: CN Điện – Điện tử HỆ ĐIỀU HÀNH RASPBIAN
Bộ môn: Điện tử

A. MỤC TIÊU
Học xong bài này sinh viên có khả năng:
- Nắm được các thành phần của kit TH Thiết kế hệ thống nhúng, chức năng và hoạt
động của từng thành phần, sự giao tiếp của chúng với nhau trong kit.
- Nắm được sơ lược về hệ điều hành Raspbian.
B. NỘI DUNG THỰC HÀNH
6.1 Giới thiệu về Raspberry và hệ điều hành Raspbian
Raspbian là một hệ điều hành máy tính dựa trên Debian cho Raspberry Pi. Có một
số phiên bản của Raspbian bao gồm Raspbian Stretch và Raspbian Jessie. Từ năm 2015,
nó đã được Raspberry Pi Foundation chính thức cung cấp như là hệ điều hành chính cho
gia đình máy tính bảng đơn Raspberry Pi. Raspbian được tạo ra bởi Mike Thompson và
Peter Green như một dự án độc lập. Bản dựng ban đầu được hoàn thành vào tháng 6 năm
2012. Hệ điều hành vẫn đang được phát triển tích cực. Raspbian được tối ưu hóa cao cho
các CPU ARM hiệu suất thấp của dòng Raspberry Pi.
Raspbian sử dụng PIXEL, Pi I đã xác nhận X -Window Enviroment, Lightweight
là môi trường máy tính để bàn chính của nó kể từ bản cập nhật mới nhất. Nó bao gồm
một môi trường máy tính để bàn LXDE được sửa đổi và trình quản lý cửa sổ xếp chồng
Openbox với một chủ đề mới và một vài thay đổi khác. Sự phân bố được xuất xưởng với
một bản sao của chương trình máy tính đại số Mathematica và một phiên bản
của Minecraft gọi Minecraft Pi cũng như một phiên bản nhẹ của Chromium như của
phiên bản mới nhất.
6.2 Cách cài đặt hệ điều hành Raspbian
6.2.1 Chuẩn bị phần cứng
- Một thẻ Micro SD Card tối thiểu 8GB loại class 10
- Một nguồn điện 5V - 1A
- Một màn hình giao tiếp HDMI
- Một bàn phím.
- Một chuột vi tính
6.2.2 Cài đặt hệ điều hành trên Raspberry
- Tải hệ điều hành tại đường dẫn: https://downloads.raspberrypi.org/raspbian_latest
- Định dạng lại thẻ nhớ

-93-
Hình 6.1 Định dạng thẻ nhớ
- Sử dụng chương trình Win 32Disklmager để ghi file ảnh hệ điều hành lên thẻ nhớ

Hình 6.2 Ghi file ảnh


- Giao diện khởi động hệ điều hành Raspbian

Hình 6.3 Giao diện màn hình desktop Raspbian

-94-
6.3 Các câu lệnh cơ bản trên Raspbian
- apt-get update: cập nhật phiên bản Raspbian. Lệnh này còn được dùng nếu bạn đổi
Repository của Raspbian.
- apt-get upgrade: Nâng cấp toàn bộ các gói phần mềm đã cài đặt trên Raspbian.
- clear: Xóa màn hình terminal và các lệnh bạn đã thực thi trước đó. Lưu ý, nó chỉ xóa
màn hình đi cho gọn, sạch mà thôi.
- date: Hiển thị ngày giờ hiện tại.
- find / -name example.txt: Tìm kiếm các file có tên là example.txt trên toàn hệ thống.
- nano example.txt: Mở file example.txt trong trình biên tập text Nano – Một trình biên tập
text (text editor) quen thuộc của Linux
- poweroff: Tắt Raspberry Pi
- raspi-config: Mở menu thiết lập cấu hình Raspberry Pi hay Raspbian.
- reboot: Khởi động lại Raspberry Pi.
- shutdown -h now: Tắt Raspberry Pi ngay lập tức
- shutdown -h 01:22: Tắt Raspberry Pi vào lúc 1:22 AM.
- startx: Mở giao diện đồ họa của Raspbian (nếu bạn đang ở giao diện console)
- cat example.txt: Hiển thị nội dung của file example.txt.
- cd /abc/xyz: Di chuyển từ thư mục hiện tại sang thư mục /abc/xyz.
- cp XXX: Copy file hoặc thư mục XXX và paste vào vị trí mới. Ví dụ: cp examplefile.txt
/home/pi/office/ sẽ copy file examplefile.txt trong folder hiện tại đến /home/pi/office.
Nếu file cần copy không ở folder hiện tại thì ghi rõ vị trí file cần copy (ví dụ cp
/home/pi/documents/examplefile.txt /home/pi/office/ sẽ copy file examplefile.txt trong
folder documents sang folder office).
- ls -la: Hiển thị danh sách các file trong folder với các thông tin file size, ngày
sửa, quyền hạn của file.
- mkdir example_directory: Tạo folder tên example_directory bên trong folder hiện tại.
- mv XXX: Nội dung cú pháp lệnh như lệnh cp nhưng mục đích của lệnh mv là move file
thay vì copy..
- rm example.txt: Xóa file example.txt.
- rmdir example_directory: Xóa thư mục example_directory (nếu thư mục này đang
trống).
- touch: Tạo file trắng mới trong folder hiện tại. Có thể sử dụng các lệnh khác như nano,
vi.
- ifconfig: Kiểm tra tình trạng mạng hiện tại trên Raspberry Pi. Bạn có thể biết IP của
Raspberry Pi nếu đang kết nối.
- iwconfig: Kiểm tra adapter không dây nào đang chạy.
- iwlist wlan0 scan: Hiển thị danh sách các mạng wifi trong khu vực.
- iwlist wlan0 scan | grep ESSID: Hiển thị danh sách các mạng wifi trong khu vực có tên
theo yêu cầu.

-95-
- nmap: Quét mạng và hiển thị các thiết bị đang kết nối, cổng, giao thức, trạng thái của hệ
thống, địa chỉ MAC và các thông tin khác.
- ping: Kiểm tra kết nối giữa các thiết bị trong mạng.
- wget http://www.website.com/example.txt: Tải file example.txt từ trên mạng về và lưu
vào folder hiện tại.
- cat /proc/meminfo: Hiển thị thông tin chi tiết về RAM của Raspberry Pi.
- cat /proc/partitions: Hiển thị thông tin các phân vùng của thẻ nhớ hoặc ổ cứng hoặc
USB cắm trên Raspberry Pi.
- cat /proc/version: Hiển thị phiên bản Raspberry Pi đang sử dụng
- df -h: Hiển thị thông tin dung lượng lưu trữ còn trống.
- dpkg –get-selections | grep XXX: Hiển thị các gói phần mềm đã cài đặt có liên quan đến
từ khóa XXX.
- dpkg –get-selections: Hiển thị toàn bộ các phần mềm đã cài trên Raspberry Pi.
- free: Hiển thị lượng RAM còn trống.
- hostname -I: Hiển thị IP củaRaspberry Pi.
- lsusb: Liệt kê các thiết bị USB đang cắm vào Raspberry Pi.
- UP key: Bấm phím mũi tên lên sẽ hiển thị các lệnh đã từng chạy trước đây.
- vcgencmd measure_temp: Hiển thị thông tin nhiệt độ GPU. Chi tiết có thể tham khảo
thêm Kiểm tra nhiệt độ Raspberry Pi.
- vcgencmd get_mem arm && vcgencmd get_mem gpu: Hiển thị thông tin RAM của CPU
và GPU.

-96-

You might also like