HARDWARE | FPC1020A 지문센서 이용해 보기 - 1

Arduino 를 가지고 놀아본 사람이라면, 그 언젠가 지문 센서를 만나게 될 것입니다. 지문 센서의 종류는 몇 가지가 있으며, 범용적으로 사용되는 센서가 있는 반면, 그렇지 않은 센서도 존재합니다.




1. Purchase

5년 전에 구입할 때는 배송료 포함 9 USD 정도였는데, 그 사이 금액이 올랐군요. 물가 상승과 원화가치 하락의 영향으로 2배정도 올랐다고 봐야겠습니다.

* FPC1020A Capacitive Semiconductor Fingerprint Identification Module Fingerprint Acquisition/UART Communication


잘 도착 했습니다. 5년 전에요...


전면에는 지문 인식 센서가 달려 있습니다.


모듈 뒷 편에는 MCU 가 달려 있어, 입출력 및 지문 처리 장치와 그에 필요한 부품들이 실장되어 있습니다. 이 센서를 선택하게 된 이유로는, Arduino 관련 센서들을 판매하는 Adafruit 에서 출시한 지문센서 모듈이 있으나, 지문 인식이 센서에 직접 닿지 않으며 모듈도 커서, All-in-One 이면서 컴팩트 하고 지문 센서가 바로 PCB 에 실장되어 있어서 였습니다.


사용된 MCU 에 대해 확인해 봤습니다. Datasheet 및 비슷한 시리즈의 비교표 입니다.

* GD32F105RBT6 (GD32F105 Series)


같은 시리즈의 상위 모델과 비표해 보면, Flash 메모리가 8배 크고, SRAM 도 32K 큰 모델도 있어서 확장성이 더 우수하여 아쉬운 부분이 있으나, 활용해 본 결과 이 모듈로도 충분하다는 것을 알 수 있었습니다.
-----------------------------------------------------
|  Chip Number |    Series   | Speed | Flash | SRAM |
-----------------------------------------------------
| GD32F105RBT6 | GD32F105    |  108  |  128K |  64K |
                    ............
| GD32F105VGT6 | GD32F105    |  108  | 1024K |  96K |
| GD32F105ZGT6 | GD32F105    |  108  | 1024K |  96K |
-----------------------------------------------------

모듈의 연결선을 보면, 일반 Pinout 은 아니고, 다발로 만들어져 있습니다. 확인해 보니, JST 1.25mm 피치의 전용 커넥터라고 합니다. 사양을 확인한 후, 아래 모듈을 구입 했습니다.

* 10PCS MICRO JST 1.25mm Pitch Female Connector Wire 10CM 15CM 20CM 30CM Cable 28AWG 2/3/4/5/6/7/8/9/10/11/12 Pin Single Head



잘 도착 했습니다. 5년 전에요...


6pin / 15cm 를 구입 했는데, 조금 더 길었으면 테스트시 편했을 터인데, 만일 실제 제품화 하게 될 경우에는 긴 길이가 걸리적 거릴 수 있기 때문에 적절한 선택이었다고 생각합니다.


JST 1.25mm pitch 의 전선 모듈 입니다.


전선 끝단 처리가 되어 있어서 신뢰가 갑니다.




2. Connection

전용 전선 모듈을 구입 했으니, 연결해 줍니다.


이렇게 되니 너무 깔끔하군요. 가능한 이런 연결 모듈을 이용해 구동하는 PCB 나 모듈을 선택해야 겠습니다.


저는 제품화 까지는 아니고, 기능 테스트를 하는 것이 우선이므로, 빵판에 쉽게 연결할 수 있도록 pin 들을 붙여 주었습니다. 기존에 가지고 있던 점프선 끝단을 잘라서 만들어 주었습니다.


납땜 후, 빨간 수축튜브로 보호해 준 다음, 구경이 큰 수축튜브를 덧씌워서 연결 부위를 강화 했습니다. 재질이 바뀌는 지점에서 힘을 많이 받아 단선이 될 수 있기에 이렇게 만들었습니다. 시각적으로도 깔끔하게 되어서 만족 스럽습니다.




3. Specification

각 pinout 의 연결 의미는 다음과 같습니다. 그림의 PCB 부품들의 모양과 실제 제품의 모양이 조금 다릅니다만, 그렇게 큰 차이는 없는지라 문제 없을 것이라 생각됩니다.


* R300 Fingerprint Module User Manual
  - PDF

일단 시작해 보기 위해 Adafruit 에서 출시한 R300 스펙을 확인해 봤습니다. 그러나, 프로토콜 부터 시작하여 활용법이 모두 다른 것이였습니다. R300 센서를 사용한다면, Adafruit Fingerprint library 를 사용하면 됩니다. 우리는 비표준 센서를 사용하고 있으니, 이 내용은 참고만 하기로 합니다.

짬짬이 인터넷을 뒤져 봤더니, 아래 두 사이트가 나왔습니다. 감사하게도, 첫 번째 사이트에서는 제가 구입한 FPC1020A 센서의 중국 메뉴얼을 일본어로 번역하여 테스트한 분이 계셨습니다.

* からくり工房「ききょうや」(旧バージョン)

이를 활용하여 실제 구현하신 분의 blog 도 발견하였습니다.

* ゲート用指紋認証システム-静電容量式(1)

제품 사이트에서 기본적인 소스가 아래와 같이 공개되어 있습니다. 가시성을 높이고 오탈자 수정했습니다. 그리고 코드에 버그가 있어서 수정한 버전을 아래에 공유 합니다.

////
// Demo code for FPC1020 Fingerprint Sensor
// Created by Deray on 2015-10-07.
////

#include <SoftwareSerial.h>
#include <FPC1020.h>

extern unsigned char l_ucFPID;
extern unsigned char rBuf[192];

#define SW_SERIAL_RX_PIN 2  // Connect to TX on FPC1020
#define SW_SERIAL_TX_PIN 3  // Connect to RX on FPC1020

SoftwareSerial swSerial(SW_SERIAL_RX_PIN, SW_SERIAL_TX_PIN);
FPC1020 Finger(&swSerial);

void setup() {
    Serial.begin(19200);
    pinMode(4, INPUT);  // IRQ
    Serial.println("Fingerprint Test!");
}

void loop() {
    unsigned int User_ID = 0;
    unsigned char incomingNub;
    unsigned char rtf = 0;

    while (1) {
        printMenu();

        unsigned char MODE = 0;
        while (Serial.available() <= 0);
        MODE = Serial.read() - 0x30;

        switch (MODE) {
            case 0:
                break;

            case 1:  // Add New User
                handleEnroll();
                break;

     f       case 2:  // Fingerprint Matching
                handleSearch();
                break;

            case 3:  // Print All User IDs
                handlePrintUsers();
                break;

            case 4:  // Delete Assigned User
                handleDeleteUser();
     f           break;

            case 5:  // Delete All Users
                handleDeleteAll();
                break;
        }
    }
}

void printMenu() {
    Serial.println("============== Menu ================");
    Serial.println("1 - Add a New User");
    Serial.println("2 - Fingerprint Matching");
    Serial.println("3 - Get User Number and Print All User ID");
    Serial.println("4 - Delete Assigned User");
    Serial.println("5 - Delete All Users");
    Serial.println("====================================");
}

unsigned int readUserID() {
    unsigned int id = 0;
    while (Serial.available() <= 0);
    delay(100);
    unsigned char count = Serial.available();
    for (char i = count; i >= 1; i--) {
        id += (Serial.read() - 0x30) * pow(10, (i - 1));
    }
    return id;
}

void handleEnroll() {
    Serial.println("Please input the new user ID (0 ~ 99).");
    unsigned int User_ID = readUserID();

    Serial.println("Add Fingerprint, please put your finger on the Sensor.");
    unsigned char rtf = Finger.Enroll(User_ID);

    if (rtf == TRUE) {
        Serial.print("Success, your User ID is: ");
        Serial.println(User_ID, DEC);
    } else if (rtf == FALSE) {
        Serial.println("Failed, please try again.");
    } else if (rtf == ACK_USER_OCCUPIED) {
        Serial.println("Failed, this User ID already exists.");
    } else if (rtf == ACK_USER_EXIST) {
        Serial.println("Failed, this fingerprint already exists.");
    }
    delay(2000);
}

void handleSearch() {
    Serial.println("Match Fingerprint, please put your finger on the Sensor.");

    if (Finger.Search()) {
        Serial.print("Success, your User ID is: ");
        Serial.println(l_ucFPID, DEC);
    } else {
        Serial.println("Failed, please try again.");
    }
    delay(1000);
}

void handlePrintUsers() {
    if (Finger.PrintUserID()) {
        unsigned char UserNumb = (l_ucFPID - 2) / 3;
        Serial.print("Number of Fingerprint Users: ");
        Serial.println(UserNumb, DEC);
        Serial.println("All User IDs:");

        for (char i = 0; i < UserNumb; i++) {
            Serial.println(rBuf[12 + i * 3], DEC);
        }
    } else {
        Serial.println("Print User ID Failed!");
    }
    delay(1000);
}

void handleDeleteUser() {
    Serial.println("Please input the user ID (0 ~ 99) to delete.");
    unsigned int User_ID = readUserID();

    if (Finger.Delete(User_ID)) {
        Serial.println("Delete Fingerprint User Success!");
    } else {
        Serial.println("Delete Fingerprint User Failed!");
    }
    delay(1000);
}

void handleDeleteAll() {
    Serial.println("Delete All Users, Y/N?");

    unsigned char DeleteFlag = 0;
    for (unsigned char i = 200; i > 0; i--) {
        delay(20);
        if (Serial.available() > 0) {
            DeleteFlag = Serial.read();
            break;
        }
    }

    if (DeleteFlag == 'Y' || DeleteFlag == 'y') {
        if (Finger.Clear()) {
            Serial.println("Delete All Fingerprint Users Success!");
        } else {
            Serial.println("Delete All Fingerprint Users Failed!");
        }
    }
    delay(500);
}

실제 구동해 보면 아래와 같이 에러가 뜹니다. FPC1020.h 라는 library 가 있어야 합니다.


여러 사이트 중에 Reddit 에서 공유된, 제조사가 만들어 놓은 library 가 있어서, 이를 활용하기로 합니다. 다만, 다운로드 하려면, 자꾸 에러를 내는 경우가 있어, 향후 다른 분들이 활용할 수 있도록 library 를 다운 받아 Google Drive 에 올려 놨습니다.

* FPC1020A
  - Library


Library 로 등록 합니다.


참고로, 일반적인 fingerprint 라이브러리를 찾으면, Adafruit 이 나오지만, 구입한 센서는 꼬빼기도 보이지 않습니다. 참고하시구요.


여러가지 시도해 봤으나, 생각하는 것 처럼 잘 동작하지 않았습니다. 공유된 사양서를 잘 분석하여 구현하면 좋겠으나, 비개발자 이다 보니 더이상 진행을 못 하고 있었습니다. 5년동안요... 2편으로 이어 집니다.


To Be Continued

* HARDWARE | FPC1020A 지문센서 이용해 보기 - 2

댓글