Датчик отпечатков пальцев и Arduino: AS608, R307 и дверной замок
Как подключить датчик отпечатков пальцев к Arduino: цвета проводов и питание AS608/R307, регистрация и проверка с Adafruit Fingerprint, замок на реле, ESP32 и решение проблем.
Датчик отпечатков пальцев позволяет Arduino-проекту одним касанием спросить «кто ты?» и открыть дверь, ящик или сейф, когда палец узнан. Самые распространённые модели в любительской электронике — оптические модули на базе AS608 и R307: они сами обрабатывают изображение пальца, хранят отпечатки в собственной памяти и отправляют Arduino только короткий ответ вроде «совпадение с ID 3». Поэтому даже небольшая плата вроде Arduino Uno легко справится с замком по отпечатку на сотни человек.
В этом руководстве разберём, как работает датчик, как правильно его подключить, даже если цвета проводов у разных производителей отличаются, как регистрировать (enroll) и проверять отпечатки с библиотекой Adafruit Fingerprint и что означают ID и оценка достоверности. Затем соберём настоящий дверной замок с реле и соленоидом на 12 V, сделаем то же самое на ESP32 и Raspberry Pi Pico и пошагово устраним печально известную ошибку «Did not find fingerprint sensor».

Что такое датчик отпечатков пальцев и как он работает?
Модули вроде AS608 и R307 — это оптические датчики. Когда палец лежит на стекле, светодиод внутри подсвечивает призму под ним; гребни папиллярных линий касаются стекла и отражают свет иначе, чем бороздки, которые стекла не касаются. Крошечная камера снимает этот узор как изображение в оттенках серого с разрешением около 500 dpi. DSP-чип модуля находит точки, где линии обрываются или раздваиваются (минуции), и превращает их в файл признаков (character file) размером в несколько сотен байт. Два файла признаков одного пальца объединяются в шаблон (template), и этот шаблон сохраняется во встроенной флеш-памяти датчика под номером ID.
При проверке датчик снова превращает новое изображение в файл признаков и сравнивает его со всеми сохранёнными шаблонами. Такой поиск 1:N обычно занимает меньше секунды; в конце датчик возвращает ID совпавшей записи и оценку достоверности (confidence), которая показывает, насколько надёжно совпадение. Главное: изображение отпечатка вообще не попадает в Arduino, вся тяжёлая работа выполняется внутри датчика. Arduino лишь отправляет команды по последовательному порту (UART) и читает короткие ответы.
| Характеристика | Модуль AS608 | R307 | FPM10A / ZFM-20 |
|---|---|---|---|
| Питание | 3,3 V | 4,2–6 V (обычно 5 V) | 3,6–6 V |
| Число записей | Обычно 300 (на некоторых платах 162) | 1000 | 162 |
| Интерфейс | UART (TTL), по умолчанию 57600 бод | UART (TTL), по умолчанию 57600 бод | UART (TTL), по умолчанию 57600 бод |
| Пин обнаружения касания | Есть (WAK + Vt) | Есть (Touch + 3.3VT) | У большинства нет |
| Уровень безопасности | 1–5 | 1–5 | 1–5 |
| Вероятность ложного допуска (FAR) | < 0,001% | < 0,001% | < 0,001% |
| Библиотека для Arduino | Adafruit Fingerprint | Adafruit Fingerprint | Adafruit Fingerprint |
Значения в таблице могут зависеть от продавца и ревизии платы, особенно ёмкость памяти. Надёжнее всего запустить тестовый скетч ниже и прочитать ёмкость, которую сообщает датчик. Заодно определимся с тремя терминами: ID — номер ячейки шаблона в памяти (от 0 до ёмкости минус один); уровень безопасности задаёт порог совпадения от 1 (самый мягкий) до 5 (самый строгий); а оценка достоверности — это степень сходства, которую датчик возвращает при каждом совпадении.
Цвета проводов и питание: какой провод куда?
Самая частая ошибка с датчиками отпечатков — считать, что цвета проводов стандартные. Одна и та же модель у одного продавца приходит с красным, чёрным, жёлтым и белым проводами, а у другого — с красным, чёрным, зелёным и синим; даже Adafruit приводит разные схемы цветов для разных версий датчика. Поэтому не ориентируйся на цвет: смотри надписи у пинов на обороте датчика или рядом с разъёмом и схему продавца. У модулей AS608 обычно 6 пинов: V+ (Vi), TX, RX, GND, WAK (Touch) и Vt (3.3VT). Для базового использования хватит первых четырёх.
| Пин датчика | Назначение | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|---|
| V+ / Vi / VCC | Питание | 3.3V (AS608) или 5V (R307) | 3V3 (5V/VIN для R307) | 3V3(OUT) (VBUS для R307) |
| GND | Земля | GND | GND | GND |
| TX | Выход данных датчика | D2 (SoftwareSerial RX) | GPIO 16 (RX2) | GP1 (UART0 RX) |
| RX | Вход данных датчика | D3 (SoftwareSerial TX) | GPIO 17 (TX2) | GP0 (UART0 TX) |
| WAK / Touch | Сигнал обнаружения пальца (необязательно) | D4 | GPIO 27 | GP2 |
| Vt / 3.3VT | Питание схемы обнаружения касания (необязательно) | 3.3V | 3V3 | 3V3(OUT) |
Пин WAK (или Touch) подключён к маломощной схеме обнаружения касания внутри датчика. Если на пин Vt подано 3,3 V, уровень на WAK меняется в тот момент, когда палец касается стекла; на большинстве модулей он становится HIGH, на некоторых LOW, так что проверь это на своей плате. В замке на батарейках можно отключать основное питание MOSFET-ом, оставив запитанным только Vt, а сигналом WAK будить микроконтроллер из сна и только тогда включать датчик.
Установка библиотеки Adafruit Fingerprint
- В Arduino IDE открой Инструменты › Управлять библиотеками (Tools › Manage Libraries), найди Adafruit Fingerprint Sensor Library и установи её. Если библиотеки раньше не добавлялись, загляни в статью Как добавить библиотеку в Arduino.
- Библиотека работает со всеми датчиками с тем же набором команд — AS608, R307, R503, FPM10A и серией ZFM; менять код не нужно.
- В меню «Файл › Примеры» (File › Examples) есть примеры enroll (регистрация), fingerprint (проверка), delete (удаление одной записи) и emptyDatabase (удаление всех записей).
- На Uno и Nano датчик подключают к D2 и D3 через SoftwareSerial, чтобы не занимать пины 0 и 1, которые использует USB-соединение. На платах со вторым аппаратным последовательным портом, таких как Mega, Leonardo и ESP32, используется Serial1 или Serial2.
Первый тест: находится ли датчик?
Прежде чем регистрировать отпечатки, убедимся, что датчик общается с Arduino. Скетч ниже сначала ищет датчик на стандартной скорости 57600 бод, а если не находит, пробует другие распространённые скорости. Найдя датчик, он выводит в монитор порта скорость, на которой датчик ответил, заявленную ёмкость, уровень безопасности и число сохранённых отпечатков. Не забудь выставить в мониторе порта 9600 бод — это не зависит от скорости датчика.
1#include <Adafruit_Fingerprint.h>
2#include <SoftwareSerial.h>
3
4SoftwareSerial fpSerial(2, 3); // D2 = RX (sensör TX), D3 = TX (sensör RX) / D2 = RX (sensor TX), D3 = TX (sensor RX)
5Adafruit_Fingerprint finger(&fpSerial);
6
7const uint32_t rates[] = {57600, 9600, 19200, 38400, 115200}; // denenecek hızlar / baud rates to try
8
9void setup() {
10 Serial.begin(9600);
11 Serial.println(F("Sensor araniyor / searching for sensor..."));
12 bool found = false;
13 for (uint8_t i = 0; i < 5 && !found; i++) {
14 finger.begin(rates[i]); // 1 sn bekler, portu açar / waits 1 s, opens the port
15 if (finger.verifyPassword()) { // sensör cevap verdi mi? / did the sensor answer?
16 Serial.print(F("Bulundu / found @ "));
17 Serial.println(rates[i]);
18 found = true;
19 }
20 }
21 if (!found) {
22 Serial.println(F("Did not find fingerprint sensor :("));
23 while (1) delay(1);
24 }
25 finger.getParameters(); // kapasite ve ayarları oku / read capacity and settings
26 Serial.print(F("Kapasite / capacity: "));
27 Serial.println(finger.capacity);
28 Serial.print(F("Guvenlik / security level: "));
29 Serial.println(finger.security_level);
30 finger.getTemplateCount(); // kayıtlı şablon sayısı / number of stored templates
31 Serial.print(F("Kayitli iz / templates: "));
32 Serial.println(finger.templateCount);
33}
34
35void loop() {
36}Регистрация отпечатка (enroll) шаг за шагом
При регистрации датчик делает два отдельных снимка одного и того же пальца, сохраняет их как файлы признаков в двух буферах (CharBuffer1 и CharBuffer2), объединяет их в шаблон и записывает шаблон под выбранным ID. Готовый пример enroll от Adafruit запрашивает ID от 1 до 127 и хранит его в однобайтовой переменной. Упрощённая версия ниже хранит ID в 16 битах и берёт верхнюю границу из реальной ёмкости датчика, так что можно использовать все ячейки датчика на 300 или 1000 отпечатков. Шаги в библиотеке такие:
- getImage(): пытается получить изображение, пока палец не окажется на стекле; если пальца нет, возвращает FINGERPRINT_NOFINGER.
- image2Tz(1): превращает первое изображение в файл признаков и кладёт его в буфер 1.
- Палец убирают и снова прикладывают тот же палец; image2Tz(2) кладёт второе изображение в буфер 2.
- createModel(): сравнивает и объединяет два буфера; если они не совпадают, возвращает FINGERPRINT_ENROLLMISMATCH.
- storeModel(id): навсегда записывает шаблон во флеш-память датчика; при отключении питания он не стирается.
1#include <Adafruit_Fingerprint.h>
2#include <SoftwareSerial.h>
3
4SoftwareSerial fpSerial(2, 3); // D2 = RX, D3 = TX
5Adafruit_Fingerprint finger(&fpSerial);
6
7void setup() {
8 Serial.begin(9600);
9 finger.begin(57600);
10 if (!finger.verifyPassword()) {
11 Serial.println(F("Did not find fingerprint sensor :("));
12 while (1) delay(1);
13 }
14 finger.getParameters(); // gerçek kapasiteyi öğren / learn the real capacity
15 Serial.println(F("Kayit modu / enroll mode"));
16}
17
18// Parmak gelene kadar bekle, görüntüyü tampona çevir / wait for a finger, convert the image into a buffer
19bool captureTo(uint8_t slot) {
20 while (finger.getImage() != FINGERPRINT_OK) delay(50);
21 uint8_t p = finger.image2Tz(slot);
22 if (p != FINGERPRINT_OK) {
23 Serial.print(F("Goruntu kotu / bad image, kod / code 0x"));
24 Serial.println(p, HEX);
25 return false;
26 }
27 return true;
28}
29
30void loop() {
31 Serial.print(F("ID gir / enter ID (1-"));
32 Serial.print(finger.capacity - 1);
33 Serial.println(F("):"));
34 while (!Serial.available()) delay(10);
35 uint16_t id = Serial.parseInt();
36 while (Serial.available()) Serial.read(); // satır sonunu temizle / clear the line ending
37 if (id == 0 || id >= finger.capacity) return;
38
39 Serial.println(F("Parmagini koy / place your finger"));
40 if (!captureTo(1)) return;
41 Serial.println(F("Kaldir / remove your finger"));
42 delay(1000);
43 while (finger.getImage() != FINGERPRINT_NOFINGER) delay(50); // parmak kalkana kadar / until the finger is lifted
44
45 Serial.println(F("Ayni parmagi tekrar koy / place the same finger again"));
46 if (!captureTo(2)) return;
47
48 uint8_t p = finger.createModel(); // iki görüntüyü birleştir / merge the two images
49 if (p == FINGERPRINT_ENROLLMISMATCH) {
50 Serial.println(F("Fingerprints did not match"));
51 return;
52 }
53 if (p != FINGERPRINT_OK) return;
54
55 p = finger.storeModel(id); // sensörün flash belleğine yaz / write to the sensor's flash
56 if (p == FINGERPRINT_OK) {
57 Serial.print(F("Kaydedildi / stored, ID #"));
58 Serial.println(id);
59 } else {
60 Serial.print(F("Kayit hatasi / store error 0x"));
61 Serial.println(p, HEX);
62 }
63}Проверка отпечатка: ID и оценка достоверности
Для проверки сначала получают изображение через getImage(), преобразуют его через image2Tz(), а затем ищут среди сохранённых шаблонов. В библиотеке две функции поиска: fingerFastSearch() работает быстро, но команда, которую отправляет библиотека, просматривает только первые 163 записи (ID 0–162); fingerSearch() ищет по всей ёмкости, прочитанной через getParameters(). Если нужны ID больше 162, используй fingerSearch() и обязательно вызывай getParameters() в setup(); иначе библиотека считает ёмкость равной 64 по умолчанию и ищет только среди первых 64 записей.
При успешном поиске finger.fingerID содержит номер совпавшей записи, а finger.confidence — оценку достоверности. Решение о совпадении датчик и так принимает по уровню безопасности; оценка лишь показывает, насколько совпадение надёжно. С хорошо зарегистрированным пальцем оценка обычно лежит в диапазоне от нескольких десятков до нескольких сотен. Для более строгого замка можно поднять порог через setSecurityLevel(4) или setSecurityLevel(5) либо добавить в коде свой нижний предел (например, отклонять всё, что ниже 50). Чем выше порог, тем меньше шанс впустить чужого, но тем больше шанс отказать своему; найди баланс, проверяя на своих пальцах.
| Код возврата | Сообщение в мониторе порта | Значение и решение |
|---|---|---|
| FINGERPRINT_OK (0x00) | Image taken / Stored! (снимок получен / сохранено) | Операция выполнена успешно. |
| FINGERPRINT_NOFINGER (0x02) | No finger detected (палец не обнаружен) | На стекле нет пальца; продолжай ждать в цикле. |
| FINGERPRINT_PACKETRECIEVEERR (0x01) | Communication error (ошибка связи) | Ответный пакет не получен; проверь подключение, скорость и питание. |
| FINGERPRINT_IMAGEFAIL (0x03) | Imaging error (ошибка съёмки) | Не удалось получить изображение; приложи палец ещё раз. |
| FINGERPRINT_IMAGEMESS (0x06) | Image too messy (изображение слишком нечёткое) | Размытое изображение; протри стекло, палец может быть слишком влажным или слишком сухим. |
| FINGERPRINT_FEATUREFAIL (0x07) | Could not find fingerprint features (не найдены признаки отпечатка) | Недостаточно деталей; приложи палец по центру и слегка прижми. |
| FINGERPRINT_NOTFOUND (0x09) | Did not find a match (совпадение не найдено) | Подходящей записи нет; палец не зарегистрирован или зарегистрирован плохо. |
| FINGERPRINT_ENROLLMISMATCH (0x0A) | Fingerprints did not match (отпечатки не совпали) | Два снимка при регистрации не совпали; повтори процедуру. |
| FINGERPRINT_BADLOCATION (0x0B) | Could not store in that location (не удалось сохранить в эту ячейку) | ID за пределами ёмкости; узнай предел через getParameters(). |
| FINGERPRINT_FLASHERR (0x18) | Error writing to flash (ошибка записи во флеш-память) | Не удалось записать в память датчика; проверь питание и подключение. |
Дверной замок по отпечатку пальца с реле и соленоидом
Теперь соберём всё вместе и сделаем дверной замок, который открывается на 3 секунды для разрешённого пальца, трижды пищит при неизвестном и блокирует систему на 30 секунд после 5 неудачных попыток подряд. В качестве замка используем соленоидный замок на 12 V. Соленоид потребляет 0,5–1 A, поэтому его ни в коем случае нельзя подключать напрямую к пину Arduino; между ними нужен модуль реле или MOSFET с логическим уровнем управления. Подключение: VCC и GND модуля реле — к 5V и GND Arduino, его пин IN — к D8, активный зуммер — к D9, плюс адаптера 12 V — к клемме COM реле, клемма NO реле — к плюсу соленоида, а минус соленоида — к минусу адаптера.
Соленоид — это катушка, и в момент отключения тока она выдаёт высокое обратное напряжение. Поэтому параллельно соленоиду в обратном направлении подключи диод 1N4007; конец диода с полоской идёт к плюсу. Если вместо реле используется MOSFET, выбери модель с логическим уровнем управления, например IRLZ44N, и соедини минус источника 12 V с GND Arduino. Подробности — в статье Управление большими токами с помощью MOSFET, а порядок выводов MOSFET можно посмотреть в утилите распиновки транзисторов.
1#include <Adafruit_Fingerprint.h>
2#include <SoftwareSerial.h>
3
4SoftwareSerial fpSerial(2, 3); // D2 = RX, D3 = TX
5Adafruit_Fingerprint finger(&fpSerial);
6
7const int RELAY_PIN = 8; // röle modülü IN / relay module IN
8const int BUZZER_PIN = 9; // aktif buzzer / active buzzer
9const uint8_t RELAY_ON = LOW; // çoğu röle modülü LOW ile çeker / most relay modules switch on LOW
10const uint8_t RELAY_OFF = HIGH;
11const uint16_t MIN_CONFIDENCE = 50; // ek güven eşiği / extra confidence threshold
12const unsigned long OPEN_MS = 3000; // kilidin açık kalma süresi / unlock time
13
14uint8_t failCount = 0;
15
16void setup() {
17 digitalWrite(RELAY_PIN, RELAY_OFF); // açılışta kilitli kalsın / stay locked at power-up
18 pinMode(RELAY_PIN, OUTPUT);
19 pinMode(BUZZER_PIN, OUTPUT);
20 Serial.begin(9600);
21 finger.begin(57600);
22 if (!finger.verifyPassword()) {
23 Serial.println(F("Did not find fingerprint sensor :("));
24 while (1) delay(1);
25 }
26 finger.getParameters(); // fingerSearch için kapasite / capacity for fingerSearch
27}
28
29// Eşleşen ID; parmak yoksa -1, tanınmadıysa -2 / matching ID; -1 no finger, -2 not recognised
30int readFinger() {
31 if (finger.getImage() != FINGERPRINT_OK) return -1;
32 if (finger.image2Tz(1) != FINGERPRINT_OK) return -2;
33 if (finger.fingerSearch(1) != FINGERPRINT_OK) return -2;
34 if (finger.confidence < MIN_CONFIDENCE) return -2;
35 return finger.fingerID;
36}
37
38void beep(int count, int ms) {
39 for (int i = 0; i < count; i++) {
40 digitalWrite(BUZZER_PIN, HIGH);
41 delay(ms);
42 digitalWrite(BUZZER_PIN, LOW);
43 delay(ms);
44 }
45}
46
47void loop() {
48 int id = readFinger();
49 if (id >= 0) {
50 Serial.print(F("Hos geldin / welcome, ID #"));
51 Serial.print(id);
52 Serial.print(F(", guven / confidence "));
53 Serial.println(finger.confidence);
54 failCount = 0;
55 beep(1, 100);
56 digitalWrite(RELAY_PIN, RELAY_ON); // kilidi aç / unlock
57 delay(OPEN_MS);
58 digitalWrite(RELAY_PIN, RELAY_OFF); // yeniden kilitle / lock again
59 } else if (id == -2) {
60 failCount++;
61 Serial.println(F("Yetkisiz / not authorised"));
62 beep(3, 80);
63 if (failCount >= 5) { // 5 hatada 30 sn bekle / 30 s lockout after 5 failures
64 Serial.println(F("30 sn kilitli / locked for 30 s"));
65 delay(30000);
66 failCount = 0;
67 }
68 delay(1000);
69 }
70 delay(50);
71}Датчик отпечатков пальцев с ESP32: подключение к Serial2
У ESP32 три аппаратных последовательных порта, поэтому SoftwareSerial не нужен: датчик подключается к UART2 (Serial2). ESP32 работает от 3,3 V, поэтому её уровни сигналов в точности совпадают с уровнями AS608, и делитель напряжения не нужен. Следить нужно только за пинами: в актуальном ядре Arduino-ESP32 (3.x) пины Serial2 по умолчанию уже не GPIO 16/17, как в старых руководствах, а GPIO 4 (RX) и GPIO 25 (TX). Поэтому пины нужно явно передать в Serial2.begin(); функция begin() библиотеки сохраняет заданные ранее пины. Карту пинов своей платы можно посмотреть в утилите распиновки.
1#include <Adafruit_Fingerprint.h>
2
3#define FP_RX 16 // ESP32 RX2 <- sensör TX / sensor TX
4#define FP_TX 17 // ESP32 TX2 -> sensör RX / sensor RX
5const int RELAY_PIN = 23; // röle modülü IN / relay module IN
6
7Adafruit_Fingerprint finger(&Serial2);
8
9void setup() {
10 Serial.begin(115200);
11 pinMode(RELAY_PIN, OUTPUT);
12 digitalWrite(RELAY_PIN, HIGH); // LOW tetiklemeli röle kapalı / active-LOW relay off
13 Serial2.begin(57600, SERIAL_8N1, FP_RX, FP_TX); // pinleri açıkça ver / set the pins explicitly
14 finger.begin(57600); // önceki pinleri korur / keeps the pins set above
15 if (!finger.verifyPassword()) {
16 Serial.println("Did not find fingerprint sensor :(");
17 while (true) delay(10);
18 }
19 finger.getParameters();
20 finger.getTemplateCount();
21 Serial.printf("Kapasite / capacity: %u, kayitli / stored: %u\n", finger.capacity, finger.templateCount);
22}
23
24void loop() {
25 if (finger.getImage() == FINGERPRINT_OK && finger.image2Tz(1) == FINGERPRINT_OK) {
26 if (finger.fingerSearch(1) == FINGERPRINT_OK) {
27 Serial.printf("ID #%u, guven / confidence %u\n", finger.fingerID, finger.confidence);
28 digitalWrite(RELAY_PIN, LOW); // kilidi aç / unlock
29 delay(3000);
30 digitalWrite(RELAY_PIN, HIGH); // yeniden kilitle / lock again
31 } else {
32 Serial.println("Did not find a match");
33 delay(1000);
34 }
35 }
36 delay(50);
37}На платах с модулем ESP32-WROVER пины GPIO 16 и 17 подключены к PSRAM; на такой плате замени FP_RX и FP_TX, например, на 25 и 26. У ESP32-C3 всего два UART, поэтому Serial2 нет; тот же код работает с Serial1 и любыми двумя удобными пинами. Благодаря Wi-Fi можно записывать каждый вход с отметкой времени на сервер или при неизвестном пальце отправлять уведомление на телефон через Telegram-бота.
Датчик отпечатков пальцев с Raspberry Pi Pico и MicroPython
Официальной версии библиотеки Adafruit для MicroPython нет, но протокол датчика настолько простой, что общаться с ним можно напрямую в несколько строк. Каждый пакет начинается со стартового кода EF 01, за ним идут 4-байтовый адрес (по умолчанию FF FF FF FF), тип пакета (01 — команда, 07 — ответ), 2-байтовая длина, команда с параметрами и в конце 2-байтовая контрольная сумма — сумма байтов типа, длины и данных. Первый байт данных в ответе — код подтверждения: 00 — успех, 02 — нет пальца, 09 — нет совпадения. Код ниже проверяет связь с датчиком, читает ёмкость и распознаёт приложенный палец, выдавая ID и оценку достоверности. Pico работает от 3,3 V, поэтому AS608 можно подключить прямо к пину 3V3(OUT); если Pico пока в новинку, хорошее начало — статья Что такое Raspberry Pi Pico?
1from machine import UART, Pin
2import time
3
4# GP0 = UART0 TX -> sensör RX, GP1 = UART0 RX <- sensör TX / sensor RX, sensor TX
5uart = UART(0, baudrate=57600, tx=Pin(0), rx=Pin(1), timeout=2000, timeout_char=100)
6HEADER = b'\xEF\x01\xFF\xFF\xFF\xFF' # başlangıç kodu + adres / start code + address
7
8def command(*data):
9 while uart.any(): # eski baytları at / drop stale bytes
10 uart.read()
11 length = len(data) + 2 # veri + 2 bayt sağlama / data + 2-byte checksum
12 body = bytes([0x01, length >> 8, length & 0xFF]) + bytes(data) # 0x01 = komut paketi / command packet
13 s = sum(body)
14 uart.write(HEADER + body + bytes([(s >> 8) & 0xFF, s & 0xFF]))
15 head = uart.read(9) # başlık + tip + uzunluk / header + type + length
16 if not head or len(head) < 9 or head[0] != 0xEF:
17 return None
18 n = (head[7] << 8) | head[8]
19 rest = uart.read(n)
20 if not rest or len(rest) < n:
21 return None
22 return rest[:-2] # sağlama hariç veri / data without checksum
23
24def ok(r):
25 return r is not None and r[0] == 0x00 # 0x00 = başarılı / success
26
27time.sleep(1) # sensörün açılmasını bekle / let the sensor boot up
28if not ok(command(0x13, 0, 0, 0, 0)): # VfyPwd: şifre 0 / password 0
29 print("Did not find fingerprint sensor")
30 while True:
31 time.sleep(1)
32
33p = command(0x0F) # ReadSysPara: sistem parametreleri / system parameters
34capacity = (p[5] << 8) | p[6] if ok(p) else 162
35print("Kapasite / capacity:", capacity)
36
37def identify():
38 if not ok(command(0x01)): # GenImg: parmak yoksa 0x02 / 0x02 = no finger
39 return None
40 if not ok(command(0x02, 1)): # Img2Tz: CharBuffer1'e çevir / convert into CharBuffer1
41 return (-1, 0)
42 r = command(0x04, 1, 0, 0, capacity >> 8, capacity & 0xFF) # Search: tüm kayıtlar / all records
43 if not ok(r):
44 return (-1, 0) # 0x09 = eşleşme yok / no match
45 return ((r[1] << 8) | r[2], (r[3] << 8) | r[4]) # (ID, güven / confidence)
46
47while True:
48 res = identify()
49 if res:
50 fid, score = res
51 if fid >= 0:
52 print("ID", fid, "guven / confidence", score)
53 else:
54 print("Eslesme yok / no match")
55 time.sleep(1)
56 time.sleep_ms(100)Ошибка «Did not find fingerprint sensor» и другие частые проблемы
Это сообщение означает, что библиотека не получила от датчика корректного ответа на команду verifyPassword(); оно не значит, что датчик сломан. В подавляющем большинстве случаев дело в подключении, питании или неверной скорости. Пройди по таблице ниже сверху вниз:
| Симптом | Вероятная причина | Решение |
|---|---|---|
| Did not find fingerprint sensor :( (датчик не найден) | TX и RX соединены напрямую, а не крест-накрест | TX датчика идёт на RX Arduino (D2), а RX — на TX (D3). Если поменять два провода данных местами, ничего не сгорит, так что попробуй. |
| Did not find fingerprint sensor :( (датчик не найден) | Подключение по цветам проводов | Переподключи по надписям пинов на плате или по схеме продавца; проверь GND мультиметром. |
| Did not find fingerprint sensor :( (датчик не найден) | Неправильное или недостаточное питание | Подай на AS608 3,3 V, а на R307 5 V; если пина 3.3V у Uno не хватает, используй внешний стабилизатор и соедини земли. |
| Did not find fingerprint sensor :( (датчик не найден) | Датчик работает на другой скорости | Запусти перебор скоростей из первого тестового скетча и подставь найденное значение в finger.begin(). |
| Did not find fingerprint sensor :( (датчик не найден) | Пароль датчика изменён | Передай пароль в конструктор: Adafruit_Fingerprint finger(&fpSerial, 0x12345678); |
| Датчик не находится на Mega или Leonardo | SoftwareSerial может принимать данные не на всех пинах | Используй Serial1: на Mega RX1 19, TX1 18; на Leonardo RX 0, TX 1. |
| Датчик не находится на ESP32 | Другие пины Serial2 по умолчанию или конфликт с PSRAM | Задай пины явно: Serial2.begin(57600, SERIAL_8N1, RX, TX); на WROVER не используй 16/17. |
| Частая ошибка «Communication error» (ошибка связи) | Разболтанный разъём, длинные или тонкие провода | Делай провода короткими, вместо макетной платы используй пайку и добавь конденсатор 100 µF по питанию. |
| Зарегистрированный палец часто отклоняется | Грязное стекло, сухой или влажный палец, регистрация только под одним углом | Протри стекло мягкой тканью, зарегистрируй тот же палец под двумя ID и при необходимости снизь уровень безопасности до 2. |
| Датчик греется, светодиод не загорается | Перепутана полярность питания или на AS608 подано 5 V | Немедленно отключи питание и исправь подключение; датчик, возможно, уже повреждён. |
Сканер отпечатков Waveshare с UART: короткая заметка

Хотя внешне он похож, сканер отпечатков Waveshare с UART работает по другому протоколу, чем AS608 и R307: команды длиной 8 байт, начинаются и заканчиваются байтом 0xF5, а скорость по умолчанию — 19200 бод. Поэтому с библиотекой Adafruit Fingerprint он не работает; вместо неё используются таблица команд и примеры кода из руководства пользователя Waveshare. При регистрации палец сканируется три раза, каждому пользователю можно назначить уровень доступа от 1 до 3, а сравнение 1:N выполняется одной командой. Плату можно питать от 3,3 V или 5 V; TXD подключается к RX микроконтроллера, а RXD — к его TX. Если нужно много готовых библиотек и примеров, выбирай AS608 или R307; если написание своего кода протокола не пугает, Waveshare — хороший вариант.
Идеи проектов с датчиком отпечатков пальцев
- Ящик или сейф по отпечатку: небольшой сейф, который открывается сервоприводом или соленоидом и поднимает тревогу при попытке чужого доступа. О фиксаторе на сервоприводе — в статье Что такое сервопривод?
- Двухэтапная дверь: более защищённый вход, который сначала запрашивает отпечаток, а затем PIN-код на матричной клавиатуре.
- Карта или палец: добавь к тому же замку считыватель RFID RC522, чтобы владельцы карт входили по карте, а остальные — по отпечатку.
- Система учёта посещаемости: сопоставь каждый ID с именем для школы или кружка и записывай время входа.
- Замок с дисплеем: выводи приветствие и имя человека на OLED-дисплей.
- Вместе с домашней сигнализацией: сигнализация на Arduino, которая ставится на охрану и снимается с неё по отпечатку пальца.
Несколько проводов и подходящая библиотека — и датчик отпечатков пальцев добавляет в твой проект настоящий уровень проверки личности: сначала протестируй датчик, аккуратно зарегистрируй пальцы, а потом собери замок с реле и соленоидом. В приложении BlueGrays есть проекты по безопасности — «Умный электронный сейф», «RFID-аутентификация», «Дверной замок с RFID на ESP32» и «Кодовый замок с клавиатурой» — с пошаговыми схемами подключения и кодом; это готовая основа, к которой можно добавить датчик отпечатков.
Частые вопросы
Сколько отпечатков может хранить датчик отпечатков пальцев?
Зависит от модели: платы AS608 обычно хранят 300 (некоторые 162), R307 — 1000, а FPM10A и ZFM-20 — 162. Чтобы узнать ёмкость своего датчика, вызови getParameters() и выведи finger.capacity в монитор порта. Учти, что один палец, зарегистрированный под двумя ID, занимает две ячейки.
Датчик отпечатков пальцев работает от 5 V или от 3,3 V?
Большинству плат AS608 нужно 3,3 V, а R307 работает от 4,2–6 V, обычно от 5 V. Не подавай питание, пока не проверишь надпись на датчике и характеристики от продавца. Если TX-выход Arduino на 5 V подключается к RX датчика на 3,3 V, безопаснее всего использовать делитель напряжения.
Где хранятся отпечатки — в Arduino? И стираются ли они при отключении питания?
Нет, шаблоны хранятся во встроенной флеш-памяти датчика и при отключении питания не стираются. Даже если заменить Arduino или загрузить новый код, записи останутся в датчике. На стороне Arduino нужно только помнить, какой ID кому принадлежит; при желании это можно сохранить в EEPROM.
Как исправить ошибку «Did not find fingerprint sensor»?
Сначала убедись, что TX и RX соединены крест-накрест: TX датчика идёт на пин RX Arduino (D2 на Uno). Затем проверь, что питание нужного напряжения и с достаточным током, а земли общие. Если датчик всё равно не находится, возможно, он работает на другой скорости или с паролем; запусти тестовый скетч, который перебирает несколько скоростей.
Чем AS608 отличается от R307?
Оба — оптические датчики с одним и тем же набором команд, и с библиотекой Adafruit Fingerprint они работают на одном и том же коде. Главные отличия — питание и ёмкость: платы AS608 обычно работают от 3,3 V и хранят около 300 записей, а R307 работает от 5 V и вмещает 1000. Перед подключением сверь порядок пинов по маркировке своей модели.
Как удалить сохранённый отпечаток?
Для удаления одной записи используй finger.deleteModel(id), а для удаления всех — finger.emptyDatabase(). Примеры delete и emptyDatabase из библиотеки делают это через монитор порта. Позже под удалённым ID можно зарегистрировать новый отпечаток.
Что собрать после прочтения
Все проекты
Умный электронный сейф
Маленький сейф для ценных вещей, который открывается кодом. Ты вводишь на клавиатуре свой четырёхзначный код; если он верный, сервопривод открывает замок, загорается зелёный свет, а экран показывает с

Дверной замок с RFID на ESP32 (RC522 + сервопривод + OLED + зуммер + светодиод)
Собираем умный дверной замок на ESP32, модуле RFID RC522, сервоприводе SG90, OLED-дисплее SSD1306, активном зуммере и 2 светодиодах. При поднесении карты её UID сравнивается со списком разрешённых карт в коде: если доступ разрешён, сервопривод поворачивается и открывает дверь (зелёный светодиод + 2 коротких сигнала), а через 5 секунд дверь снова запирается сама. При чужой карте загорается красный светодиод, звучат 3 быстрых сигнала, а прочитанный UID показывается на экране.

Аутентификация по RFID
Совсем как вход по карте у двери подъезда: ты подносишь карту к считывателю RFID, а Arduino сравнивает её номер с сохранённым. Правильная карта зажигает зелёный светодиод на три секунды, чужая — красн

Чтение значения RFID
В брелоке от подъезда или карте доступа спрятан секретный идентификационный номер, и этот проект его читает. Поднеси карту к считывателю RFID, и Arduino выведет номер карты на экран компьютера. Первый

Кодовый замок с клавиатурой 4x4 и LCD
Маленький электронный дверной замок, который не пускает тех, кто не знает кода. Ты нажимаешь клавишу решётки и вводишь код на клавиатуре; если он верный, экран сообщает, что доступ разрешён, загораетс

Считыватель карт RFID RC522 на ESP32 (с LCD)
В этом проекте модуль RFID RC522 на базе MFRC522 подключается к ESP32 по SPI и читает UID карты или метки. Это основа для дверных замков, клубных систем и контроля доступа. Прочитанный UID выводится на LCD-экран; эта версия не сравнивает его со списком разрешённых карт. ВНИМАНИЕ: RC522 работает только от 3.3V; подача 5V сожжёт модуль!

Датчик двери на герконе
Узнай, открыта дверь или закрыта, просто взглянув на огонёк. Маленький магнит крепится на дверь, а чувствительный к магниту контакт — на раму; когда дверь закрыта, они рядом, и горит зелёный светодиод

Сигнализация движения на ESP32 (PIR + зуммер + светодиод + Telegram)
Умная охранная сигнализация, которая при обнаружении движения PIR-датчиком включает зуммер и светодиод и одновременно сразу отправляет владельцу уведомление в Telegram. В ней есть 30-секундная пауза, ограничивающая частоту повторных тревог; этот механизм не проверяет срабатывания PIR и не устраняет ложные тревоги. Подходит для дома, гаража, склада или мастерской. С ESP32-CAM можно добавить уведомления с фото, а с обычной ESP32 DevKit V1 приходят текстовые.
Другие статьи
Приложение BlueGrays
Собери эту схему шаг за шагом в телефоне
Схема подключения, код и список деталей на одном экране. 200+ проектов на Arduino, ESP32 и Pico готовы к сборке.
Наведи камеру телефона
Наведи камеру на код — откроется магазин приложений на телефоне.
или открыть магазин

