Cảm biến vân tay AS608 / R307 là lựa chọn rất phổ biến trong các dự án IoT kiểm soát truy cập: cửa thông minh, tủ đồ, phòng lab, máy chấm công mini… Module xử lý toàn bộ thuật toán nhận dạng bên trong, ESP32 chỉ cần giao tiếp UART → ổn định, dễ triển khai, phù hợp production nhỏ.
1) AS608 / R307 làm được gì?
Hai module này có tính năng gần như tương đương:
- Đăng ký (Enroll) vân tay
- Nhận diện (Match / Search)
- Lưu ID vân tay trong bộ nhớ trong
- Trả về kết quả nhận dạng + độ tin cậy
- Giao tiếp UART TTL
Thông số chính
- Điện áp: 3.3 – 5V
- Giao tiếp: UART
- Tốc độ baud mặc định: 57600
- Bộ nhớ: ~ 100–200 vân tay (tuỳ module)
👉 Điểm mạnh: không cần xử lý ảnh hay ML trên ESP32.
2) Use case IoT thực tế
- Khoá cửa thông minh
- Check-in phòng học / phòng lab
- Tủ thiết bị cá nhân
- Access control cho IoT Gateway
- Kết hợp dashboard + log truy cập realtime
3) Chuẩn bị phần cứng
- ESP32 (DevKit / ESP32-C3 / ESP32-S3)
- Cảm biến vân tay AS608 hoặc R307
- Dây jumper
- (Tuỳ chọn) relay / solenoid lock để mở khoá
4) Nối dây AS608 / R307 ↔ ESP32 (UART)
Module thường có các chân: VCC, GND, TX, RX
Kết nối khuyến nghị (ESP32 dùng UART2):
| Fingerprint | ESP32 |
|---|---|
| VCC | 5V (hoặc 3V3 nếu module hỗ trợ) |
| GND | GND |
| TX | GPIO16 (RX2) |
| RX | GPIO17 (TX2) |
📌 Lưu ý:
- TX của sensor → RX của ESP32
- RX của sensor → TX của ESP32
5) Nguyên lý hoạt động
- ESP32 gửi lệnh qua UART
- Cảm biến:
- Quét vân tay
- So sánh với DB nội bộ
- Trả về:
finger_idconfidencematch / no match
- ESP32:
- Gửi kết quả lên IoT Dashboard
- Có thể kích hoạt relay / action
6) Cài thư viện Arduino
Trong Arduino IDE → Library Manager:
- Adafruit Fingerprint Sensor Library
Thư viện này hỗ trợ tốt cho AS608 / R307.
7) Code
Ví dụ 1 — Serial-only (đọc vân tay local + in Serial Monitor)
Mục tiêu:
- Kiểm tra wiring UART đúng chưa
- Sensor có phản hồi không
- Quét vân tay → in ra Matched/Not matched, ID, Confidence
- Không Wi-Fi/MQTT (chạy đơn giản, ổn định để debug)
#include <Arduino.h>
#include <Adafruit_Fingerprint.h>
#define FP_RX 16
#define FP_TX 17
#define FP_BAUD 57600
HardwareSerial FPSerial(2);
Adafruit_Fingerprint finger(&FPSerial);
void setup() {
Serial.begin(115200);
delay(200);
FPSerial.begin(FP_BAUD, SERIAL_8N1, FP_RX, FP_TX);
finger.begin(FP_BAUD);
Serial.println("=== Fingerprint Serial-only Test ===");
if (!finger.verifyPassword()) {
Serial.println("[ERROR] Fingerprint sensor not found or wrong password!");
while (true) delay(1000);
}
Serial.println("[OK] Fingerprint sensor ready.");
Serial.println("Place your finger on the sensor...");
}
void loop() {
// 1) Capture image
uint8_t p = finger.getImage();
if (p == FINGERPRINT_NOFINGER) {
delay(80);
return;
}
if (p != FINGERPRINT_OK) {
Serial.println("[WARN] getImage failed");
delay(200);
return;
}
// 2) Convert image to template
p = finger.image2Tz();
if (p != FINGERPRINT_OK) {
Serial.println("[WARN] image2Tz failed");
delay(200);
return;
}
// 3) Search in database
p = finger.fingerFastSearch();
if (p == FINGERPRINT_OK) {
Serial.print("[MATCH] ID=");
Serial.print(finger.fingerID);
Serial.print(" | confidence=");
Serial.println(finger.confidence);
} else {
Serial.println("[NO MATCH] Finger not recognized");
}
// Small delay to avoid spamming
delay(800);
}
✅ Kết quả Serial kỳ vọng:
[OK] Fingerprint sensor ready.- Đặt tay: hiện
[MATCH] ID=... confidence=...hoặc[NO MATCH]
Ví dụ 2 — IoT / MQTT (đọc vân tay + gửi log realtime lên Cloud)
Mục tiêu:
- Nhận diện vân tay
- Gửi event lên MQTT để IoT Dashboard hiển thị log realtime
- Format event gọn, dễ mở rộng
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <Adafruit_Fingerprint.h>
#define FP_RX 16
#define FP_TX 17
#define FP_BAUD 57600
#define PUBLISH_COOLDOWN_MS 800
// WiFi
const char* WIFI_SSID = "YOUR_WIFI";
const char* WIFI_PASS = "YOUR_PASS";
// MQTT
const char* MQTT_HOST = "mqtt.iotlabs.vn";
const int MQTT_PORT = 8883;
const char* MQTT_USER = "YOUR_USER";
const char* MQTT_PASS = "YOUR_PASS";
const char* PROJECT_ID = "demo_project";
const char* DEVICE_ID = "esp32_fingerprint_01";
HardwareSerial FPSerial(2);
Adafruit_Fingerprint finger(&FPSerial);
WiFiClient espClient;
PubSubClient mqtt(espClient);
unsigned long lastPublish = 0;
uint32_t nowSeconds() {
return (uint32_t)(millis() / 1000);
}
void wifiConnect() {
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) delay(300);
}
void mqttConnect() {
mqtt.setServer(MQTT_HOST, MQTT_PORT);
while (!mqtt.connected()) {
mqtt.connect(DEVICE_ID, MQTT_USER, MQTT_PASS);
delay(500);
}
}
void publishResult(bool matched, int fingerId, int confidence) {
String topic = String("iotlabs/") + PROJECT_ID + "/" + DEVICE_ID + "/event";
StaticJsonDocument<256> doc;
doc["ts"] = nowSeconds();
doc["type"] = "fingerprint";
JsonObject data = doc.createNestedObject("data");
data["matched"] = matched;
data["finger_id"] = fingerId;
data["confidence"] = confidence;
char payload[256];
size_t n = serializeJson(doc, payload, sizeof(payload));
mqtt.publish(topic.c_str(), payload, n);
}
void setup() {
Serial.begin(115200);
delay(200);
FPSerial.begin(FP_BAUD, SERIAL_8N1, FP_RX, FP_TX);
finger.begin(FP_BAUD);
Serial.println("=== Fingerprint MQTT Mode ===");
if (!finger.verifyPassword()) {
Serial.println("[ERROR] Fingerprint sensor not found!");
while (true) delay(1000);
}
wifiConnect();
mqttConnect();
Serial.println("[OK] Ready. Place your finger...");
}
void loop() {
if (WiFi.status() != WL_CONNECTED) wifiConnect();
if (!mqtt.connected()) mqttConnect();
mqtt.loop();
// Rate-limit publishing
if (millis() - lastPublish < PUBLISH_COOLDOWN_MS) {
delay(50);
return;
}
uint8_t p = finger.getImage();
if (p == FINGERPRINT_NOFINGER) {
delay(80);
return;
}
if (p != FINGERPRINT_OK) {
Serial.println("[WARN] getImage failed");
delay(200);
return;
}
p = finger.image2Tz();
if (p != FINGERPRINT_OK) {
Serial.println("[WARN] image2Tz failed");
delay(200);
return;
}
p = finger.fingerFastSearch();
if (p == FINGERPRINT_OK) {
Serial.printf("[MATCH] ID=%d | confidence=%d\n", finger.fingerID, finger.confidence);
publishResult(true, finger.fingerID, finger.confidence);
} else {
Serial.println("[NO MATCH]");
publishResult(false, -1, 0);
}
lastPublish = millis();
}
So sánh
- Ví dụ 1 (Serial-only)
- ✅ Dễ test phần cứng, debug nhanh
- ✅ Không phụ thuộc Wi-Fi/MQTT
- ❌ Không có log dashboard, không lưu lịch sử
- Ví dụ 2 (MQTT/Cloud)
- ✅ Có log realtime trên IoT Dashboard
- ✅ Dễ làm rule cảnh báo (failed attempts, ngoài giờ…)
- ❌ Phụ thuộc Wi-Fi/MQTT (nên test bằng Ví dụ 1 trước)
8) Dashboard realtime
Realtime log:
- Finger ID
- Thời gian
- Trạng thái: matched / failed
- Confidence
Card gợi ý:
- Total access today
- Failed attempts
- Last access user
Rule cảnh báo:
- Failed > 5 lần / phút → cảnh báo an ninh
- Truy cập ngoài giờ → notify admin
9) Quy trình đăng ký vân tay (Enroll)
Thông thường:
- Chạy sketch enroll (1 lần)
- Đặt vân tay 2–3 lần
- Gán finger_id
- Lưu vào bộ nhớ module
👉 Enroll không cần làm lại sau khi reset ESP32.
10) Gợi ý mở rộng
- Kết hợp relay / khoá điện
- Phân quyền user theo
finger_id - Lưu lịch sử vào DB (audit log)
- Kết hợp RFID + Fingerprint (2FA)
- Offline-first: cho phép mở khoá ngay cả khi mất mạng


