آموزش تست و راه اندازی ماژول ZFM-60 :
ماژول های اثر انگشت از جمله ماژول های پر کاربرد در ساخت سیستم های حضور و غیاب و اکسس کنترلر ها است . این ماژول ها از نظر عملکرد به انواع اپتیکال و خازنی دسته بندی می شوند . در مدل های خازنی از یک صفحه تاچ خازنی جهت اسکن اثر انگشت استفاده می شود . اما در مدل های اپتیکال از تصویر برداری استفاده می شود . در مدل های اپتیکال تصویر اثر انگشت کاربر با استفاده از مکانیزمی اپتیکال بر روی یک لنز تثبیت می شود . سپس یک میکرو کنترلر با استفاده از الگو های هوش مصنوعی و پزدازش تصویر یک عدد یا در واقع یک ID به اثر انگشت کاربر اختصاص می دهد . با قرارگیری انگشت در هر جهتی ، این ماژول ها قادر به پردازش تصویر و یافتن ID آن هستند . ماژول های اثر انگشت اپتیکال به دلیل قیمت پایین و سرعت عملکرد بالایی که دارند کاربرد بیشتری نسبت به انواع خازنی دارند .
یکی از سری ماژول های اثر انگشت اپتیکال ، سری ZFMxx می باشد . این ماژول های تنوع بسیار زیادی دارند و تنها در اینترفیس و میزان حافظه متفاوت اند . ما در این مقاله قصد داریم به راه اندازی مدل ZFM60 بپردازیم . به طور کلی هر مدل ماژول ZFM در دو نوع USB و UART ساخته می شود . در مدل های USB رابط ارتباطی ماژول به صورت ارتباط USB است که امکان اتصال مستقیم به کامپیوتر را می دهد . اما در ماژول های دارای ارتباط UART خروجی به صورت UART می باشد . هدف ما در این مقاله تست و راه اندازی ماژول ZFM60 مدل UART با استفاده از آردونیو است و قصد پرداختن به کامند ها و الگو های راه اندازی این ماژول نداریم .
نکته : حافظه ماژول ZFM-60 به صورت متغیرر بین 150 تا 1000 کاربر است (به دلیل تفاوت حجم تصاویر و پردازش های مربوط به آن ها ).
شماتیک اتصال به آردوینو :
به طور معمول رنگ بندی سیم های ماژول ZFM-60 دارای ترتیب ثابتی است اما همیشه بر اساس شماره پین ، آن را به مدار خود متصل کنید . برای اتصال این ماژول به آردوینو از شماتیک زیر استفاده کنید :
از کتابخانه زیر برای راه اندازی ماژول های ZFMxx می توان استفاده کرد :
پس از بستن مدار شماتیک فوق و نصب کتابخانه بالا ، برنامه زیر را در آردوینو IDE خود کپی و سپس بر روی برد خود آپلود کیند :
#include <SoftwareSerial.h>
#include <FPM.h>
/* Enroll fingerprints with direct control of sensor LED
* So far, only works with ZFM60 modules */
/* pin #2 is IN from sensor (GREEN wire)
* pin #3 is OUT from arduino (WHITE/YELLOW wire)
* Black Wire is GND
* Red Wire is +5 Vcc
*/
SoftwareSerial fserial(2, 3);
FPM finger(&fserial);
FPM_System_Params params;
void setup()
{
Serial.begin(9600);
Serial.println("ENROLL + LED test");
fserial.begin(57600);
if (finger.begin()) {
finger.readParams(¶ms);
Serial.println("Found fingerprint sensor!");
Serial.print("Capacity: "); Serial.println(params.capacity);
Serial.print("Packet length: "); Serial.println(FPM::packet_lengths[params.packet_len]);
} else {
Serial.println("Did not find fingerprint sensor :(");
while (1) yield();
}
/* just to find out if your sensor supports the handshake command */
if (finger.handshake()) {
Serial.println("Handshake command is supported.");
}
else {
Serial.println("Handshake command not supported.");
}
}
void loop()
{
Serial.println("Send any character to enroll a finger...");
while (Serial.available() == 0) yield();
Serial.println("Searching for a free slot to store the template...");
int16_t fid;
if (get_free_id(&fid))
enroll_finger(fid);
else
Serial.println("No free slot in flash library!");
while (Serial.read() != -1); // clear buffer
}
bool get_free_id(int16_t * fid) {
int16_t p = -1;
for (int page = 0; page < (params.capacity / FPM_TEMPLATES_PER_PAGE) + 1; page++) {
p = finger.getFreeIndex(page, fid);
switch (p) {
case FPM_OK:
if (*fid != FPM_NOFREEINDEX) {
Serial.print("Free slot at ID ");
Serial.println(*fid);
return true;
}
case FPM_PACKETRECIEVEERR:
Serial.println("Communication error!");
return false;
case FPM_TIMEOUT:
Serial.println("Timeout!");
return false;
case FPM_READ_ERROR:
Serial.println("Got wrong PID or length!");
return false;
default:
Serial.println("Unknown error!");
return false;
}
yield();
}
}
int16_t enroll_finger(int16_t fid) {
int16_t p = -1;
Serial.println("Waiting for valid finger to enroll");
finger.led_on();
while (p != FPM_OK) {
p = finger.getImageNL();
switch (p) {
case FPM_OK:
Serial.println("Image taken");
break;
case FPM_NOFINGER:
Serial.println(".");
break;
case FPM_PACKETRECIEVEERR:
Serial.println("Communication error");
break;
case FPM_IMAGEFAIL:
Serial.println("Imaging error");
break;
case FPM_TIMEOUT:
Serial.println("Timeout!");
break;
case FPM_READ_ERROR:
Serial.println("Got wrong PID or length!");
break;
default:
Serial.println("Unknown error");
break;
}
yield();
}
// OK success!
p = finger.image2Tz(1);
switch (p) {
case FPM_OK:
Serial.println("Image converted");
break;
case FPM_IMAGEMESS:
Serial.println("Image too messy");
return p;
case FPM_PACKETRECIEVEERR:
Serial.println("Communication error");
return p;
case FPM_FEATUREFAIL:
Serial.println("Could not find fingerprint features");
return p;
case FPM_INVALIDIMAGE:
Serial.println("Could not find fingerprint features");
return p;
case FPM_TIMEOUT:
Serial.println("Timeout!");
return p;
case FPM_READ_ERROR:
Serial.println("Got wrong PID or length!");
return p;
default:
Serial.println("Unknown error");
return p;
}
Serial.println("Remove finger");
delay(2000);
p = 0;
while (p != FPM_NOFINGER) {
p = finger.getImageNL();
yield();
}
p = -1;
Serial.println("Place same finger again");
while (p != FPM_OK) {
p = finger.getImageNL();
switch (p) {
case FPM_OK:
Serial.println("Image taken");
break;
case FPM_NOFINGER:
Serial.print(".");
break;
case FPM_PACKETRECIEVEERR:
Serial.println("Communication error");
break;
case FPM_IMAGEFAIL:
Serial.println("Imaging error");
break;
case FPM_TIMEOUT:
Serial.println("Timeout!");
break;
case FPM_READ_ERROR:
Serial.println("Got wrong PID or length!");
break;
default:
Serial.println("Unknown error");
break;
}
yield();
}
finger.led_off();
// OK success!
p = finger.image2Tz(2);
switch (p) {
case FPM_OK:
Serial.println("Image converted");
break;
case FPM_IMAGEMESS:
Serial.println("Image too messy");
return p;
case FPM_PACKETRECIEVEERR:
Serial.println("Communication error");
return p;
case FPM_FEATUREFAIL:
Serial.println("Could not find fingerprint features");
return p;
case FPM_INVALIDIMAGE:
Serial.println("Could not find fingerprint features");
return p;
case FPM_TIMEOUT:
Serial.println("Timeout!");
return false;
case FPM_READ_ERROR:
Serial.println("Got wrong PID or length!");
return false;
default:
Serial.println("Unknown error");
return p;
}
// OK converted!
p = finger.createModel();
if (p == FPM_OK) {
Serial.println("Prints matched!");
} else if (p == FPM_PACKETRECIEVEERR) {
Serial.println("Communication error");
return p;
} else if (p == FPM_ENROLLMISMATCH) {
Serial.println("Fingerprints did not match");
return p;
} else if (p == FPM_TIMEOUT) {
Serial.println("Timeout!");
return p;
} else if (p == FPM_READ_ERROR) {
Serial.println("Got wrong PID or length!");
return p;
} else {
Serial.println("Unknown error");
return p;
}
Serial.print("ID "); Serial.println(fid);
p = finger.storeModel(fid);
if (p == FPM_OK) {
Serial.println("Stored!");
return 0;
} else if (p == FPM_PACKETRECIEVEERR) {
Serial.println("Communication error");
return p;
} else if (p == FPM_BADLOCATION) {
Serial.println("Could not store in that location");
return p;
} else if (p == FPM_FLASHERR) {
Serial.println("Error writing to flash");
return p;
} else if (p == FPM_TIMEOUT) {
Serial.println("Timeout!");
return p;
} else if (p == FPM_READ_ERROR) {
Serial.println("Got wrong PID or length!");
return p;
} else {
Serial.println("Unknown error");
return p;
}
}
پس از پروگرام کردن آردوینو ، محیط Serial monitor را باز کنید . می تواندی با وارد کردن هر کاراکتر یک کاربر جدید تعریف کنید . یک حرف را وارد و سپس انگشت خود را بر روی ماژول قرار دهید .

