add wifi hotspot

This commit is contained in:
2026-08-30 20:44:35 +07:00
parent 14bf4821df
commit 016c822227
2 changed files with 808 additions and 833 deletions
+263 -443
View File
@@ -1,510 +1,330 @@
# WiFiSense
# WiFiSense — ESP32-S3 + OLED Edition
Firmware ESP32-S3 phát hiện sự hiện diện/chuyển động của người trong phòng bằng **phân tích tín hiệu WiFi và xử lý tín hiệu thống kê**. Không cần cảm biến bổ sung — chỉ cần WiFi.
> Phát hiện chuyển động thụ động qua biến động tín hiệu RSSI WiFi, hiển thị trực tiếp trên màn hình OLED 0.96", tự động cấu hình WiFi qua Captive Portal.
> **English version:** [README-en.md](README-en.md)
## Tổng quan
Dự án sử dụng ESP32-S3 liên tục theo dõi cường độ tín hiệu WiFi (RSSI) và phát hiện những nhiễu động đo được do chuyển động của con người gây ra. Khi phát hiện chuyển động, ngõ ra LED đã cấu hình sẽ được kích hoạt theo thời gian thực.
**Phù hợp cho:** tự động hóa nhà ở, phát hiện có người trong phòng, kích hoạt đèn thông minh và tiết kiệm năng lượng.
![Platform](https://img.shields.io/badge/Platform-ESP32--S3-blue)
![IDE](https://img.shields.io/badge/IDE-Arduino-teal)
![License](https://img.shields.io/badge/License-MIT-green)
---
## Cơ sở vật lý
## Mục lục
### Nguyên lý nền tảng
Cơ thể người chứa khoảng 60% nước. Nước dẫn điện và hấp thụ mạnh bức xạ điện từ tại 2,4 GHz (tần số WiFi):
- **Hệ số hấp thụ của nước ở 2,4 GHz:** ~0,15 dB/cm
- **Bề rộng thân người điển hình:** ~20 cm
- **Suy hao tín hiệu do cơ thể người:** 515 dB, tùy vị trí
Khi bạn di chuyển giữa router và ESP32-S3:
1. **Tín hiệu mạnh hơn** khi có ít vật cản hơn.
2. **Tín hiệu yếu đi** khi cơ thể chặn đường truyền thẳng.
3. **Tín hiệu dao động** do bị tán xạ và phản xạ.
Chính biến động RSSI động này là tín hiệu mà firmware phát hiện.
### Vì sao phương sai quan trọng
Nhiễu tĩnh (tường, nội thất) ảnh hưởng RSSI một cách ổn định. Ngược lại, **chuyển động của người tạo ra thay đổi nhanh và khó dự đoán**:
- **Môi trường yên tĩnh:** độ lệch chuẩn RSSI = 0,20,5 dBm (nhiễu ngẫu nhiên)
- **Người đứng yên:** độ lệch chuẩn = 0,81,5 dBm (hơi thở, cử động nhỏ)
- **Người đi lại:** độ lệch chuẩn = 2,55,0 dBm (biến động mạnh)
Firmware đo **độ lệch chuẩn của 40 lần đọc RSSI gần nhất** để phát hiện bất thường.
- [Nguyên lý hoạt động](#nguyên-lý-hoạt-động)
- [Sơ đồ luồng hệ thống](#sơ-đồ-luồng-hệ-thống)
- [Phần cứng](#phần-cứng)
- [Cài đặt môi trường](#cài-đặt-môi-trường)
- [Nạp code](#nạp-code)
- [Cách sử dụng](#cách-sử-dụng)
- [Màn hình OLED](#màn-hình-oled)
- [Troubleshooting](#troubleshooting)
---
## Các thuật toán phát hiện
## Nguyên lý hoạt động
Firmware kết hợp **6 hệ thống phát hiện độc lập**:
WiFiSense **không dùng camera, microphone hay cảm biến vật lý nào**. Thay vào đó, nó khai thác một hiện tượng vật lý: khi có người/vật di chuyển trong phòng, sóng WiFi bị phản xạ và nhiễu loạn, khiến **chỉ số RSSI** (cường độ tín hiệu) dao động theo những mẫu đặc trưng.
### 1. Bộ lọc Kalman
Giảm nhiễu đo lường nhưng vẫn giữ các cạnh tín hiệu (các thay đổi quan trọng).
### Pipeline xử lý tín hiệu
```
filtered_value = estimate + gain × (measurement - estimate)
WiFi RSSI thô
┌─────────────────┐
│ Kalman Filter │ ← Loại bỏ nhiễu ngẫu nhiên ngắn hạn
└────────┬────────┘
┌──────────────────────┐
│ Exponential Smoothing │ ← Làm mượt tín hiệu (α = 0.15)
└──────────┬───────────┘
┌──────────────────────────────────────────────────┐
│ Cửa sổ trượt (40 mẫu ngắn + 100 mẫu dài) │
│ • Độ lệch chuẩn (Variance) → biên độ dao động │
│ • Rate of Change → tốc độ thay đổi │
│ • Peak Detection → đỉnh đột biến │
│ • Z-Score → bất thường thống │
└──────────────────────┬───────────────────────────┘
┌────────────────────────────────┐
│ Tính Confidence Score (0100) │
└──────────────┬─────────────────┘
┌──────────────────────────────────────────────────┐
│ Persistence Counter (≥ 3 mẫu liên tiếp) │
│ → Kết luận: MOTION / CLEAR │
│ → Bật LED + hiển thị OLED │
└──────────────────────────────────────────────────┘
```
- **Kalman gain:** 0,15 (cân bằng độ nhạy và độ ổn định)
- **Tác dụng:** loại bỏ 6070% nhiễu ngẫu nhiên mà ít gây trễ
### Adaptive Baseline
### 2. Làm mượt hàm mũ
Lớp lọc thứ hai để tính đường nền rất mượt.
```
smooth = 0.15 × new_reading + 0.85 × previous_smooth
```
### 3. Phân tích phương sai cửa sổ trượt
Phát hiện bất thường bằng cách phân tích hành vi tín hiệu theo thời gian.
```
variance = √(Σ(reading - mean)² / N)
```
- **Kích thước cửa sổ:** 40 mẫu, tương đương khoảng 1,4 giây dữ liệu thời gian thực
- **Ngưỡng chuyển động chậm:** độ lệch chuẩn 1,8 dBm
- **Ngưỡng chuyển động nhanh:** độ lệch chuẩn 3,5 dBm
### 4. Phát hiện Z-score (bất thường thống kê)
Xác định các lần đọc lệch khỏi chuẩn thống kê.
```
z_score = |current_reading - mean| / standard_deviation
```
- **Ngưỡng bất thường:** Z > 2,5 (độ tin cậy thống kê 99,4%)
- **Tác dụng:** hạn chế dương tính giả do các đột biến ngẫu nhiên
### 5. Phát hiện đỉnh
Bắt các chuyển tiếp tín hiệu đột ngột khi bạn bắt đầu di chuyển vào phòng.
```
peak = max(Δ_current - Δ_previous)
```
Thuật toán kiểm tra liệu bản thân tốc độ thay đổi có biến động đột ngột hay không.
### 6. Tốc độ thay đổi
Định lượng mức độ thay đổi nhanh của tín hiệu.
```
rate = mean(recent_5_samples) - mean(old_5_samples)
```
Chuyển động nhanh thường tạo tốc độ thay đổi lớn hơn.
Baseline (đường cơ sở khi không có chuyển động) **tự thích nghi** theo thời gian thực với tốc độ rất chậm (α = 0.008), giúp hệ thống tự điều chỉnh khi môi trường thay đổi dần (người rời phòng, thay đổi vị trí router…).
---
## Logic phát hiện (đa tiêu chí)
Firmware kích hoạt phát hiện khi:
## Sơ đồ luồng hệ thống
```
motion = (variance > 1.8) OR (Z-score > 2.5 AND peak > 2.0)
┌──────────────┐
│ Khởi động │
└──────┬───────┘
┌──────▼───────┐
│ Đọc NVS │ credentials đã lưu?
└──────┬───────┘
Có ▼ ▼ Không
┌──────────────┐ ┌──────────────────────┐
│ Kết nối WiFi │ │ Mở AP WiFiSense-Setup│
└──────┬───────┘ │ DNS + Captive Portal │
OK ▼ ▼ Fail │ Người dùng chọn mạng │
┌────────┐ ┌──────────┐ │ → Lưu NVS → Restart │
│Calibrate│ │Thử lại x3│ └──────────────────────┘
└────┬───┘ └────┬─────┘
│ Fail│
│ ┌────▼──────────────┐
│ │ Xóa NVS + Restart │
│ └───────────────────┘
┌────▼──────────────────┐
│ Loop chính │
│ • Lấy RSSI mỗi 500ms │
│ • Kalman + Smooth │
│ • Tính Variance/Z │
│ • Cập nhật OLED │
│ • Bật/tắt LED │
└───────────────────────┘
```
Diễn giải: chuyển động được phát hiện nếu độ lệch chuẩn tín hiệu cao, **hoặc** có bất thường thống kê đồng thời có chuyển tiếp tín hiệu sắc nét.
Sau khi có chuyển động, điều kiện phải duy trì **3 chu kỳ liên tiếp** thì LED mới bật. Đây là cổng bền vững để loại bỏ dương tính giả.
---
## Màn hình OLED
## Phần cứng
Firmware hỗ trợ **màn hình OLED SSD1306 0,96 inch, độ phân giải 128×64, giao tiếp I2C** nối với ESP32-S3 như sau:
### Linh kiện cần thiết
| Chân OLED | Chân ESP32-S3 |
| Linh kiện | Thông số | Ghi chú |
|---|---|---|
| Vi điều khiển | ESP32-S3 (bất kỳ board) | Đã test trên ESP32-S3-DevKitC-1 |
| Màn hình OLED | 0.96" SSD1306 128×64 I2C | Địa chỉ I2C: `0x3C` |
| LED | 3mm hoặc 5mm, bất kỳ màu | Kèm điện trở 220Ω–330Ω |
| Dây jumper | Male-to-Male hoặc Male-to-Female | — |
### Sơ đồ đấu dây
```
ESP32-S3 SSD1306 OLED
───────── ────────────
GPIO 6 ───────── SDA
GPIO 7 ───────── SCL
3.3V ───────── VCC
GND ───────── GND
ESP32-S3 LED
───────── ────────────
GPIO 2 ──[330Ω]── Anode (+)
GND ───────── Cathode (-)
```
> **Lưu ý:** Một số board ESP32-S3 (ví dụ Waveshare) có thể có sẵn LED trên GPIO 2 — kiểm tra datasheet của board bạn đang dùng.
---
## Cài đặt môi trường
### 1. Arduino IDE
Tải về tại [arduino.cc/en/software](https://www.arduino.cc/en/software) (phiên bản 2.x khuyến nghị).
### 2. Thêm ESP32 vào Board Manager
Vào **File → Preferences → Additional boards manager URLs**, thêm:
```
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
```
Sau đó vào **Tools → Board → Boards Manager**, tìm **esp32** của Espressif và cài đặt.
### 3. Cài thư viện
Vào **Tools → Manage Libraries** và cài đặt 2 thư viện sau:
| Thư viện | Tác giả | Ghi chú |
|---|---|---|
| **Adafruit SSD1306** | Adafruit | Tìm đúng tên này |
| **Adafruit GFX Library** | Adafruit | Dependency của SSD1306 |
> Các thư viện còn lại (`WiFi`, `WebServer`, `DNSServer`, `Preferences`) đã có sẵn trong ESP32 Arduino core, **không cần cài thêm**.
### 4. Chọn board
**Tools → Board → ESP32 Arduino → ESP32S3 Dev Module**
Các thông số quan trọng:
| Tùy chọn | Giá trị |
|---|---|
| VCC | 3.3V |
| GND | GND |
| SDA | GPIO 6 |
| SCL | GPIO 7 |
Địa chỉ I2C mặc định là `0x3C`. Giao tiếp I2C được khởi tạo bằng `Wire.begin(6, 7)`.
Cài các thư viện sau bằng Library Manager của Arduino IDE:
- **Adafruit SSD1306** của Adafruit
- **Adafruit GFX Library** của Adafruit
Trang chính hiển thị trạng thái WiFi, RSSI, độ tin cậy, chất lượng tín hiệu, đường nền, phương sai và tổng số lần phát hiện. Sketch đã có trang chi tiết kỹ thuật, nhưng phần tự chuyển trang hiện đang được tắt trong `loop()`, vì vậy trang chính được hiển thị liên tục.
Nếu màn hình không khởi tạo, hãy kiểm tra nguồn 3,3V, dây GND chung, dây SDA/SCL và giá trị `OLED_ADDRESS` trong `WiFiSense.ino`.
| USB Mode | Hardware CDC and JTAG |
| Flash Size | 4MB (hoặc theo board của bạn) |
| Partition Scheme | Default 4MB with spiffs |
| PSRAM | Disabled (nếu board không có) |
---
## Dữ liệu đầu ra thời gian thực
## Nạp code
### Serial Plotter (đồ thị)
1. Kết nối ESP32-S3 với máy tính qua USB.
2. Mở file `WiFiSense.ino` trong Arduino IDE.
3. Chọn đúng **Port** tại **Tools → Port**.
4. Nhấn nút **Upload** (→) hoặc `Ctrl+U`.
5. Chờ quá trình biên dịch và nạp hoàn tất (~3060 giây).
Mở `Tools > Serial Plotter` trong Arduino IDE để xem:
- **Raw:** cường độ WiFi trực tiếp
- **Kalman:** tín hiệu đã giảm nhiễu
- **Smooth:** đường nền đã làm mượt
- **Baseline:** mức tín hiệu kỳ vọng hiện tại
- **Variance:** độ lệch chuẩn, chỉ báo chuyển động
- **ZScore:** độ lệch thống kê
### Serial Monitor (văn bản)
Ví dụ dữ liệu thời gian thực:
```
[WALKING] Conf:75% | Quality:92% | Rate:2.5 | Total:14
[CALM] Conf:20% | Quality:88% | Rate:0.3 | Total:14
```
- **Intensity:** `CALM → SLOW → WALKING → FAST → SPRINT`
- **Confidence:** độ chắc chắn phát hiện, 0100%
- **Quality:** điểm ổn định tín hiệu, 0100%
- **Rate:** tốc độ tín hiệu thay đổi
- **Total:** tổng số lần phát hiện trong phiên
---
## Lắp đặt vật lý (rất quan trọng với độ chính xác)
### Cấu hình tối ưu
```
Router (WiFi AP)
|
[3-5m]
|
[Người đi qua tại đây]
|
[ESP32-S3]
```
**Quy tắc đặt thiết bị:**
1. **Khoảng cách:** 35 m giữa router và ESP32-S3.
2. **Tầm nhìn:** người nên đi qua gần vị trí giữa hai thiết bị.
3. **Vị trí router:** đặt anten thẳng đứng để có vùng phủ gần đẳng hướng.
4. **Tránh:** lò vi sóng, điện thoại không dây và các thiết bị 2,4 GHz khác.
### Đánh giá thực tế
- **Lắp đặt tốt:** độ chính xác phát hiện 8592%.
- **Lắp đặt kém:** 6075%.
- **Kém nhất:** đặt sát router hoặc bị chắn đường truyền thẳng có thể làm hệ thống không hiệu quả.
---
## Độ chính xác và giới hạn
### ✅ Hoạt động tốt với
- **Nhận biết trạng thái có người trong phòng**.
- **Phát hiện chuyển động:** đi bộ, chạy, cử chỉ lớn.
- **Phản hồi thời gian thực:** độ trễ khoảng 35 ms.
- **Chống báo động giả:** cổng bền vững 3 chu kỳ và xác thực đa tiêu chí.
### ⚠️ Giới hạn do đặc tính vật lý
| Tình huống | Vấn đề |
|---|---|
| Chuyển động rất chậm (đang ngủ) | Có thể không phát hiện dao động mức hô hấp |
| Nhiều người | Tín hiệu bị trung bình; chỉ nhận biết “có người”, không đếm người |
| Vật thể kim loại lớn | Phản xạ có thể gây dương tính giả |
| WiFi ở xa | Biến động tín hiệu yếu khó phân biệt với nhiễu |
| Tường kim loại | Tán xạ tín hiệu làm giảm độ tin cậy |
### ❌ Không thể thực hiện chỉ với WiFi
- Phân biệt chính xác **đứng hay ngồi**.
- Xác định **đó là ai**.
- Định vị chính xác hơn mức “có/không có người trong phòng”.
- Đạt **độ chính xác trên 95%** (giới hạn vật lý thực tế khoảng 90%).
Để vượt 90% độ chính xác, có thể cân nhắc:
- Nhiều ESP32-S3 để tam giác hóa.
- Phân loại bằng học máy.
- Cảm biến kết hợp: WiFi + PIR.
- WiFi 5 GHz (nhạy hơn nhưng tầm ngắn hơn).
---
## Hướng dẫn cài đặt
### Phần cứng cần có
- **Bo phát triển ESP32-S3**
- **Cáp USB** để nạp firmware
- **Mạng WiFi 2,4 GHz**
- LED nối vào `LED_PIN` đã cấu hình trong `WiFiSense.ino` (GPIO2 chỉ là mặc định; hãy kiểm tra chân LED của board)
### Cài đặt phần mềm
1. **Cài Arduino IDE** nếu chưa có
- Tải tại: https://www.arduino.cc/en/software
2. **Thêm hỗ trợ board ESP32**
- Mở `Arduino IDE > Preferences`.
- Thêm URL sau vào **Additional Board Manager URLs**:
```
https://espressif.github.io/arduino-esp32/package_esp32_index.json
```
- Vào `Tools > Board > Board Manager`.
- Tìm **esp32** và cài **esp32 by Espressif Systems**.
3. **Thư viện cần thiết**
- `WiFi.h` và `Wire.h` được cung cấp sẵn cùng ESP32 board support.
- Cài **Adafruit SSD1306** và **Adafruit GFX Library**.
4. **Cấu hình board**
```
Tools > Board: ESP32S3 Dev Module
Tools > USB CDC On Boot: Enabled
Tools > Flash Size: default
Tools > Baud Rate: 115200
```
5. **Cập nhật thông tin WiFi**
- Mở `WiFiSense.ino`.
- Tìm các dòng:
```cpp
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
```
- Thay bằng tên WiFi và mật khẩu của bạn.
6. **Nạp firmware cho ESP32-S3**
- Kết nối ESP32-S3 bằng USB.
- Chọn đúng cổng tại `Tools > Port`.
- Nhấn **Upload**.
- Chờ thông báo build/nạp thành công.
7. **Xem dữ liệu thời gian thực**
- Mở `Tools > Serial Monitor`, đặt tốc độ **115200**.
- Hoặc mở `Tools > Serial Plotter` để xem đồ thị.
- Bạn sẽ thấy ví dụ như:
```
[CALM] Conf:15% | Quality:89% | Rate:0.2 | Total:0
```
---
## Hiệu chỉnh và tinh chỉnh
### Nếu bỏ sót chuyển động
Hạ các ngưỡng để tăng độ nhạy. Trong firmware hiện tại, chỉnh các hằng số sau:
```cpp
constexpr float SLOW_MOVEMENT_THRESHOLD = 1.5f; // mặc định 1.8
constexpr float FAST_MOVEMENT_THRESHOLD = 3.0f; // mặc định 3.5
constexpr float Z_SCORE_THRESHOLD = 2.2f; // mặc định 2.5
```
### Nếu có nhiều báo động giả
Tăng yêu cầu bền vững:
```cpp
constexpr uint8_t PERSISTENCE_REQUIRED = 5; // mặc định 3
```
Hoặc tăng ngưỡng phương sai:
```cpp
constexpr float SLOW_MOVEMENT_THRESHOLD = 2.0f; // mặc định 1.8
```
### Điều chỉnh tốc độ phát hiện
Giảm khoảng cách giữa các mẫu:
```cpp
constexpr uint16_t SAMPLE_INTERVAL_MS = 25; // mặc định 35 ms
```
### Học môi trường
Firmware tự điều chỉnh đường nền theo phòng:
```cpp
constexpr float ADAPTIVE_ALPHA = 0.008f;
```
Hãy cho thiết bị hoạt động trong phòng yên tĩnh vài phút để đường nền thích nghi ổn định hơn.
> Nếu board không tự vào chế độ nạp: giữ nút **BOOT**, nhấn **RESET**, thả **RESET**, rồi thả **BOOT**.
---
## Cách sử dụng
### Hiệu chuẩn ban đầu ⚠️ **QUAN TRỌNG**
### Lần đầu tiên (chưa có WiFi lưu)
Thiết bị cần một giai đoạn hiệu chuẩn trong phòng trống trước khi phát hiện chuyển động chính xác. Firmware hiện tại thu 200 mẫu, mất khoảng 6 giây; nếu môi trường nhiễu, hãy để phòng trống lâu hơn:
Khi khởi động và chưa có credentials trong NVS, ESP32 sẽ tự động mở **Captive Portal**:
1. Cấp nguồn ESP32-S3 trong phòng cần giám sát.
2. Để phòng trống, không có người di chuyển.
3. Đợi firmware kết nối WiFi và hoàn tất hiệu chuẩn RSSI.
4. Serial Monitor sẽ hiển thị đường nền; phương sai trong môi trường yên tĩnh thường thấp (<1,0 dBm).
5. Sau đó, kiểm tra bằng cách đi qua vùng giữa router và ESP32-S3.
```
OLED hiển thị:
┌──────────────────────────────┐
│ ** SETUP MODE ** │
│──────────────────────────────│
│ 1. Ket noi WiFi: │
│ WiFiSense-Setup │
│ 2. Mo trinh duyet: │
│ 192.168.4.1 │
└──────────────────────────────┘
```
**Vì sao cần hiệu chuẩn?**
**Các bước cấu hình:**
- Mỗi phòng có đặc tính WiFi khác nhau (tường, ni thất, khoảng cách tới router).
- Thuật toán đường nền thích nghi cần điều kiện bình thường làm tham chiếu.
- Nếu không có tham chiếu, hệ thống khó phân biệt nhiễu phòng với chuyển động người.
1. Dùng điện thoại hoặc máy tính, kết ni vào WiFi **`WiFiSense-Setup`** (không mật khẩu).
2. Trình duyệt sẽ tự động mở trang cấu hình (Captive Portal). Nếu không tự mở, truy cập thủ công vào `http://192.168.4.1`.
3. Chọn mạng WiFi nhà bạn từ danh sách quét được.
4. Nhập mật khẩu WiFi → nhấn **Kết nối & Lưu**.
5. ESP32 lưu thông tin vào bộ nhớ NVS và **tự khởi động lại**.
6. Lần này ESP32 kết nối thẳng vào WiFi đã chọn và bắt đầu calibrate.
### Vận hành cơ bản
### Các lần sau (đã có WiFi lưu)
1. Cấp nguồn ESP32-S3.
2. Chờ kết nối WiFi.
3. Giữ phòng yên tĩnh trong giai đoạn hiệu chuẩn.
4. Mở Serial Monitor hoặc Serial Plotter.
5. LED sẽ bật khi phát hiện chuyển động.
6. Serial hiển thị điểm tin cậy và cường độ chuyển động.
ESP32 tự kết nối WiFi khi khởi động, không cần cấu hình lại.
### Theo dõi hiệu năng
### Đổi WiFi
Quan sát Serial Plotter:
Nếu muốn kết nối sang mạng khác: xóa credentials bằng cách mất điện trong khi đang ở chế độ portal, hoặc thêm một nút bấm vật lý để gọi `clearCredentials()` + `ESP.restart()`.
- **Variance:** nên vượt 1,8 khi có chuyển động.
- **ZScore:** có thể vượt 2,5 trong lúc di chuyển.
- **Confidence:** thường trên 50% khi có chuyển động rõ rệt.
### Calibration
### Khắc phục sự cố
Sau khi kết nối WiFi thành công, ESP32 sẽ **calibrate trong ~6 giây** (200 mẫu × 30ms). Trong thời gian này:
| Vấn đề | Cách xử lý |
- **Giữ phòng trống** (không có người di chuyển).
- OLED hiển thị tiến trình calibration.
- Baseline được thiết lập dựa trên RSSI trung bình.
---
## Màn hình OLED
Sau calibration, OLED hiển thị **1 trang duy nhất** cập nhật mỗi 500ms:
```
┌──────────────────────────────┐ ← 128px
│ WiFiSense [ MOTION ] │ dòng 1: tiêu đề + badge trạng thái
│──────────────────────────────│ đường kẻ
│ RSSI: -67dBm C: 82% │ dòng 2: RSSI thô + Confidence số
│ Conf [████████████░░░░░░] │ dòng 3: thanh Confidence
│ Qual [█████████░░░░░░░░░] │ dòng 4: thanh Signal Quality
│──────────────────────────────│ đường kẻ
│ Base:-66.1 Var:2.3 │ dòng 5: Baseline + Variance
│ #15 WALKING │ dòng 6: tổng detections + cường độ
└──────────────────────────────┘
```
### Ý nghĩa các chỉ số
| Chỉ số | Mô tả |
|---|---|
| LED không sáng | Kiểm tra WiFi, `LED_PIN`, và mức kích hoạt `LED_ON_LEVEL` trong `WiFiSense.ino` |
| LED luôn sáng | Tăng `PERSISTENCE_REQUIRED` hoặc ngưỡng phương sai |
| Phát hiện chập chờn | Đặt ESP32-S3 tại vị trí WiFi tốt hơn, cách router 35 m |
| Không có Serial output | Kiểm tra baud rate 115200 và cáp USB có hỗ trợ dữ liệu |
| Nhiều báo động giả | Giảm `ADAPTIVE_ALPHA` xuống 0,005 để đường nền học chậm hơn |
| **RSSI** | Cường độ tín hiệu WiFi thô (dBm). Giá trị điển hình: -40 (gần) đến -90 (xa). |
| **C (Confidence)** | Độ tin cậy phát hiện chuyển động, 0100%. Trên ~50% là có người. |
| **Conf bar** | Thanh trực quan hóa Confidence. |
| **Qual bar** | Chất lượng tín hiệu tổng thể (dựa trên độ ổn định dài hạn). |
| **Base** | Baseline RSSI hiện tại (tự thích nghi). |
| **Var** | Variance của cửa sổ 40 mẫu gần nhất — số càng cao = dao động càng mạnh. |
| **#N** | Tổng số lần phát hiện chuyển động kể từ khi khởi động. |
| **Badge** | `MOTION` (đảo màu trắng) khi phát hiện, `CLEAR` khi yên tĩnh. |
| **Cường độ** | `CALM` / `SLOW` / `WALKING` / `FAST` / `SPRINT` — ước lượng mức độ di chuyển. |
---
## Thông số hiệu năng
## Troubleshooting
| Chỉ số | Giá tr|
### OLED không hiển th
| Nguyên nhân | Giải pháp |
|---|---|
| Độ trễ phát hiện | 3570 ms |
| Tỷ lệ dương tính giả | <5% khi bố trí tốt |
| Tỷ lệ phát hiện đúng | 8592% |
| Công suất tiêu thụ | ~100 mA khi hoạt động |
| Thời gian hiệu chuẩn | 200 mẫu, khoảng 6 giây; nên để trống lâu hơn nếu nhiễu |
| Tầm bố trí tối ưu | 35 m |
| Ngưỡng phương sai tối thiểu | 1,8 dBm |
| Sai địa chỉ I2C | Chạy sketch `I2C Scanner` để tìm địa chỉ thực. Nếu khác `0x3C`, sửa `#define OLED_ADDRESS` thành `0x3D`. |
| Sai chân SDA/SCL | Kiểm tra lại: SDA → GPIO **6**, SCL → GPIO **7**. |
| Nguồn không đủ | Đảm bảo OLED lấy nguồn 3.3V (không phải 5V đối với các module 3.3V). |
| Thư viện chưa cài | Kiểm tra lại Library Manager: `Adafruit SSD1306``Adafruit GFX Library`. |
### Không thấy WiFi "WiFiSense-Setup"
| Nguyên nhân | Giải pháp |
|---|---|
| ESP32 đang kết nối WiFi cũ | Chờ 30 giây timeout, ESP32 sẽ tự chuyển sang AP mode. |
| Credentials cũ còn trong NVS | Upload lại firmware có `clearCredentials()` trong `setup()` (tạm thời), sau đó upload lại bản gốc. |
### Trang cấu hình không tự mở trên điện thoại
Mt số thiết bị Android/iOS không tự kích hoạt captive portal với DNS redirect. Mở trình duyệt và truy cập thủ công: **`http://192.168.4.1`**
### Phát hiện chuyển động không chính xác
| Vấn đề | Giải pháp |
|---|---|
| Phát hiện khi không có người | Giảm `FAST_MOVEMENT_THRESHOLD``SLOW_MOVEMENT_THRESHOLD`, hoặc tăng `PERSISTENCE_REQUIRED`. |
| Không phát hiện khi có người | Đặt ESP32 gần router hơn; tăng `CALIBRATION_SAMPLES`; kiểm tra không có thiết bị khác gây nhiễu. |
| Baseline trôi quá nhanh | Giảm `ADAPTIVE_ALPHA` (ví dụ từ `0.008` xuống `0.003`). |
### Mất kết nối WiFi liên tục
- Kiểm tra khoảng cách tới router. RSSI nên ở mức > -75 dBm để ổn định.
- Sau 3 lần mất kết nối liên tiếp (`MAX_RECONNECT_ATTEMPTS = 3`), ESP32 tự xóa NVS và mở lại Captive Portal — đây là hành vi thiết kế để người dùng có thể đổi mạng.
- Tăng `MAX_RECONNECT_ATTEMPTS` nếu mạng nhà bạn hay bị ngắt tạm thời.
### Upload thất bại (Port not found / No device)
1. Kiểm tra cáp USB (phải là cáp data, không phải cáp sạc).
2. Giữ nút **BOOT** trên board, nhấn **RESET**, thả **RESET**, thả **BOOT**, rồi Upload ngay.
3. Thử port COM khác trong Arduino IDE.
---
## Chi tiết kỹ thuật
## Cấu trúc project
### Sử dụng bộ nhớ
ESP32-S3 có bộ nhớ dư dả cho các buffer và biến xử lý của firmware này. Mức sử dụng Flash/SRAM thực tế phụ thuộc phiên bản Arduino-ESP32, cấu hình board và tùy chọn build.
### Hiệu năng thuật toán
- **Bộ lọc Kalman:** O(1), thời gian hằng.
- **Tính phương sai:** O(40), tuyến tính theo cửa sổ ngắn.
- **Tính Z-score:** O(40), tuyến tính theo cửa sổ ngắn.
- **Chu kỳ đo:** mặc định 35 ms.
### Đặc điểm nhiễu
Phép đo RSSI WiFi thường có:
- **Độ lệch chuẩn:** ±23 dBm do nhiễu ngẫu nhiên.
- **Trôi tín hiệu:** ±5 dBm trong nhiều giờ do thay đổi môi trường.
- **Ngoại lai:** khoảng 15% lần đọc có thể là đột biến.
Bộ lọc Kalman và đường nền thích nghi giúp giảm ảnh hưởng của các hiện tượng này.
```
WiFiSense/
└── WiFiSense.ino ← Toàn bộ code trong 1 file
```
---
## Tài liệu tham khảo
## Tác giả
1. **Đặc tính điện môi của mô người**
- Stogryn, A. (1986). *Equations for calculating the dielectric constant of saline water*.
- Độ hấp thụ của nước ở 2,4 GHz: ~0,15 dB/cm.
2. **Truyền sóng WiFi trong môi trường trong nhà**
- Rappaport, T. S. (2002). *Wireless Communications: Principles and Practice*.
- Mô hình suy hao không gian tự do với các yếu tố môi trường.
3. **Phát hiện bất thường thống kê**
- Chandola, V., và cộng sự (2009). *Anomaly Detection: A Survey*.
- Phương pháp Z-score cho ngoại lai đơn biến.
**Tony Trần** — [github.com/thanhtantran](https://github.com/thanhtantran)
**Orange Pi Việt Nam** — [orangepi.vn](https://orangepi.vn)
---
## Hướng phát triển
## License
Chưa triển khai, nhưng có thể thực hiện:
- [ ] Phân loại bằng học máy (người, thú cưng, luồng gió)
- [ ] Nhiều ESP32-S3 để tam giác hóa
- [ ] Tích hợp home automation qua MQTT
- [ ] Ghi log đám mây về trạng thái có người
- [ ] Học máy huấn luyện theo từng phòng
- [ ] Biến thể WiFi 5 GHz (nhạy hơn nhưng khoảng cách ngắn hơn)
---
## Source-Available License
Copyright (c) 2026 Trần Thanh Tân / [TTAI Solutions Software](https://ttaisolutions.com/).
All rights reserved.
Được phép xem, tải xuống, cài đặt và sử dụng phần mềm này cho mục đích cá nhân, giáo dục và sử dụng nội bộ trong tổ chức.
Được phép sửa đổi cho mục đích cá nhân hoặc sử dụng nội bộ.
Nếu chưa có sự cho phép trước bằng văn bản của chủ sở hữu bản quyền, bạn không được:
1. Bán, bán lại, cấp phép lại hoặc phân phối thương mại phần mềm này hay bất kỳ phần đáng kể nào trong mã nguồn của nó.
2. Cung cấp phần mềm này, dù đã sửa đổi hay chưa, dưới dạng sản phẩm thương mại, dịch vụ lưu trữ hoặc dịch vụ SaaS trả phí.
3. Đóng gói phần mềm này cùng phần cứng hoặc sản phẩm khác để bán lại.
4. Xóa hoặc thay đổi thông báo bản quyền, hoặc nhận mình là tác giả của phần mềm gốc.
Mọi yêu cầu cấp phép thương mại vui lòng gửi tới: https://ttaisolutions.com
---
## Danh sách kiểm tra nhanh
- [ ] ESP32-S3 đã kết nối và cài driver USB
- [ ] Arduino IDE đã cài ESP32 board support
- [ ] Đã cập nhật thông tin WiFi trong code
- [ ] Firmware đã nạp thành công
- [ ] Serial Monitor có dữ liệu
- [ ] LED phản hồi khi có chuyển động
- [ ] Thiết bị được đặt tối ưu, cách router 35 m
- [ ] Đã để thiết bị hiệu chuẩn trong môi trường yên tĩnh
- [ ] Đã thử đi qua giữa router và ESP32-S3
- [ ] OLED hiển thị trang trạng thái WiFiSense
---
**Cần hỗ trợ?** Xem phần khắc phục sự cố trước, sau đó kiểm tra lại vị trí đặt thiết bị — đây là yếu tố quyết định lớn đến độ chính xác.
**Chúc bạn phát hiện hiệu quả!**
MIT License — xem file `LICENSE` để biết thêm chi tiết.