GIAO TIẾP VỚI ARDUINO
Xin chào các bạn! Hôm nay mình sẽ đem tới cho các bạn một bài chia sẻ mới về module nhận dạng vân tay. Chắc có lẻ nhiều bạn khi nhắc tới nhận dạng vân tay có thể sẽ nghĩ đến phải biết xử lý ảnh, machine learning, AI,…mới có thể xử lý hình ảnh dấu vân tay đúng không. NHƯNG KHÔNG, mọi thứ xử lý đó đã được module cảm biến vân tay làm sẵn hết, chúng ta chỉ cần giao tiếp với module qua cổng UART hoặc USB là có thể thêm dấu vân tay vào bộ nhớ, nhận diện vân tay đó là vân tay nào,…để có thể ra lệnh điều khiển theo tùy ý mình.
Và để có thể cụ thể hơn công việc đó là như thế nào thì bạn hãy xem hết bài viết dưới đây của mình nhé
1. Giới thiệu module cảm biến vân tay AS608
Cảm biến nhận dạng vân tay AS608 Fingerprint Sensor sử dụng giao tiếp UART TTL hoặc USB để giao tiếp với Vi điều khiển hoặc kết nối trực tiếp với máy tính (thông qua mạch chuyển USB-UART hoặc giao tiếp USB).
- Nguồn cung cấp điện áp: DC 3.6 đến 6.0V
- Nguồn cung hiện tại: <120mA
- Màu đèn nền: màu xanh lục
- Baudrate: 9600, 19200, 28800, 38400, 57600 (default is 57600)
- Mức độ an toàn: từ thấp đến cao 1,2,3,4,5
- Tỷ lệ chấp nhận sai (FAR): <0,001% (mức độ bảo mật 3)
- Tỷ lệ từ chối giả (FRR): <1.0% (mức độ bảo mật 3)
- Có thể lưu trữ hơn 200 dấu vân tay khác nhau.
Cảm biến nhận dạng vân tay AS608 Fingerprint Sensor được tích hợp nhân xử lý nhận dạng vân tay phía trong, tự động gán vân tay với 1 chuỗi data và truyền qua giao tiếp UART ra ngoài nên hoàn toàn không cần các thao tác xử lý hình ảnh, đơn giản chỉ là phát lệnh đọc/ghi và so sánh chuỗi UART nên rất dễ sử dụng và lập trình.
2. Giao tiếp Arduino với Module cảm biến AS608
2.1. Chuẩn bị
- Arduino Uno (mình sử dụng cái này, nếu bạn dùng Kit Arduino khác thì cứ dùng).
- Module cảm biến vân tay AS608.
- Các dây jack cắm để nối cảm biến với arduino.
Mình sử dụng thư viện Fingerprint của Adafruit:
Vào Arduino -> Sketch -> Include library -> Manage libraries -> Tìm thư viện adafruit fingerprint để cài đặt vào nhé
Sau khi cài đặt thư viện xong, bạn có thể tham khảo 1 số examples có sẵn trong
File -> Examples -> Adafruit Fingerprint Sensor Lib
2.2. Lập trình Arduino
Đây là code arduino của mình, bạn có thể tham khảo (mình sẽ giới thiệu sơ qua phần code này ở phía dưới)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
|
#include <Adafruit_Fingerprint.h>
// pin #2 is IN from sensor
// pin #3 is OUT from arduino
SoftwareSerial mySerial(2, 3);
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
String inputString = “”;
bool stringComplete = false; // whether the string is complete
uint8_t id;
uint8_t checkTask = 0; //for check task
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
while (!Serial); // For Yun/Leo/Micro/Zero/…
delay(100);
Serial.println(“\n\nAdafruit Fingerprint sensor enrollment”);
// set the data rate for the sensor serial port
finger.begin(57600);
if (finger.verifyPassword()) {
Serial.println(“Found fingerprint sensor!”);
} else {
Serial.println(“Did not find fingerprint sensor :(“);
while (1) { delay(1); }
}
Serial.println(F(“Reading sensor parameters”));
finger.getParameters();
Serial.print(F(“Status: 0x”)); Serial.println(finger.status_reg, HEX);
Serial.print(F(“Sys ID: 0x”)); Serial.println(finger.system_id, HEX);
Serial.print(F(“Capacity: “)); Serial.println(finger.capacity);
Serial.print(F(“Security level: “)); Serial.println(finger.security_level);
Serial.print(F(“Device address: “)); Serial.println(finger.device_addr, HEX);
Serial.print(F(“Packet len: “)); Serial.println(finger.packet_len);
Serial.print(F(“Baud rate: “)); Serial.println(finger.baud_rate);
finger.getTemplateCount();
Serial.print(F(“Sensor contains: “)); Serial.print(finger.templateCount); Serial.println(” templates”);
}
void loop() // run over and over again
{
getFingerprintID();
delay(50); //don’t ned to run this at full speed.
if(checkTask == 1) //Add template fingerprint
{
Serial.println(“Ready to enroll a fingerprint!”);
Serial.println(“Please type in the ID # (from 1 to 127) you want to save this finger as…”);
id = readnumber();
if (id == 0) {// ID #0 not allowed, try again!
return;
}
Serial.print(“Enrolling ID #”);
Serial.println(id);
while (! getFingerprintEnroll() )
{
}
checkTask = 0;
}
else if(checkTask == 2) //check template
{
checkTask = 0;
uint8_t p = finger.loadModel(id);
if(p == FINGERPRINT_OK)
{
Serial.print(“ID “);
Serial.print(id);
Serial.println(” is exist”);
}
else
{
Serial.print(“ID “);
Serial.print(id);
Serial.println(” is NO exist”);
}
}
else if(checkTask == 3) //delete template
{
checkTask = 0;
if(id == 0) //delete all template
{
finger.emptyDatabase();
Serial.println(“Now database is empty”);
}
else
deleteFingerprint(id);
}
}
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a ‘X’, set a flag so the main loop can
// do something about it:
if (inChar == ‘X’) {
if(inputString[0] == ‘C’ && inputString[4] == ‘X’) //to check ID
{
id = (inputString[1] – 48)*100 + (inputString[2] – 48)*10 + (inputString[3] – 48);
checkTask = 2;
Serial.print(“Check ID…”);
Serial.println(id);
}
else if(inputString == “ADDX”) //add new fingerprint
{
Serial.println(“Add fingerprint…”);
checkTask = 1;
}
else if(inputString[0] == ‘D’ && inputString[4] == ‘X’) //delete fingerprint in memmory
{
id = (inputString[1] – 48)*100 + (inputString[2] – 48)*10 + (inputString[3] – 48);
Serial.print(“Delete template ID…”);
Serial.println(id);
checkTask = 3;
}
}
}
inputString = “”;
}
uint8_t readnumber(void) {
uint8_t num = 0;
while (num == 0) {
while (! Serial.available());
num = Serial.parseInt();
}
return num;
}
uint8_t getFingerprintID() {
uint8_t p = finger.getImage();
switch (p) {
case FINGERPRINT_OK:
Serial.println(“Image taken”);
break;
case FINGERPRINT_NOFINGER:
Serial.println(“No finger detected”);
return p;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println(“Communication error”);
return p;
case FINGERPRINT_IMAGEFAIL:
Serial.println(“Imaging error”);
return p;
default:
Serial.println(“Unknown error”);
return p;
}
// OK success!
p = finger.image2Tz();
switch (p) {
case FINGERPRINT_OK:
Serial.println(“Image converted”);
break;
case FINGERPRINT_IMAGEMESS:
Serial.println(“Image too messy”);
return p;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println(“Communication error”);
return p;
case FINGERPRINT_FEATUREFAIL:
Serial.println(“Could not find fingerprint features”);
return p;
case FINGERPRINT_INVALIDIMAGE:
Serial.println(“Could not find fingerprint features”);
return p;
default:
Serial.println(“Unknown error”);
return p;
}
// OK converted!
p = finger.fingerSearch();
if (p == FINGERPRINT_OK) {
Serial.println(“Found a print match!”);
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println(“Communication error”);
return p;
} else if (p == FINGERPRINT_NOTFOUND) {
Serial.println(“Did not find a match”);
return p;
} else {
Serial.println(“Unknown error”);
return p;
}
// found a match!
Serial.print(“Found ID #”); Serial.print(finger.fingerID);
Serial.print(” with confidence of “); Serial.println(finger.confidence);
return finger.fingerID;
}
uint8_t getFingerprintEnroll() {
int p = –1;
Serial.print(“Waiting for valid finger to enroll as #”); Serial.println(id);
while (p != FINGERPRINT_OK) {
p = finger.getImage();
switch (p) {
case FINGERPRINT_OK:
Serial.println(“Image taken”);
break;
case FINGERPRINT_NOFINGER:
Serial.println(“.”);
break;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println(“Communication error”);
break;
case FINGERPRINT_IMAGEFAIL:
Serial.println(“Imaging error”);
break;
default:
Serial.println(“Unknown error”);
break;
}
}
// OK success!
p = finger.image2Tz(1);
switch (p) {
case FINGERPRINT_OK:
Serial.println(“Image converted”);
break;
case FINGERPRINT_IMAGEMESS:
Serial.println(“Image too messy”);
return p;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println(“Communication error”);
return p;
case FINGERPRINT_FEATUREFAIL:
Serial.println(“Could not find fingerprint features”);
return p;
case FINGERPRINT_INVALIDIMAGE:
Serial.println(“Could not find fingerprint features”);
return p;
default:
Serial.println(“Unknown error”);
return p;
}
Serial.println(“Remove finger”);
delay(2000);
p = 0;
while (p != FINGERPRINT_NOFINGER) {
p = finger.getImage();
}
Serial.print(“ID “); Serial.println(id);
p = –1;
Serial.println(“Place same finger again”);
while (p != FINGERPRINT_OK) {
p = finger.getImage();
switch (p) {
case FINGERPRINT_OK:
Serial.println(“Image taken”);
break;
case FINGERPRINT_NOFINGER:
Serial.print(“.”);
break;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println(“Communication error”);
break;
case FINGERPRINT_IMAGEFAIL:
Serial.println(“Imaging error”);
break;
default:
Serial.println(“Unknown error”);
break;
}
}
// OK success!
p = finger.image2Tz(2);
switch (p) {
case FINGERPRINT_OK:
Serial.println(“Image converted”);
break;
case FINGERPRINT_IMAGEMESS:
Serial.println(“Image too messy”);
return p;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println(“Communication error”);
return p;
case FINGERPRINT_FEATUREFAIL:
Serial.println(“Could not find fingerprint features”);
return p;
case FINGERPRINT_INVALIDIMAGE:
Serial.println(“Could not find fingerprint features”);
return p;
default:
Serial.println(“Unknown error”);
return p;
}
// OK converted!
Serial.print(“Creating model for #”); Serial.println(id);
p = finger.createModel();
if (p == FINGERPRINT_OK) {
Serial.println(“Prints matched!”);
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println(“Communication error”);
return p;
} else if (p == FINGERPRINT_ENROLLMISMATCH) {
Serial.println(“Fingerprints did not match”);
return p;
} else {
Serial.println(“Unknown error”);
return p;
}
Serial.print(“ID “); Serial.println(id);
p = finger.storeModel(id);
if (p == FINGERPRINT_OK) {
Serial.println(“Stored!”);
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println(“Communication error”);
return p;
} else if (p == FINGERPRINT_BADLOCATION) {
Serial.println(“Could not store in that location”);
return p;
} else if (p == FINGERPRINT_FLASHERR) {
Serial.println(“Error writing to flash”);
return p;
} else {
Serial.println(“Unknown error”);
return p;
}
return true;
}
uint8_t deleteFingerprint(uint8_t id) {
uint8_t p = –1
p = finger.deleteModel(id);
if (p == FINGERPRINT_OK) {
Serial.println(“Deleted!”);
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println(“Communication error”);
} else if (p == FINGERPRINT_BADLOCATION) {
Serial.println(“Could not delete in that location”);
} else if (p == FINGERPRINT_FLASHERR) {
Serial.println(“Error writing to flash”);
} else {
Serial.print(“Unknown error: 0x”); Serial.println(p, HEX);
}
return p;
}
|
Thư viện sử dụng Adafruit_Fingerprint.h
Mình cấu hình sử dụng SoftwareSerial ở chân 2 và 3 của arduino Uno.
SoftwareSerial mySerial(2, 3);
Trong hàm loop mình cho mặc định chương trình sẽ chạy vòng quét kiểm tra vân tay từ cảm biến getFingerprintID()
Nếu không có vân tay chạm vào thì sẽ báo No finger detected
Trường hợp có vân tay chạm vào thì sẽ hiển thị các thông tin xử lý như image taken, image converted,…Kèm dữ liệu vân tay đó đã có lưu trữ trong bộ nhớ module cảm biến chưa, hay vân tay lạ. Ở dưới do vân tay mình đã thêm vào bộ nhớ với ID là 2 nên khi quét sẽ hiển thị thông tin ID được tìm thấy.
Thông số confidence biểu thị cho mức độ tin cậy khi so khớp giữa vân tay được quét và vân tay đã được lưu trữ trong bộ nhớ cảm biến. Giá trị càng cao thì càng tin cậy.
Ở code của mình sẽ có thêm 1 số chức năng như: thêm vân tay mới, xóa vân tay, kiểm tra vân tay,…
Mình có sử dụng sự kiện serialEvent() để bắt gói tin gửi qua serial để thực hiện các chức năng trên.
Cụ thể thêm mới vân tay theo lệnh serial “ADDX”, Hàm xử lý thêm vân tay getFingerprintEnroll()
Khi dùng lệnh ADDX thì nó sẽ bắt mình nhập ID cần lưu vào, sau khi nhập ID thì quá trình xử lý vân tay và lưu trữ bắt đầu thực thi như ảnh phía trên. Nhớ là lúc khi nhập ID thì bạn phải để ngón tay bạn vào cảm biến trước để nó quét xử lý nhé.
Kiểm tra ID vân tay đã tồn tại trong bộ nhớ hay chưa theo lệnh “C001X”, trong đó 001 là mã 3 ký tự chữ số của ID mình muốn kiểm tra. Hàm xử lý kiểm tra là finger.loadModel(id)
Xóa vân tay theo lệnh “D001X”, với 001 là mã 3 ký tự chữ số của ID mình muốn xóa. Hàm xóa vân tay deleteFingerprint(id)
Ngoài ra để xóa toàn bộ dữ liệu vân tay lưu trong bộ nhớ, có thể dùng cú pháp “D000X” sẽ xóa sạch bộ nhớ bằng lệnh finger.emptyDatabase()
3. Kết luận
Vậy là cũng đã xongbài chia sẻ hôm nay. Phần code lập trình của mình các bạn có thể tham khảo hay tùy biến lại theo ý các bạn, hi vọng nó sẽ giúp các bạn tiếp cận cảm biến AS608 nhanh gọn hơn.Chúc thành công!
Nguồn:https://tapit.vn/giao-tiep-cam-bien-nhan-dang-van-tay-as608-phan-1/