An open API service indexing awesome lists of open source software.

https://github.com/nikialeksey/fpscanner

Python driver for fingerprint scanner
https://github.com/nikialeksey/fpscanner

driver dy-50 fingerprint fingerprint-scanner fpm10a python python2 rs-232 sensor zfm-20 zhiantec

Last synced: 9 months ago
JSON representation

Python driver for fingerprint scanner

Awesome Lists containing this project

README

          

# Python driver for fingerprint sensors by Zhiantec - ZFM-20 series

[![PyPI version](https://badge.fury.io/py/fpscanner.svg)](https://badge.fury.io/py/fpscanner)
[![PDD status](http://www.0pdd.com/svg?name=nikialeksey/fpscanner)](http://www.0pdd.com/p?name=nikialeksey/fpscanner)

## Is your scanner can be managed by this library?
If your scanner is ZFM-20 or his cheap clone then it possible. I made this library inspired by
[pyfingerprint](https://github.com/bastianraschke/pyfingerprint), so it may also work with ZFM-60, ZFM-70, ZFM-100,
R303 and R305.

## Origin manuals
Fingerprint protocol specs are taken from
[original ZHM-20 user manual](https://raw.githubusercontent.com/nikialeksey/fpscanner/master/ZFM+user+manualV15.pdf).

## Terminology

**Image**

Image is a Fingerprint scanned grayscale image. Image can be scanned and stored in volatile image buffer.

**Characteristic**

Characteristic is a fingerprint characteristic. It represented by a bytearray. Characteristic can be created from
fingerprint image and stored in volatile characteristic buffer.

**Template**

Template is a registered fingerprint model stored in scanner nonvolatile memory.
We can not see or feel the template, we only can ask scanner if characteristic look like some template
in scanner memory.

## Working with sensor

### Handshake

First of all you need make a handshake to verify connection:
```python
with SerialPort(Serial(port='', baudrate=9600 * 6, timeout=2)) as port:
rq = RqCommand(port)
rs = RsSimple(port)
Handshake(rq, rs).make()
```
As you see you will need to know serial port name of your scanner device. For windows users it may looks like `COM1`,
for unix users it may looks like `/dev/ttyUSB0`.

### Fingerprint image

More complex task - make an image of your fingerprint:
```python
with SerialPort(Serial(port='...', baudrate=9600 * 6, timeout=2)) as port:
rq = RqCommand(port)
rs = RsSimple(port)
print 'Waiting for finger...'
while not Scan(rq, rs).is_scanned():
pass
print 'Finger has been scanned! Downloading the finger image...'
image = UpImage(rq, rs).image()
image.show()
```

### Matching characteristics

Another more complex task - match characteristics of two fingerprints. Fingerprint scanner can matching only two
fingerprints and it has two buffers for that operation - `RqCharBuffer1` and `RqCharBuffer2`.
```python
with SerialPort(Serial(port='...', baudrate=9600 * 6, timeout=2)) as port:
rq = RqCommand(port)
rs = RsSimple(port)
print 'Wait for finger...'
while not Scan(rq, rs).is_scanned():
pass
Img2Tz(rq, rs, RqCharBuffer1()).execute()

print 'Once again...'
while not Scan(rq, rs).is_scanned():
pass
Img2Tz(rq, rs, RqCharBuffer2()).execute()

print 'Score {0}'.format(Match(rq, rs).score())
```

### Enroll fingerprint

Another complex task is enroll a finger.
```python
with SerialPort(Serial(port='...', baudrate=9600 * 6, timeout=2)) as port:
rq = RqCommand(port)
rs = RsSimple(port)
print 'Wait for finger...'
while not Scan(rq, rs).is_scanned():
pass

Img2Tz(rq, rs, RqCharBuffer1()).execute()
searchResult = Search(rq, rs, start=0, count=TemplateCount(rq, rs).as_int()).execute()

if searchResult.code() == 0:
print 'Template already exist'
exit(1)

print 'Once again...'
while not Scan(rq, rs).is_scanned():
pass

Img2Tz(rq, rs, RqCharBuffer2()).execute()
score = Match(rq, rs).score()
RegModel(rq, rs).execute()
Store(rq, rs, RqCharBuffer1(), 1).execute()
print 'Stored success!'
```

### Match fingerprint with it db saved version

```python
with SerialPort(Serial(port='...', baudrate=9600 * 6, timeout=2)) as port:
rq = RqCommand(port)
rs = RsSimple(port)
while not Scan(rq, rs).is_scanned():
pass
Img2Tz(rq, rs, RqCharBuffer1()).execute() # save scanned finger to the buffer 1

templatesCount = TemplateCount(rq, rs).as_int() # get all templates count
searchResult = Search(rq, rs, start=0, count=templatesCount).execute() # find finger in the db

if searchResult.code() != 0:
print('Finger has not been saved!')
else:
number = searchResult.number() # finger index in the db
print('Finger found in index {0}'.format(number))
LoadChar(rq, rs, RqCharBuffer2(), number).execute() # extract original template to the buffer 2

print('Score {0}'.format(Match(rq, rs).score())) # Match it!
```

@todo #1:30m Add deletion enrolled fingers