LinkedIn YouTube Facebook
Szukaj

Newsletter

Proszę czekać.

Dziękujemy za zgłoszenie!

Wstecz
SoM / SBC

[PROJEKT] Sejf otwierany odciskiem palca oparty o Arduino

Podłączenie czujnika do Arduino

Przed podłączeniem czujnika należy się upewnić, że prędkość transmisji ustawiono na 9600.

Czujnik linii papilarnych SEN0348 Arduino Pro Mini
GND (przewód czerwony) GND
RX (przewód czarny) 3
TX (przewód żółty) 2
VIN (przewód zielony) VCC
IRQ (przewód niebieski) Nie podłączone
3.3V (przewód biały) VCC

Podłączenie programatora do Arduino Pro Mini:

Arduino Pro Mini Konwerter USB–UART ZL5USB
RX TX
TX RX
DTR (Reset) DTR
VCC +3V
GND GND

Rys. 14. Skaner linii papilarnych i konwerter USB-UART podłączone do Arduino Pro Mini

Instalowanie biblioteki DFRobot_ID809.h

W artykule [KROK-PO-KROKU] Arudino – jak zaimportować biblioteki? szczegółowo opisaliśmy proces importowania nowych bibliotek do środowiska Arduino. Jeśli nie opanowałeś jeszcze tego procesu, skorzystaj z tego poradnika. Biblioteka DFRobot_ID809.h, którą wykorzystamy do obsługi czytnika jest dostępna w sekcji Do pobrania.

Inicjalizacja czujnika linii papilarnych

Nadszedł czas na napisanie programu obsługującego czujnik linii papilarnych. Najpierw trzeba dołączyć do programu biblioteki SoftwareSerial.h i DFRobot_ID809.h

#include <SoftwareSerial.h>
#include <DFRobot_ID809.h>

Następnie należy do stałej FPSerial przypisać wirtualny port Serial1. Dzięki przypisaniu w instrukcji #define można łatwo podmienić go później na fizyczny interfejs UART Kolejna instrukcja przypisuje do stałej LED numer portu, do którego podłączona jest dioda.

#define FPSerial Serial1
#define LED 13

Teraz trzeba stworzyć obiekt Serial1 typu SoftwareSerial. Jako argumenty podamy numery portów, które pełnią rolę wyprowadzeń odpowiednio RX i TX. Następnie należy stworzyć obiekt czujnika linii papilarnych.

SoftwareSerial Serial1(2, 3);
DFRobot_ID809 fingerprint;

W funkcji setup() trzeba ustawić port LED jako port wyjściowy, a następnie stan portu jako niski. Dioda podłączona do tego portu będzie się świecić w przypadku błędu komunikacji z czujnikiem.

pinMode(LED, OUTPUT);
digitalWrite(LED, LOW);

Następnie należy zainicjalizować interfejs FPSerial z prędkością 9600 baud oraz obiekt fingerprint z argumentem FPSerial.

FPSerial.begin(9600);
fingerprint.begin(FPSerial);

Po zainicjalizowaniu program będzie sprawdzał czy wszystko przebiegło pomyślnie, a w przypadku błędu zapali diodę.

if(fingerprint.isConnected() == false)
digitalWrite(LED, HIGH);

Funkcja setup() powinna więc w tym momencie wyglądać następująco

void setup() {
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
  FPSerial.begin(9600);
  fingerprint.begin(FPSerial);
  if(fingerprint.isConnected() == false)
    digitalWrite(LED, HIGH);
  }

W funkcji loop() należy dodać funkcję ctrlLED, która pozwala sterować diodami wbudowanymi w czytnik. Funkcja przyjmuje trzy parametry.

Parametr pierwszy – tryb pracy LED wybieramy z dostępnych:

  • eBreathing,
  • eFastBlink,
  • eKeepsOn,
  • eNormalClose,
  • eFadeIn,
  • eFadeOut,
  • eSlowBlink.

Parametr drugi – kolor diody LED. Dostępne wartości:

  • eLEDGreen,
  • eLEDRed,
  • eLEDYellow,
  • eLEDBlue,
  • eLEDCyan,
  • eLEDMagenta,
  • eLEDWhite.

Parametr trzeci to liczba mignięć diodą. Podanie wartości 0 spowoduje ciągłe miganie.

Przykładowo ustawię tryb „oddychania”, kolor niebieski, a także miganie ciągłe.

fingerprint.ctrlLED(fingerprint.eBreathing, fingerprint.eLEDBlue, 0);

Pełen kod do inicjalizacji czujnika

Cały kod powinien więc wyglądać następująco

#include <SoftwareSerial.h>
#include <DFRobot_ID809.h>

#define FPSerial Serial1
#define LED 13

SoftwareSerial Serial1(2, 3);
DFRobot_ID809 fingerprint;

void setup() {
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
  FPSerial.begin(9600);
  fingerprint.begin(FPSerial);
  if(fingerprint.isConnected() == false)
    digitalWrite(LED, HIGH);
}

void loop() {
  fingerprint.ctrlLED(fingerprint.eBreathing,  fingerprint.eLEDBlue, 0);

}

Natomiast efekt działania programu powinien wyglądać tak:

Rys. 15. Skaner linii papilarnych po inicjalizacji

Dodawanie wzorców

Kolejnym krokiem będzie dodanie wzorców odcisków palców. Najpierw należy zdefiniować wartość COLLECT_NUMBER jako 3. Jest to liczba mówiąca ile razy trzeba zeskanować odcisk, aby dodać wzorzec. Wartość można zmienić na inną liczbę całkowitą z zakresu od 1 do 10.

#define COLLECT_NUMBER 3

Następnie trzeba dodać funkcję enroll(), która ma za zadanie tworzyć nowe wzorce. W funkcji najpierw należy dodać zmienną i oraz przypisać jej wartość 0.

int i = 0;

Potrzebna będzie również zmienna ID, której należy przypisać numer pierwszego pustego wzorca. W tym celu można skorzystać z funkcji getEmptyID().

int ID = fingerprint.getEmptyID();

Następnie należy sprawdzić czy funkcja getEmptyID() nie zwróciła błędu. W przypadku wykrycia błędu należy zapalić diodę i zatrzymać wykonywanie programu.

if (ID == ERR_ID809)
  {
  digitalWrite(LED, HIGH);
  while (1);
  }

W pętli while o warunku i < COLLECT_NUMBER należy umieścić funkcję ctrlLED z argumentami, które spowodują szybkie miganie diod w kolorze magenta. W warunku if należy pobrać odcisk palca, a także sprawdzić czy wynik funkcji nie jest równy kodowi błędu. Posłuży do tego funkcja collectionFingerprint przyjmująca jako argument czas, po którym pomiar ma być przerwany. Jeżeli udało się pomyślnie pobrać odcisk palca, ustawimy diody w tryb powolnego migania kolorem żółtym, a także zwiększymy wartość i o 1. Następnie (nadal w pętli while) należy dodać jeszcze jedną pętlę while, która będzie sprawdzać czy palec nadal jest przyłożony do czujnika i czekać, dopóki nie zostanie on zdjęty. Zastosowanie pętli typu while zamiast for ma na celu zapewnienie, że zostaną poprawnie zeskanowane trzy odciski. W przypadku pętli for funkcja collectionFingerprint zostałaby wykonana zawsze trzy razy, niezależnie od tego czy wykonała się poprawnie, czy też zwróciła kod błędu.

while (i < COLLECT_NUMBER)
  {
  fingerprint.ctrlLED(fingerprint.eFastBlink, fingerprint.eLEDMagenta, 0);
  if ((fingerprint.collectionFingerprint(10)) != ERR_ID809)
    {
    fingerprint.ctrlLED(fingerprint.eSlowBlink, fingerprint.eLEDYellow, 0);
    i++;
    }
  while (fingerprint.detectFinger());
  }

Po zeskanowaniu trzech odcisków należy utworzyć wzorzec za pomocą funkcji storeFingerprint(), która jako argument przyjmuje numer pustego wzorca. Warto od razu sprawdzić, czy operacja przebiegła pomyślnie i jeżeli tak, to zasygnalizować to za pomocą na przykład zapalenia diod na zielono.

if (fingerprint.storeFingerprint(ID) != ERR_ID809)
{
  fingerprint.ctrlLED(fingerprint.eKeepsOn, fingerprint.eLEDGreen, 0);
  delay(1000);
  fingerprint.ctrlLED(fingerprint.eNormalClose, fingerprint.eLEDBlue, 0);
  delay(1000);
}

Pełen kod funkcji enroll

Cała funkcja enroll powinna więc wyglądać następująco

void enroll()
{
  int i = 0;
  int ID = fingerprint.getEmptyID();
  if (ID == ERR_ID809)
  {
    digitalWrite(LED, HIGH);
    while (1);
  }
  while (i < COLLECT_NUMBER)
  {
    fingerprint.ctrlLED(fingerprint.eFastBlink, fingerprint.eLEDMagenta, 0);
    if ((fingerprint.collectionFingerprint(10)) != ERR_ID809)
    {
      fingerprint.ctrlLED(fingerprint.eSlowBlink, fingerprint.eLEDYellow, 0);
      i++;
    }
    while (fingerprint.detectFinger());
  }
  if (fingerprint.storeFingerprint(ID) != ERR_ID809)
  {
    fingerprint.ctrlLED(fingerprint.eKeepsOn, fingerprint.eLEDGreen, 0);
    delay(1000);
    fingerprint.ctrlLED(fingerprint.eNormalClose, fingerprint.eLEDBlue, 0);
    delay(1000);
  }
}

Funkcję enroll należy wykonać w pętli loop.

void loop() {
  fingerprint.ctrlLED(fingerprint.eBreathing, fingerprint.eLEDBlue, 0);
  enroll();
}

Teraz trzeba wgrać program i dodać wzorzec przynajmniej jednego palca.

Rys. 16. Dodawanie wzorców do bazy

Identyfikacja

Kolejnym krokiem jest dodanie do programu identyfikacji odcisku palca – sprawdzenia czy aktualnie odczytany odcisk znajduje się w bazie. Poprawne dopasowanie zeskanowanego odcisku do zapamiętanego wzorca sygnalizowane jest zapaleniem diody na zielono, natomiast brak dopasowania – na czerwono.

Pierwszym krokiem jest rezygnacja z wywołania funkcji enroll() w pętli loop, a także inicjalizacja zmiennej ret, która będzie przechowywać wynik identyfikacji.

//enroll();
int ret;

W kolejnej linii pętli loop powinna być dodana wcześniej funkcja ctrlLED ustawiająca miganie diod na niebiesko.

fingerprint.ctrlLED(fingerprint.eBreathing, fingerprint.eLEDBlue, 0);

Następnie należy dodać warunek if który zeskanuje odciski i sprawdzi, czy skanowanie przebiegło pomyślnie.

if ((fingerprint.collectionFingerprint(0)) != ERR_ID809)

Jeżeli udało się pobrać odcisk, należy zasygnalizować to zmieniając kolor diod na żółty i zaczekać aż palec zostanie zdjęty z czujnika. Można tego dokonać za pomocą pętli while z warunkiem detectFinger().

fingerprint.ctrlLED(fingerprint.eFastBlink, fingerprint.eLEDYellow, 3);
while (fingerprint.detectFinger());

Do zmiennej ret należy przypisać wynik funkcji search dopasowującej zeskanowany odcisk do zapamiętanych wzorców. Następnie za pomocą warunku if należy sprawdzić czy wartość zmiennej jest niezerowa. Jeżeli wartość zmiennej nie jest równa zeru, to oznacza, że udało się odnaleźć pasujący wzorzec. Można to zasygnalizować zapalając diodę na zielono. Natomiast jeżeli wartość jest równa zeru, to nie udało się znaleźć wzorca. Można to zasygnalizować zapalając LED na czerwono.

ret = fingerprint.search();
    if (ret != 0)
    {
      fingerprint.ctrlLED(fingerprint.eKeepsOn, fingerprint.eLEDGreen, 0);
      
    } else
    {
      fingerprint.ctrlLED(fingerprint.eKeepsOn, fingerprint.eLEDRed, 0);
      
    }

Na koniec w pętli loop należy dodać opóźnienie 1000 ms. W naszym przypadku można skorzystać z funkcji delay(), gdyż nie wpłynie to negatywnie na działanie programu. Jednak jeżeli w programie znalazłaby się obsługa innych czujników, warto zastąpić delay() licznikiem programowym, który będzie działał w trybie nieblokującym.

delay(1000);

Cała funkcja loop powinna wyglądać następująco:

void loop() {
  int ret;
  fingerprint.ctrlLED(fingerprint.eBreathing, fingerprint.eLEDBlue, 0);
  if ((fingerprint.collectionFingerprint(0)) != ERR_ID809)
  {
    fingerprint.ctrlLED(fingerprint.eFastBlink, fingerprint.eLEDYellow, 3);
    while (fingerprint.detectFinger());
    ret = fingerprint.search();
    if (ret != 0)
    {
      fingerprint.ctrlLED(fingerprint.eKeepsOn, fingerprint.eLEDGreen, 0);
     
    } else
    {
      fingerprint.ctrlLED(fingerprint.eKeepsOn, fingerprint.eLEDRed, 0);
     
    }
  }
  delay(1000);
}

Efekt działania programu powinien natomiast wyglądać tak:

Rys. 17. Identyfikacja odcisków palców

Dodawanie odcisków po identyfikacji

Możliwość dodawania nowych wzorców bez konieczności przeprogramowywania urządzenia umożliwi łatwe i wygodne zarządzanie dostępem do sejfu. Aby zabezpieczyć skarbonkę przed niepożądanym dodaniem nowych wzorców, należy funkcję enroll() wywołać dopiero po zeskanowaniu zapisanego odcisku. Aby rozróżnić samo otwieranie sejfu oraz dodawanie nowych odcisków, można skorzystać z dodatkowego przycisku, który wciśnięty podczas skanowania po poprawnej weryfikacji uruchomi funkcję dodawania do bazy nowych odcisków palców.

Najpierw należy podłączyć przycisk do Arduino zgodnie z poniższą tabelką.

Przycisk Arduino
Styk A GND
Styk B 12

Rys. 18. Zestaw z dołączonym przyciskiem typu microswitch

Następnie należy przypisać do stałej Button numer portu, do którego podłączony jest przycisk.

#define Button 12

W funkcji setup należy ustawić port Button jako wejściowy z podciągnięciem do zasilania (pull-up), co pozwoli wyeliminować stany nieustalone.

pinMode(Button, INPUT_PULLUP);

W pętli loop w warunku if (ret != 0) należy dodać warunek sprawdzający czy przycisk jest wciśnięty. Jeśli tak, to należy wywołać funkcję enroll; jeżeli nie to jedynie zapalić diodę na zielono.

if (ret != 0)
    {
      if(digitalRead(Button)==0)
        enroll();
      else
        fingerprint.ctrlLED(fingerprint.eKeepsOn, fingerprint.eLEDGreen, 0);
      
    }

W tym przypadku program sprawdza czy w momencie zdjęcia palca z czujnika przycisk jest wciśnięty, dzięki czemu nie ma potrzeby niwelacji drgań styków przycisku.

Cały program powinien w tym momencie wyglądać następująco

#include <Servo.h>
#include <DFRobot_ID809.h>

#define FPSerial Serial1
#define LED 13
#define Button 12
#define COLLECT_NUMBER 3

SoftwareSerial Serial1(2, 3);
DFRobot_ID809 fingerprint;

void enroll()
{
  int i = 0;
  int ID = fingerprint.getEmptyID();
  if (ID == ERR_ID809)
  {
    digitalWrite(LED, HIGH);
    while (1);
  }
  while (i < COLLECT_NUMBER)
  {
    fingerprint.ctrlLED(fingerprint.eFastBlink, fingerprint.eLEDMagenta, 0);
    if ((fingerprint.collectionFingerprint(10)) != ERR_ID809)
    {
      fingerprint.ctrlLED(fingerprint.eSlowBlink, fingerprint.eLEDYellow, 0);
      i++;
    }
    while (fingerprint.detectFinger());
  }
  if (fingerprint.storeFingerprint(ID) != ERR_ID809)
  {
    fingerprint.ctrlLED(fingerprint.eKeepsOn, fingerprint.eLEDGreen, 0);
    delay(1000);
    fingerprint.ctrlLED(fingerprint.eNormalClose, fingerprint.eLEDBlue, 0);
    delay(1000);
  }
}

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(Button, INPUT_PULLUP);
  digitalWrite(LED, LOW);
  FPSerial.begin(9600);
  fingerprint.begin(FPSerial);
  if (fingerprint.isConnected() == false)
    digitalWrite(LED, HIGH);
}

void loop() {
  int ret;
  fingerprint.ctrlLED(fingerprint.eBreathing, fingerprint.eLEDBlue, 0);
  if ((fingerprint.collectionFingerprint(0)) != ERR_ID809)
  {
    fingerprint.ctrlLED(fingerprint.eFastBlink, fingerprint.eLEDYellow, 3);
    while (fingerprint.detectFinger());
    ret = fingerprint.search();
    if (ret != 0)
    {
      if(digitalRead(Button)==0)
        enroll();
      else
        fingerprint.ctrlLED(fingerprint.eKeepsOn, fingerprint.eLEDGreen, 0);
      
    } else
    {
      fingerprint.ctrlLED(fingerprint.eKeepsOn, fingerprint.eLEDRed, 0);
      
    }
  }

  delay(1000);
}

Po wgraniu program powinien działać w następujący sposób:

Rys. 19. Dodawanie wzorców do bazy

 

Autor: Adam Kita