

 !"#
$$$
!!
%&'(
)*
+(,
! -!.&/#
01234052678239:2* GV Nguyễn Trung Dũng
6;<* Điện tử và Kỹ thuật Máy tính
=>8?* DHKM16A1HN
6@AB6CD60E2* Nhóm 2
Hà Nội, ngày 21 tháng 10 năm 2025
F -G%
STT Họ và tên Mã sinh viên Ghi chú
1 Trần Thanh Nhàn 22174800055 Nhóm trưởng
2 Nguyễn Thị Hùng Anh 22174800049 Thành viên
3 Phạm Công Bằng 22174800059 Thành viên
THỰC HÀNH LẬP TRÌNH DI ĐỘNG GVHD: Vũ Trung Dũng
&H 
Nhóm sinh viên xin gửi lời cảm ơn chân thành tới thầy Trung Dũng giảng
viên môn Thực hành Lập trình di động đã tận tình giảng dạy, hướng dẫn hỗ trợ
chúng em trong suốt quá trình học tập và thực hiện đề tài.
Xin chân thành cảm ơn Khoa Điện tử K thuật máy tính, Trường Đại học
Kinh tế Kỹ thuật Công nghiệp (UNETI) đã tạo điều kiện về sở vật chất, trang
thiết bị và môi trường học tập thuận lợi để nhóm có thể hoàn thành tốt đề tài này.
Cuối cùng, nhóm xin gửi lời cảm ơn đến các thành viên trong nhóm đã luôn tích
cực, hỗ trợ và cùng nhau hoàn thành từng phần của đề tài đúng tiến độ.
Nhóm em xin chân thành cảm ơn!
1
THỰC HÀNH LẬP TRÌNH DI ĐỘNG GVHD: Vũ Trung Dũng
&FI
Trong thời đại công nghiệp hóa, đô thị hóa phát triển mạnh mẽ, vấn đề ô nhiễm
không khí ngày càng trở nên nghiêm trọng ảnh hưởng trực tiếp đến sức khỏe con
người.mViệc xây dựng các hệ thống giám sát môi trường thông minh, khả năng đo
và hiển thị chất lượng không khí theo thời gian thực, đang trở thành một hướng nghiên
cứu thiết thực và có ý nghĩa.
Nhằm vận dụng các kiến thức đã học về lập trình Android, mạng máy tính và hệ
thống IoT, nhóm chúng em thực hiện đề tài J60KBLKM239N2330OAPOBD6QB>7R23
L6S23L6TU. Đề tài tập trung vào việc xây dựng một ứng dụng di động thể nhận dữ
liệu từ vi điều khiển ESP32 thông qua mạng WiFi, hiển thị thông số môi trường trực
quan, đồng thời cảnh báo khi vượt ngưỡng cho phép.
Thông qua quá trình thực hiện, nhóm đã hội củng cố kiến thức lập trình,
kỹ năng làm việc nhóm, duy logic khả năng kết hợp giữa phần cứng phần
mềm trong một hệ thống IoT hoàn chỉnh. Mặc đã rất cố gắng, nhưng do thời gian
kiến thức còn hạn chế, báo cáo không tránh khỏi thiếu sót. Nhóm rất mong nhận
được ý kiến đóng góp của thầy cô để đề tài được hoàn thiện hơn.
2
THỰC HÀNH LẬP TRÌNH DI ĐỘNG GVHD: Vũ Trung Dũng
,&,
&H VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVW
&FIVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX
,&,VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVY
( ,'HVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVZ
W*[\))VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV]
WVWV&^9;D6_2`aBb0VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV]
WVXV NDB05c4b?6dA40De<`aBb0VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV]
1.2.1. Mục tiêu chung........................................................................................6
1.2.2. Mục tiêu cụ thể.........................................................................................6
1.2.3. Phạm vi thực hiện....................................................................................6
WVYVf236g<De<`aBb0VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVh
1.3.1. Ý nghĩa thực tiễn......................................................................................7
1.3.2. Ý nghĩa học thuật.....................................................................................7
WViVjD`0kA2l0mnBDe<6EB6o23VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVp
X*qr"(%sVVVVVVVVVVVVVVVVVVVVVVVVVVVWt
XVWVQcBuvDBl23B6kDe<6EB6o23VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWt
XVXV6w2DM236EB6o23VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWt
2.2.1. Danh sách linh kiện...............................................................................10
2.2.2. Sơ đồ nguyên lý (mô tả kết nối).............................................................10
XVYV6MD2x23De<By23L6o0?6w2DM23VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWW
XViV6w2AaA`0acL60k2z-YXVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWW
2.4.1. Mục tiêu..................................................................................................11
2.4.2. Thư viện sử dụng...................................................................................11
2.4.3. Cấu hình WiFi và server........................................................................11
2.4.4. Đọc dữ liệu cảm biến..............................................................................12
2.4.5. Gửi dữ liệu lên server.............................................................................12
3
THỰC HÀNH LẬP TRÌNH DI ĐỘNG GVHD: Vũ Trung Dũng
2.4.6. Lấy ngưỡng cảnh báo từ server.............................................................12
2.4.7. Xử lý hiển thị cảnh báo..........................................................................13
2.4.8. Chu kỳ cập nhật.....................................................................................13
2.4.9. Kết quả hoạt động của phần cứng.........................................................13
Y*+(,! -!.&/
#VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWi
YVWV080B60EcD6c234aM239N23VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWi
YVXVQcBuvD6EB6o23?6w2AaA29u;09VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWi
YVYV b26{26D6T26| <02DB040B}VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWi
YViV0kc`~B6o23L5|6<uBDB040B}VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVW]
YVZVb0`jB237•23D126mO;|-€BB023PDB040B}VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWh
YV]V{AL0KA4b•cQB9‚>0Ec|-€<uD6DB040B}VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
YVhVqcQB9‚>0Ecu<„0>€qVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWp
YVƒVKB…c16;dB`†23M239N23VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVXW
i*\H‡!!ˆ!‰VVVVVVVVVXX
iVWVKB…c1B6CD2360EAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVXX
iVXVO2630O6EB6o23VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVXX
4.2.1. Ưu điểm..................................................................................................22
4.2.2. Hạn chế..................................................................................................22
4.2.3. Hướng phát triển....................................................................................22
iVYVa•cQBM239N23B6CDBKVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVXY
4
THỰC HÀNH LẬP TRÌNH DI ĐỘNG GVHD: Vũ Trung Dũng
( ,'H
5
THỰC HÀNH LẬP TRÌNH DI ĐỘNG GVHD: Vũ Trung Dũng
W*[\))
WVWV&^9;D6_2`aBb0
Trong bối cảnh hiện nay, ô nhiễm không khí đang trở thành một trong những vấn
đề môi trường nghiêm trọng nhất, đặc biệt tại các khu đô thị lớn khu công nghiệp.
Nồng độ bụi mịn PM2.5, PM10 cùng các khí độc hại như CO, NH , SO ngày càng
tăng, gây ảnh hưởng trực tiếp đến sức khỏe con người và chất lượng cuộc sống.
Tuy nhiên, phần lớn các thiết bị giám sát không khí thương mại hiện nay D60
?6TD<;‡L6@Bu0k2L6<0‡4bB60KcBT26>0266;dB. vậy, nhóm quyết định thực hiện
đề tài JEB6o2330OAPOBD6QB>7R23L6S23L6TB6S23A026U nhằm mục tiêu thiết
kế một hệ thống ;|29u;09D60?6TB6Q?, dễ cài đặt, cho phép …c<2POB4bD126
mO;D6QB>7R23L6S23L6TB6€;B6Š030<2B6CD, phù hợp với nội dung học phần Thực
hành Lập trình di động.
WVXV NDB05c4b?6dA40De<`aBb0
1.2.1. Mục tiêu chung
Xây dựng một hệ thống có khả năng:
Thu thập dữ liệu về bụi mịn, nhiệt độ, độ ẩm nồng độ khí độc trong môi
trường.
Tự động truyền dữ liệu qua mạng WiFi để lưu trữ hiển thị trên ứng dụng
Android.
Cảnh báo màu và âm thanh khi chỉ số vượt ngưỡng an toàn.
Cho phép người dùng xem lại dữ liệu, tra cứu theo thời gian và xuất báo cáo.
1.2.2. Mục tiêu cụ thể
6w2DM23* sử dụng z-YX(€40BW kết nối với cảm biến SDS011 (bụi
mịn), SHT31 (nhiệt độ độ ẩm), MQ-2 và MQ-135 (khí gas khí độc), kèm
LED và buzzer cảnh báo.
6w2AaA* xây dựng M239N2329u;09 bằng Java trên Android Studio,
hiển thị dữ liệu realtime, lưu trữ thống qua sở dữ liệu }-\&|
q .
KB2o0* truyền dữ liệu thông qua giao thức 4b‹- giữa ESP32
server, sau đó ứng dụng Android lấy dữ liệu qua .
0k2B6Œ* giao diện Android trực quan, sử dụng thư viện 29u;096<uB để
biểu diễn dữ liệu dạng biểu đồ.
1.2.3. Phạm vi thực hiện
Hệ thống hoạt động trong Ad23•0Ž02†0m†•&•.
Dữ liệu được lưu trữ trên >;D<>P€u4€u•q •, chưa triển khai lên cloud.
Chỉ giám sát các chỉ số cơ bản: PM2.5, PM10, nhiệt độ, độ ẩm, MQ2, MQ135.
6
Cảm biến ESP32
Server
(PHP + MySQL)
Ứng dụng
Android
THỰC HÀNH LẬP TRÌNH DI ĐỘNG GVHD: Vũ Trung Dũng
Ứng dụng tập trung vào 60k2B6Œ4bD126mO;, chưa mở rộng AI dự đoán.
WVYVf236g<De<`aBb0
1.3.1. Ý nghĩa thực tiễn
Giúp người dùng 26n2m0KBB{26Bud23S260‘AL6S23L6TBd0L6c4CD>’?
`jB theo thời gian thực.
Ứng dụng được triển khai dễ dàng cho 6†30<`{26‡Bu7Š236_D6;jD9;<26
2360E?26“, nâng cao ý thức bảo vệ môi trường.
Cung cấp cơ sở để ?6”2BTD6‡B6o23L54b`7<u<D126mO;P8A khi chất
lượng không khí vượt ngưỡng cho phép.
1.3.2. Ý nghĩa học thuật
Giúp sinh viên 4n29N23L0K2B6MD>05223b26 gồm: lập trình vi điều khiển,
xử lý dữ liệu cảm biến, lập trình Android, cơ sở dữ liệu và giao tiếp IoT.
Hiểu …c}Bu{26?6OBBu0k2M239N23;6;b2D6•26, từ phần cứng
truyền dữ liệu – đến giao diện người dùng.
Củng cố kỹ năng >n?Bu{26P;DL€B‡‡4bB60KBLKD–P—9‚>0Ec.
WViV S6{26Bl23…c<26EB6o23
Hệ thống được chia thành bốn thành phần chính, hoạt động B6€;D6c˜0Buc}a2
9‚>0EcBcw2BC qua mạng WiFi nội bộ (LAN):
3c}52>^6;dB`†23*
1. z-YX thu thập dữ liệu từ các cảm biến:
o -(-tWW: đo bụi mịn PM2.5, PM10.
o -YW: đo nhiệt độ và độ ẩm.
o \X‡ \WYZ: phát hiện khí gas, khói và khí độc hại.
2. Dữ liệu sau khi được xử lý và xác định ngưỡng sẽ được z-YX3™0>52P€u4€u
q  thông qua -•„0>€<99š9<B<V?6?• để lưu vào D–P—
9‚>0Ec }-\&.
3. +239N2329u;09 sau đó truy xuất dữ liệu t MySQL qua •„0>€
3€Bš9<B<V?6?‡3€BšB6u€P6;>9PV?6?‡›• để hiển thị, thống kê và cảnh báo.
4. Dựa trên dữ liệu nhận được, app 60k2B6Œu€<>B0A€, đổi màu giao diện (xanh
vàng đỏ) phát âm thanh cảnh báo nếu vượt ngưỡng.Người dùng thể
•€Am0kc`~B6o23L5‡B{AL0KA9‚>0EcB6€;B6Š030<2‡6;jD•cQB„0>€-
để phân tích.
7
Hình 1. 1. Sơ đồ tổng quan
THỰC HÀNH LẬP TRÌNH DI ĐỘNG GVHD: Vũ Trung Dũng
8
THỰC HÀNH LẬP TRÌNH DI ĐỘNG GVHD: Vũ Trung Dũng
WViVjD`0kA2l0mnBDe<6EB6o23
uc}a29‚>0EcBC`†23* Toàn bộ dữ liệu cảm biến được gửi lưu trữ hoàn
toàn tự động qua HTTP.
0OAPOBB6Š030<2B6CD* Ứng dụng Android cập nhật liên tục các chỉ số từ cơ
sở dữ liệu.
126mO;B6S23A026* LED buzzer kích hoạt khi vượt ngưỡng, giao diện
đổi màu trực quan.
&7cBu‚œ?6”2BTD6* Dữ liệu được lưu trong MySQL, thể xem lại, thống
kê theo ngày hoặc giờ.
—u†239‘9b23* thể nâng cấp kết nối cloud (Firebase/Thingspeak) hoặc
bổ sung AI dự đoán xu hướng ô nhiễm.
9
THỰC HÀNH LẬP TRÌNH DI ĐỘNG GVHD: Vũ Trung Dũng
X*qr"(%s
XVWVQcBuvDBl23B6kDe<6EB6o23
Hệ thống gồm hai khối chính:
6o0?6w2DM23•B60KBmŒ;•* sử dụng vi điều khiển ESP32 DevKit V1 làm
trung tâm, kết nối các cảm biến đo môi trường (bụi mịn, khí gas, nhiệt độ – độ
ẩm).
6o0?6w2AaA* bao gồm chương trình trên ESP32, ứng dụng Android, cơ sở
dữ liệu MySQL và các API PHP trung gian.
Dữ liệu được thu thập từ cảm biến, gửi lên server XAMPP để lưu trữ, được
ứng dụng Android truy xuất, hiển thị theo thời gian thực.
XVXV6w2DM236EB6o23
2.2.1. Danh sách linh kiện
-
52>026L0E2 6MD2x23D6T26 60D6v
1 z-YX
(€40BW
Vi điều khiển trung tâm, thu thập và
truyền dữ liệu qua WiFi
32-bit, hỗ trợ WiFi
& BLE
2 1Am0K2
-(-tWW
Đo nồng độ bụi mịn PM2.5 và PM10 Giao tiếp UART
3 1Am0K2
-YW
Đo nhiệt độ và độ ẩm không khí Giao tiếp I2C
4 1Am0K2
\X
Phát hiện khí gas, khói, LPG Ngõ ra analog
5 1Am0K2
\WYZ
Phát hiện khí độc, CO , NH Ngõ ra analog
6 &z( Hiển thị màu cảnh báo theo mức ô
nhiễm
Kết nối GPIO 25-
27
7 c••€u Báo hiệu âm thanh khi vượt ngưỡng GPIO 18
8 3c~2Z|
X
Cung cấp điện cho ESP32 và cảm biến
2.2.2. Sơ đồ nguyên lý (mô tả kết nối)
10
THỰC HÀNH LẬP TRÌNH DI ĐỘNG GVHD: Vũ Trung Dũng
Hình 2. 1. Sơ đồ kết nối phần cứng
XVYV6MD2x23De<By23L6o0?6w2DM23
6o0D1Am0K2* đo đạc liên tục thông số môi trường (bụi, khí, nhiệt độ, độ
ẩm).
6o0•™>^Buc23B”A•z-YX•* thu thập, lọc xử dữ liệu, xác định
ngưỡng ô nhiễm, điều khiển cảnh báo và gửi dữ liệu lên server.
6o0D126mO;* hiển thị bằng LED RGB (xanh – vàng – đỏ) và phát âm thanh
qua buzzer khi vượt ngưỡng.
6o023c~2* cung cấp ổn định 5V/2A cho toàn hệ thống.
XViV6w2AaA`0acL60k2z-YX
2.4.1. Mục tiêu
Thu thập dữ liệu cảm biến SDS011, MQ-2, MQ-135, SHT31.
Gửi dữ liệu lên server MySQL thông qua •<99š9<B<V?6?•V
Lấy ngưỡng cảnh báo từ server qua •3€BšB6u€P6;>9PV?6?•.
Hiển thị trạng thái đèn cảnh báo và buzzer tương ứng.
2.4.2. Thư viện sử dụng
#include <WiFi.h> // quản lý kết nối WiFi.
#include <HTTPClient.h> // gửi và nhận dữ liệu qua HTTP.
#include <Adafruit_SHT31.h> // điều khiển cảm biến nhiệt độ – độ ẩm.
#include <ArduinoJson.h> // hóa dữ liệu thành định dạng JSON để gửi lên
server.
2.4.3. Cấu hình WiFi và server
const char* ssid = "Nha 19 Vinh Hung";
const char* password = "0343729584";
11
THỰC HÀNH LẬP TRÌNH DI ĐỘNG GVHD: Vũ Trung Dũng
const char* serverAddData = "http://192.168.1.80/giamsatkk/api/add_data.php";
const char* serverThreshold =http://192.168.1.80/giamsatkk/api/get_thresholds.php ;
ESP32 kết nối WiFi nội bộ và sử dụng API PHP để giao tiếp với MySQL.
2.4.4. Đọc dữ liệu cảm biến
float temp = sht31.readTemperature();
float hum = sht31.readHumidity();
float mq2 = analogRead(MQ2_PIN);
float mq135 = analogRead(MQ135_PIN);
Đọc giá trị nhiệt độ, độ ẩm, và khí gas từ các cảm biến tương ứng.
2.4.5. Gửi dữ liệu lên server
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(serverAddData);
http.addHeader("Content-Type", "application/json");
DynamicJsonDocument doc(256);
doc["temp"] = temp;
doc["hum"] = hum;
doc["mq2"] = mq2;
doc["mq135"] = mq135;
String json;
serializeJson(doc, json);
http.POST(json);
http.end();
}
010B6TD6* ESP32 tạo một đối tượng JSON chứa dữ liệu cảm biến, gửi POST
request tới add_data.php, i dữ liệu được lưu vào MySQL. Quá trình này
diễn ra lặp lại sau mỗi 3–5 giây.
2.4.6. Lấy ngưỡng cảnh báo từ server
HTTPClient http;
http.begin(serverThreshold);
int httpCode = http.GET();
if (httpCode == 200) {
String payload = http.getString();
DynamicJsonDocument doc(256);
deserializeJson(doc, payload);
float limit_pm25 = doc["pm25"];
12
THỰC HÀNH LẬP TRÌNH DI ĐỘNG GVHD: Vũ Trung Dũng
float limit_mq2 = doc["mq2"];
}
ESP32 đọc giá trị ngưỡng do người dùng cài đặt trên app Android, từ đó điều
khiển đèn cảnh báo.
2.4.7. Xử lý hiển thị cảnh báo
if (mq2 > limit_mq2 || mq135 > 3000) {
digitalWrite(RED_LED, HIGH);
tone(BUZZER, 2000);
} else {
digitalWrite(GREEN_LED, HIGH);
noTone(BUZZER);
}
Nếu giá trị cảm biến vượt ngưỡng → đèn đỏ + còi kêu.
Nếu trong ngưỡng an toàn → đèn xanh + tắt còi.
2.4.8. Chu kỳ cập nhật
delay(5000);
Mỗi 5 giây, ESP32 đọc dữ liệu mới, gửi lên server, cập nhật lại trạng thái
cảnh báo.
2.4.9. Kết quả hoạt động của phần cứng
Dữ liệu được ghi nhận chính xác và cập nhật ổn định.
Tốc độ gửi dữ liệu trung bình: W3@0žZ30”}.
Sai số cảm biến thấp (<5%).
Cảnh báo đèn và buzzer hoạt động theo đúng logic ngưỡng.
13
THỰC HÀNH LẬP TRÌNH DI ĐỘNG GVHD: Vũ Trung Dũng
Y*+(,! -!.&/
#
YVWV080B60EcD6c234aM239N23
Ứng dụng được xây dựng bằng Android Studio (Java), chức năng hiển thị,
cảnh báo thống chất lượng không khí theo thời gian thực, dựa trên dữ liệu từ
sở dữ liệu MySQL.Ứng dụng được kết nối với server thông qua giao thức HTTP (API
PHP). Dữ liệu do ESP32 gửi lên MySQL sẽ được ứng dụng truy xuất, giải JSON,
và hiển thị bằng giao diện trực quan.
Cấu trúc ứng dụng gồm 4 Activity chính:
1. <02DB040B}* hiển thị dữ liệu realtime và trạng thái cảnh báo.
2. 6<uBDB040B}* hiển thị biểu đồ thống kê lịch sử.
3. -€BB023PDB040B}* cài đặt ngưỡng cảnh báo.
4. -€<uD6DB040B}* tra cứu và xuất dữ liệu theo thời gian.
YVXVQcBuvD6EB6o23?6w2AaA29u;09
6b26?6w2 6MD2x23D6T26
<02DB040B}VŸ<4< Nhận và hiển thị dữ liệu mới nhất từ server, đổi màu cảnh
báo.
6<uBDB040B}VŸ<4< Truy xuất và vẽ biểu đồ dữ liệu cảm biến bằng
MPAndroidChart.
-€BB023PDB040B}VŸ<4< Cho phép người dùng cài đặt và lưu ngưỡng cảnh báo.
-€<uD6DB040B}VŸ<4< Tìm kiếm dữ liệu theo ngày, giờ; xuất ra file CSV.
 Trung gian giao tiếp giữa App và MySQL.
}-\&(<B<m<P€ Lưu trữ các giá trị cảm biến (temp, hum, pm25, mq2,
mq135...).
YVYV b26{26D6T26| <02DB040B}
<•6MD2x23*
Hiển thị dữ liệu cảm biến mới nhất (nhiệt độ, độ ẩm, bụi, khí gas...).
Đổi màu giao diện theo trạng thái cảnh báo (xanh, vàng, đỏ).
Cập nhật dữ liệu liên tục theo chu kỳ 3 giây.
m•;9€D6T26*
private void getLatestData() {
StringRequest request = new StringRequest(Request.Method.GET,
ServerConfig.GET_LATEST_URL,
response -> {
try {
JSONObject obj = new JSONObject(response);
14
THỰC HÀNH LẬP TRÌNH DI ĐỘNG GVHD: Vũ Trung Dũng
tvTemp.setText(obj.getString("temp") + " °C");
tvHum.setText(obj.getString("hum") + " %");
tvPM.setText(obj.getString("pm25") + " µg/m³");
tvGas.setText(obj.getString("mq135"));
double pm = obj.getDouble("pm25");
if (pm < 35) mainLayout.setBackgroundColor(Color.GREEN);
else if (pm < 75) mainLayout.setBackgroundColor(Color.YELLOW);
else mainLayout.setBackgroundColor(Color.RED);
} catch (JSONException e) {
e.printStackTrace();
}
},
error -> Toast.makeText(this, "Lỗi kết nối server",
Toast.LENGTH_SHORT).show());
Volley.newRequestQueue(this).add(request);
}
D•010B6TD6*
Ứng dụng gửi yêu cầu GET đến get_latest.php.
Dữ liệu JSON trả về được parse và hiển thị lên giao diện.
Màu nền thay đổi tùy theo giá trị PM2.5.
Hàm được gọi định kỳ bằng Handler.postDelayed() để cập nhật realtime.
Hình 3. 1. Giao diện MainActivity – hiển thị chỉ số không khí và cảnh báo màu
15
Lối tắt
Cập nhật lần cuối
Real-time
Hiển thị thông số
Thanh menu
Tên app
Nút cảnh báo
THỰC HÀNH LẬP TRÌNH DI ĐỘNG GVHD: Vũ Trung Dũng
YViV0kc`~B6o23L5|6<uBDB040B}
<•6MD2x23*
Hiển thị biểu đồ biến động của PM2.5, nhiệt độ, MQ2, MQ135 theo thời gian.
Cho phép người dùng chọn khoảng thời gian cần xem thống kê.
m•;9€D6T26*
private void loadChartData() {
StringRequest request = new StringRequest(Request.Method.GET,
ServerConfig.GET_HISTORY_URL,
response -> {
try {
JSONArray array = new JSONArray(response);
ArrayList<Entry> entries = new ArrayList<>();
for (int i = 0; i < array.length(); i++) {
JSONObject obj = array.getJSONObject(i);
entries.add(new Entry(i, (float) obj.getDouble("pm25")));
}
LineDataSet dataSet = new LineDataSet(entries, "PM2.5 (µg/m³)");
dataSet.setColor(Color.BLUE);
LineData lineData = new LineData(dataSet);
chart.setData(lineData);
chart.invalidate();
} catch (JSONException e) {
e.printStackTrace();
}
},
error -> Toast.makeText(this, "Không thể tải dữ liệu",
Toast.LENGTH_SHORT).show());
Volley.newRequestQueue(this).add(request);
}
D•010B6TD6*
Ứng dụng gửi yêu cầu tới get_history.php.
Dữ liệu trả về dưới dạng JSON array, mỗi phần tử chứa giá trị PM2.5 theo thời
gian.
MPAndroidChart được sử dụng để vẽ biểu đồ đường (LineChart).
Người dùng có thể chọn khoảng thời gian hiển thị (1 giờ, 1 ngày, 1 tuần...).
16
THỰC HÀNH LẬP TRÌNH DI ĐỘNG GVHD: Vũ Trung Dũng
Hình 3. 2. Giao diện ChartActivity thống kê các thông số theo biểu đồ
YVZVb0`jB237•23D126mO;|-€BB023PDB040B}
<•6MD2x23*
Cho phép người dùng nhập ngưỡng giới hạn cho nhiệt độ, độ ẩm, khí gas
bụi.
Lưu ngưỡng này vào -6<u€9u€„€u€2D€P và đồng bộ lên server.
m•;9€D6T26*
btnSave.setOnClickListener(v -> {
float pm25Limit = Float.parseFloat(edtPM25.getText().toString());
float gasLimit = Float.parseFloat(edtGas.getText().toString());
SharedPreferences.Editor editor = prefs.edit();
editor.putFloat("pm25_limit", pm25Limit);
editor.putFloat("gas_limit", gasLimit);
editor.apply();
Toast.makeText(this, "Đã lưu ngưỡng cảnh báo",
Toast.LENGTH_SHORT).show();
});
D•010B6TD6*
Khi người dùng nhấn “Lưu”, giá trị được ghi vào SharedPreferences.
App có thể gửi dữ liệu này đến server thông qua API save_threshold.php.
Ngưỡng được ESP32 tải về để cập nhật logic cảnh báo đèn và buzzer.
17
THỰC HÀNH LẬP TRÌNH DI ĐỘNG GVHD: Vũ Trung Dũng
Hình 3. 3. Giao diện SettingsActivity – nhập ngưỡng giới hạn và lưu
YV]V{AL0KA4b•cQB9‚>0Ec|-€<uD6DB040B}
<•6MD2x23*
Tra cứu dữ liệu theo ngày, giờ hoặc khoảng thời gian tùy chọn.
Hiển thị bảng kết quả chi tiết, cho phép xuất ra file txt.
m•;9€D6T26*
btnSearch.setOnClickListener(v -> {
String date = edtDate.getText().toString();
String url = ServerConfig.SEARCH_URL + "?date=" + date;
StringRequest request = new StringRequest(Request.Method.GET, url,
response -> {
try {
JSONArray arr = new JSONArray(response);
listData.clear();
for (int i = 0; i < arr.length(); i++) {
JSONObject obj = arr.getJSONObject(i);
listData.add("[" + obj.getString("datetime") + "] "
+ obj.getString("pm25") + " µg/m³");
}
adapter.notifyDataSetChanged();
} catch (JSONException e) { e.printStackTrace(); }
},
error -> Toast.makeText(this, "Không có dữ liệu",
Toast.LENGTH_SHORT).show());
Volley.newRequestQueue(this).add(request);
18