43
43
44
44
_GETIMAGE = const (0x01 )
45
45
_IMAGE2TZ = const (0x02 )
46
+ _COMPARE = const (0x03 )
46
47
_FINGERPRINTSEARCH = const (0x04 )
47
48
_REGMODEL = const (0x05 )
48
49
_STORE = const (0x06 )
53
54
_DOWNLOADIMAGE = const (0x0B )
54
55
_DELETE = const (0x0C )
55
56
_EMPTY = const (0x0D )
57
+ _SETSYSPARA = const (0x0E )
56
58
_READSYSPARA = const (0x0F )
57
59
_HISPEEDSEARCH = const (0x1B )
58
60
_VERIFYPASSWORD = const (0x13 )
59
61
_TEMPLATECOUNT = const (0x1D )
60
62
_TEMPLATEREAD = const (0x1F )
63
+ _SOFTRESET = const (0x3D )
61
64
_GETECHO = const (0x53 )
62
65
_SETAURA = const (0x35 )
63
66
87
90
MODULEOK = const (0x55 )
88
91
89
92
# pylint: disable=too-many-instance-attributes
93
+ # pylint: disable=too-many-public-methods
90
94
class Adafruit_Fingerprint :
91
95
"""UART based fingerprint sensor."""
92
96
97
+ _debug = False
93
98
_uart = None
94
99
95
100
password = None
@@ -112,6 +117,8 @@ def __init__(self, uart, passwd=(0, 0, 0, 0)):
112
117
self ._uart = uart
113
118
if self .verify_password () != OK :
114
119
raise RuntimeError ("Failed to find sensor, check wiring!" )
120
+ if self .read_sysparam () != OK :
121
+ raise RuntimeError ("Failed to read system parameters!" )
115
122
116
123
def check_module (self ):
117
124
"""Checks the state of the fingerprint scanner module.
@@ -149,6 +156,20 @@ def read_sysparam(self):
149
156
self .baudrate = struct .unpack (">H" , bytes (r [15 :17 ]))[0 ]
150
157
return r [0 ]
151
158
159
+ def set_sysparam (self , param_num , param_val ):
160
+ """Set the system parameters (param_num)"""
161
+ self ._send_packet ([_SETSYSPARA , param_num , param_val ])
162
+ r = self ._get_packet (12 )
163
+ if r [0 ] != OK :
164
+ raise RuntimeError ("Command failed." )
165
+ if param_num == 4 :
166
+ self .baudrate = param_val
167
+ elif param_num == 5 :
168
+ self .security_level = param_val
169
+ elif param_num == 6 :
170
+ self .data_packet_size = param_val
171
+ return r [0 ]
172
+
152
173
def get_image (self ):
153
174
"""Requests the sensor to take an image and store it memory, returns
154
175
the packet error code or OK success"""
@@ -188,7 +209,7 @@ def load_model(self, location, slot=1):
188
209
def get_fpdata (self , sensorbuffer = "char" , slot = 1 ):
189
210
"""Requests the sensor to transfer the fingerprint image or
190
211
template. Returns the data payload only."""
191
- if slot != 1 or slot != 2 :
212
+ if slot not in ( 1 , 2 ) :
192
213
# raise error or use default value?
193
214
slot = 2
194
215
if sensorbuffer == "image" :
@@ -199,14 +220,14 @@ def get_fpdata(self, sensorbuffer="char", slot=1):
199
220
raise RuntimeError ("Uknown sensor buffer type" )
200
221
if self ._get_packet (12 )[0 ] == 0 :
201
222
res = self ._get_data (9 )
202
- # print('datasize: ' + str(len(res)))
203
- # print( res)
223
+ self . _print_debug ( "get_fpdata data size:" , str (len (res )))
224
+ self . _print_debug ( "get_fdata res:" , res , data_type = "hex" )
204
225
return res
205
226
206
227
def send_fpdata (self , data , sensorbuffer = "char" , slot = 1 ):
207
228
"""Requests the sensor to receive data, either a fingerprint image or
208
229
a character/template data. Data is the payload only."""
209
- if slot != 1 or slot != 2 :
230
+ if slot not in ( 1 , 2 ) :
210
231
# raise error or use default value?
211
232
slot = 2
212
233
if sensorbuffer == "image" :
@@ -217,8 +238,8 @@ def send_fpdata(self, data, sensorbuffer="char", slot=1):
217
238
raise RuntimeError ("Uknown sensor buffer type" )
218
239
if self ._get_packet (12 )[0 ] == 0 :
219
240
self ._send_data (data )
220
- # print('datasize: ' + str(len(res )))
221
- # print(res )
241
+ self . _print_debug ( "send_fpdata data size:" , str (len (data )))
242
+ self . _print_debug ( "sent_fdata data:" , data , data_type = "hex" )
222
243
return True
223
244
224
245
def empty_library (self ):
@@ -268,9 +289,13 @@ def finger_fast_search(self):
268
289
)
269
290
r = self ._get_packet (16 )
270
291
self .finger_id , self .confidence = struct .unpack (">HH" , bytes (r [1 :5 ]))
271
- # print(r )
292
+ self . _print_debug ( "finger_fast_search packet:" , r , data_type = "hex" )
272
293
return r [0 ]
273
294
295
+ def close_uart (self ):
296
+ """close serial port"""
297
+ self ._uart .close ()
298
+
274
299
def finger_search (self ):
275
300
"""Asks the sensor to search for a matching fingerprint starting at
276
301
slot 1. Stores the location and confidence in self.finger_id
@@ -282,7 +307,17 @@ def finger_search(self):
282
307
)
283
308
r = self ._get_packet (16 )
284
309
self .finger_id , self .confidence = struct .unpack (">HH" , bytes (r [1 :5 ]))
285
- # print(r)
310
+ self ._print_debug ("finger_search packet:" , r , data_type = "hex" )
311
+ return r [0 ]
312
+
313
+ def compare_templates (self ):
314
+ """Compares two fingerprint templates in char buffers 1 and 2. Stores the confidence score
315
+ in self.finger_id and self.confidence. Returns the packet error code or
316
+ OK success"""
317
+ self ._send_packet ([_COMPARE ])
318
+ r = self ._get_packet (14 )
319
+ self .confidence = struct .unpack (">H" , bytes (r [1 :3 ]))
320
+ self ._print_debug ("compare_templates confidence:" , self .confidence )
286
321
return r [0 ]
287
322
288
323
def set_led (self , color = 1 , mode = 3 , speed = 0x80 , cycles = 0 ):
@@ -302,7 +337,7 @@ def _get_packet(self, expected):
302
337
"""Helper to parse out a packet from the UART and check structure.
303
338
Returns just the data payload from the packet"""
304
339
res = self ._uart .read (expected )
305
- # print("Got ", res)
340
+ self . _print_debug ( "_get_packet received data: " , res , data_type = "hex" )
306
341
if (not res ) or (len (res ) != expected ):
307
342
raise RuntimeError ("Failed to read data from sensor" )
308
343
@@ -328,30 +363,32 @@ def _get_packet(self, expected):
328
363
# print(packet_type + length + struct.unpack('>HHHH', res[9:9+(length-2)]))
329
364
330
365
reply = list (i for i in res [9 : 9 + (length - 2 )])
331
- # print( reply)
366
+ self . _print_debug ( "_get_packet reply:" , reply , data_type = "hex" )
332
367
return reply
333
368
334
369
def _get_data (self , expected ):
335
370
"""Gets packet from serial and checks structure for _DATAPACKET
336
371
and _ENDDATAPACKET. Alternate method for getting data such
337
372
as fingerprint image, etc. Returns the data payload."""
338
373
res = self ._uart .read (expected )
374
+ self ._print_debug ("_get_data received data:" , res , data_type = "hex" )
339
375
if (not res ) or (len (res ) != expected ):
340
376
raise RuntimeError ("Failed to read data from sensor" )
341
377
342
378
# first two bytes are start code
343
379
start = struct .unpack (">H" , res [0 :2 ])[0 ]
344
- # print( start)
380
+ self . _print_debug ( "_get_data received start pos:" , start )
345
381
if start != _STARTCODE :
346
382
raise RuntimeError ("Incorrect packet data" )
347
383
# next 4 bytes are address
348
384
addr = list (i for i in res [2 :6 ])
349
- # print( addr)
385
+ self . _print_debug ( "_get_data received address:" , addr )
350
386
if addr != self .address :
351
387
raise RuntimeError ("Incorrect address" )
352
388
353
389
packet_type , length = struct .unpack (">BH" , res [6 :9 ])
354
- # print(str(packet_type) + ' ' + str(length))
390
+ self ._print_debug ("_get_data received packet_type:" , packet_type )
391
+ self ._print_debug ("_get_data received length:" , length )
355
392
356
393
# todo: check checksum
357
394
@@ -363,15 +400,19 @@ def _get_data(self, expected):
363
400
res = self ._uart .read (length - 2 )
364
401
# todo: we should really inspect the headers and checksum
365
402
reply = list (i for i in res [0 :length ])
366
- self ._uart .read (2 ) # disregard checksum but we really shouldn't
403
+ received_checksum = struct .unpack (">H" , self ._uart .read (2 ))
404
+ self ._print_debug ("_get_data received checksum:" , received_checksum )
405
+
367
406
reply += self ._get_data (9 )
368
407
elif packet_type == _ENDDATAPACKET :
369
408
res = self ._uart .read (length - 2 )
370
409
# todo: we should really inspect the headers and checksum
371
410
reply = list (i for i in res [0 :length ])
372
- self ._uart .read (2 ) # disregard checksum but we really shouldn't
373
- # print(len(reply))
374
- # print(reply)
411
+ received_checksum = struct .unpack (">H" , self ._uart .read (2 ))
412
+ self ._print_debug ("_get_data received checksum:" , received_checksum )
413
+
414
+ self ._print_debug ("_get_data reply length:" , len (reply ))
415
+ self ._print_debug ("_get_data reply:" , reply , data_type = "hex" )
375
416
return reply
376
417
377
418
def _send_packet (self , data ):
@@ -389,12 +430,14 @@ def _send_packet(self, data):
389
430
packet .append (checksum >> 8 )
390
431
packet .append (checksum & 0xFF )
391
432
392
- # print("Sending: ", [hex(i) for i in packet])
433
+ self ._print_debug ("_send_packet length:" , len (packet ))
434
+ self ._print_debug ("_send_packet data:" , packet , data_type = "hex" )
393
435
self ._uart .write (bytearray (packet ))
394
436
395
437
def _send_data (self , data ):
396
- print (len (data ))
397
- self .read_sysparam ()
438
+ self ._print_debug ("_send_data length:" , len (data ))
439
+ self ._print_debug ("_send_data data:" , data , data_type = "hex" )
440
+ # self.read_sysparam() #moved this to init
398
441
if self .data_packet_size == 0 :
399
442
data_length = 32
400
443
elif self .data_packet_size == 1 :
@@ -403,58 +446,56 @@ def _send_data(self, data):
403
446
data_length = 128
404
447
elif self .data_packet_size == 3 :
405
448
data_length = 256
406
-
449
+ self . _print_debug ( "_send_data sensor data length:" , data_length )
407
450
i = 0
408
- for i in range (int (len (data ) / (data_length - 2 ))):
409
- start = i * (data_length - 2 )
410
- end = (i + 1 ) * (data_length - 2 )
411
- # print(start)
412
- # print(end)
413
- # print(i)
451
+ left = len (data )
452
+ for i in range (int (len (data ) / data_length )):
453
+ start = i * data_length
454
+ end = (i + 1 ) * data_length
455
+ left = left - data_length
456
+ self ._print_debug ("_send_data data start:" , start )
457
+ self ._print_debug ("_send_data data end:" , end )
458
+ self ._print_debug ("_send_data i:" , i )
414
459
415
460
packet = [_STARTCODE >> 8 , _STARTCODE & 0xFF ]
416
461
packet = packet + self .address
417
- packet .append (_DATAPACKET )
462
+
463
+ if left <= 0 :
464
+ packet .append (_ENDDATAPACKET )
465
+ else :
466
+ packet .append (_DATAPACKET )
467
+
418
468
length = len (data [start :end ]) + 2
419
- # print( length)
469
+ self . _print_debug ( "_send_data length:" , length )
420
470
packet .append (length >> 8 )
421
471
packet .append (length & 0xFF )
422
472
checksum = _DATAPACKET + (length >> 8 ) + (length & 0xFF )
423
473
424
- for j in range (len (data [start :end ])):
474
+ # for j in range(len(data[start:end])):
475
+ for j in range (start , end ):
425
476
packet .append (data [j ])
426
477
checksum += data [j ]
427
478
428
479
packet .append (checksum >> 8 )
429
480
packet .append (checksum & 0xFF )
430
481
431
- # print("Sending: ", [hex(i) for i in packet] )
482
+ self . _print_debug ( "_send_data sending packet: " , packet , data_type = "hex" )
432
483
self ._uart .write (packet )
433
- # print(i)
434
-
435
- i += 1
436
- start = i * (data_length - 2 )
437
- end = (i + 1 ) * (data_length - 2 )
438
- # print(start)
439
- # print(end)
440
- # print(i)
441
-
442
- packet = [_STARTCODE >> 8 , _STARTCODE & 0xFF ]
443
- packet = packet + self .address
444
- packet .append (_ENDDATAPACKET )
445
- length = len (data [start :end ]) + 2
446
- # print(length)
447
- packet .append (length >> 8 )
448
- packet .append (length & 0xFF )
449
- checksum = _ENDDATAPACKET + (length >> 8 ) + (length & 0xFF )
450
-
451
- for j in range (len (data [start :end ])):
452
- packet .append (data [j ])
453
- checksum += data [j ]
454
-
455
- packet .append (checksum >> 8 )
456
- packet .append (checksum & 0xFF )
457
484
458
- # print("Sending: ", [hex(i) for i in packet])
459
- self ._uart .write (packet )
460
- # print(i)
485
+ def soft_reset (self ):
486
+ """Performs a soft reset of the sensor"""
487
+ self ._send_packet ([_SOFTRESET ])
488
+ if self ._get_packet (12 )[0 ] == OK :
489
+ if self ._uart .read (1 )[0 ] != MODULEOK :
490
+ raise RuntimeError ("Sensor did not send a handshake signal!" )
491
+
492
+ def _print_debug (self , info , data , data_type = "str" ):
493
+ """Prints debugging information. This is activated
494
+ by flag _debug"""
495
+ if not self ._debug :
496
+ return
497
+
498
+ if data_type == "hex" :
499
+ print ("*** DEBUG ==>" , info , ["{:02x}" .format (i ) for i in data ])
500
+ elif data_type == "str" :
501
+ print ("*** DEBUG ==>" , info , data )
0 commit comments