Compare commits

...

13 commits

Author SHA1 Message Date
Limor "Ladyada" Fried
cdb797b039
Merge pull request #21 from jerryneedell/jerryn_fingersearch
add finger_search
2020-07-15 17:41:50 -04:00
Jerry Needell
cedbc6466d add fingerprintsearch -- for R503 sensor 2020-07-14 14:55:39 -04:00
dherrada
1155d89382 Fixed discord invite link 2020-07-08 16:49:04 -04:00
Scott Shawcroft
5ebbb6ca6e
Merge pull request #19 from adafruit/black-update
Black reformatting with Python 3 target.
2020-04-09 09:35:11 -07:00
Kattni Rembor
450d68f200 Black reformatting with Python 3 target. 2020-04-08 15:14:34 -04:00
sommersoft
4e1dbf6552 build.yml: add black formatting check
Signed-off-by: sommersoft <sommersoft@gmail.com>
2020-04-07 16:04:49 -05:00
Kattni
870469df24
Merge pull request #18 from adafruit/pylint-update
Ran black, updated to pylint 2.x
2020-03-17 12:31:23 -04:00
sommersoft
06f580c352 update code of coduct: discord moderation contact section
Signed-off-by: sommersoft <sommersoft@gmail.com>
2020-03-15 18:31:58 -05:00
dherrada
e032600513 Ran black, updated to pylint 2.x 2020-03-15 18:00:36 -04:00
Kattni
27f8ce933e
Merge pull request #17 from sommersoft/patch_coc
Update Code of Conduct
2020-03-13 15:58:44 -04:00
sommersoft
7a21e5c3b9 update code of conduct 2020-03-13 13:51:52 -05:00
sommersoft
f94c57e0bf update pylintrc for black
Signed-off-by: sommersoft <sommersoft@gmail.com>
2020-03-08 19:10:13 -05:00
sommersoft
080c594fa2 build.yml: move pylint, black, and Sphinx installs to each repo; add description to 'actions-ci/install.sh'
Signed-off-by: sommersoft <sommersoft@gmail.com>
2020-03-05 10:09:27 -06:00
9 changed files with 224 additions and 169 deletions

View file

@ -34,11 +34,18 @@ jobs:
with:
repository: adafruit/actions-ci-circuitpython-libs
path: actions-ci
- name: Install deps
- name: Install dependencies
# (e.g. - apt-get: gettext, etc; pip: circuitpython-build-tools, requirements.txt; etc.)
run: |
source actions-ci/install.sh
- name: Pip install pylint, black, & Sphinx
run: |
pip install --force-reinstall pylint black==19.10b0 Sphinx sphinx-rtd-theme
- name: Library version
run: git describe --dirty --always --tags
- name: Check formatting
run: |
black --check --target-version=py35 .
- name: PyLint
run: |
pylint $( find . -path './adafruit*.py' )

View file

@ -52,7 +52,7 @@ confidence=
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
# disable=import-error,print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call
disable=print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call,import-error
disable=print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call,import-error,bad-continuation
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option

View file

@ -34,13 +34,15 @@ Examples of unacceptable behavior by participants include:
* Excessive or unwelcome helping; answering outside the scope of the question
asked
* Trolling, insulting/derogatory comments, and personal or political attacks
* Promoting or spreading disinformation, lies, or conspiracy theories against
a person, group, organisation, project, or community
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate
The goal of the standards and moderation guidelines outlined here is to build
and maintain a respectful community. We ask that you dont just aim to be
and maintain a respectful community. We ask that you dont just aim to be
"technically unimpeachable", but rather try to be your best self.
We value many things beyond technical expertise, including collaboration and
@ -72,10 +74,10 @@ You may report in the following ways:
In any situation, you may send an email to <support@adafruit.com>.
On the Adafruit Discord, you may send an open message from any channel
to all Community Helpers by tagging @community helpers. You may also send an
open message from any channel, or a direct message to @kattni#1507,
@tannewt#4653, @Dan Halbert#1614, @cater#2442, @sommersoft#0222, or
@Andon#8175.
to all Community Moderators by tagging @community moderators. You may
also send an open message from any channel, or a direct message to
@kattni#1507, @tannewt#4653, @Dan Halbert#1614, @cater#2442,
@sommersoft#0222, @Mr. Certainly#0472 or @Andon#8175.
Email and direct message reports will be kept confidential.
@ -83,7 +85,7 @@ In situations on Discord where the issue is particularly egregious, possibly
illegal, requires immediate action, or violates the Discord terms of service,
you should also report the message directly to Discord.
These are the steps for upholding our communitys standards of conduct.
These are the steps for upholding our communitys standards of conduct.
1. Any member of the community may report any situation that violates the
Adafruit Community Code of Conduct. All reports will be reviewed and
@ -124,4 +126,4 @@ For other projects adopting the Adafruit Community Code of
Conduct, please contact the maintainers of those projects for enforcement.
If you wish to use this code of conduct for your own project, consider
explicitly mentioning your moderation policy or making a copy with your
own moderation policy so as to avoid confusion.
own moderation policy so as to avoid confusion.

View file

@ -7,7 +7,7 @@ Introduction
:alt: Documentation Status
.. image :: https://img.shields.io/discord/327254708534116352.svg
:target: https://discord.gg/nBQh6qu
:target: https://adafru.it/discord
:alt: Discord
.. image:: https://github.com/adafruit/Adafruit_CircuitPython_Fingerprint/workflows/Build%20CI/badge.svg

View file

@ -34,6 +34,7 @@ Implementation Notes
**Hardware:**
* `Fingerprint sensor <https://www.adafruit.com/product/751>`_ (Product ID: 751)
* `Panel Mount Fingerprint sensor <https://www.adafruit.com/product/4651>`_ (Product ID: 4651)
**Software and Dependencies:**
@ -42,6 +43,7 @@ Implementation Notes
"""
from micropython import const
try:
import struct
except ImportError:
@ -58,6 +60,7 @@ _ENDDATAPACKET = const(0x8)
_GETIMAGE = const(0x01)
_IMAGE2TZ = const(0x02)
_FINGERPRINTSEARCH = const(0x04)
_REGMODEL = const(0x05)
_STORE = const(0x06)
_LOAD = const(0x07)
@ -99,8 +102,10 @@ ADDRCODE = const(0x20)
PASSVERIFY = const(0x21)
MODULEOK = const(0x55)
# pylint: disable=too-many-instance-attributes
class Adafruit_Fingerprint:
"""UART based fingerprint sensor."""
_uart = None
password = None
@ -114,20 +119,22 @@ class Adafruit_Fingerprint:
device_address = None
data_packet_size = None
baudrate = None
system_id = None
status_register = None
def __init__(self, uart, passwd=(0, 0, 0, 0)):
# Create object with UART for interface, and default 32-bit password
# Create object with UART for interface, and default 32-bit password
self.password = passwd
self._uart = uart
if self.verify_password() != OK:
raise RuntimeError('Failed to find sensor, check wiring!')
raise RuntimeError("Failed to find sensor, check wiring!")
def check_module(self):
"""Checks the state of the fingerprint scanner module.
Returns OK or error."""
self._send_packet([_GETECHO])
if self._get_packet(12)[0] != MODULEOK:
raise RuntimeError('Something is wrong with the sensor.')
raise RuntimeError("Something is wrong with the sensor.")
return True
def verify_password(self):
@ -140,7 +147,7 @@ class Adafruit_Fingerprint:
in ``self.template_count``. Returns the packet error code or OK success"""
self._send_packet([_TEMPLATECOUNT])
r = self._get_packet(14)
self.template_count = struct.unpack('>H', bytes(r[1:3]))[0]
self.template_count = struct.unpack(">H", bytes(r[1:3]))[0]
return r[0]
def read_sysparam(self):
@ -148,12 +155,14 @@ class Adafruit_Fingerprint:
self._send_packet([_READSYSPARA])
r = self._get_packet(28)
if r[0] != OK:
raise RuntimeError('Command failed.')
self.library_size = struct.unpack('>H', bytes(r[5:7]))[0]
self.security_level = struct.unpack('>H', bytes(r[7:9]))[0]
raise RuntimeError("Command failed.")
self.status_register = struct.unpack(">H", bytes(r[1:3]))[0]
self.system_id = struct.unpack(">H", bytes(r[3:5]))[0]
self.library_size = struct.unpack(">H", bytes(r[5:7]))[0]
self.security_level = struct.unpack(">H", bytes(r[7:9]))[0]
self.device_address = bytes(r[9:13])
self.data_packet_size = struct.unpack('>H', bytes(r[13:15]))[0]
self.baudrate = struct.unpack('>H', bytes(r[15:17]))[0]
self.data_packet_size = struct.unpack(">H", bytes(r[13:15]))[0]
self.baudrate = struct.unpack(">H", bytes(r[15:17]))[0]
return r[0]
def get_image(self):
@ -192,36 +201,36 @@ class Adafruit_Fingerprint:
self._send_packet([_LOAD, slot, location >> 8, location & 0xFF])
return self._get_packet(12)[0]
def get_fpdata(self, sensorbuffer='char', slot=1):
def get_fpdata(self, sensorbuffer="char", slot=1):
"""Requests the sensor to transfer the fingerprint image or
template. Returns the data payload only."""
if slot != 1 or slot != 2:
# raise error or use default value?
slot = 2
if sensorbuffer == 'image':
if sensorbuffer == "image":
self._send_packet([_UPLOADIMAGE])
elif sensorbuffer == 'char':
elif sensorbuffer == "char":
self._send_packet([_UPLOAD, slot])
else:
raise RuntimeError('Uknown sensor buffer type')
raise RuntimeError("Uknown sensor buffer type")
if self._get_packet(12)[0] == 0:
res = self._get_data(9)
# print('datasize: ' + str(len(res)))
# print(res)
return res
def send_fpdata(self, data, sensorbuffer='char', slot=1):
def send_fpdata(self, data, sensorbuffer="char", slot=1):
"""Requests the sensor to receive data, either a fingerprint image or
a character/template data. Data is the payload only."""
if slot != 1 or slot != 2:
# raise error or use default value?
slot = 2
if sensorbuffer == 'image':
if sensorbuffer == "image":
self._send_packet([_DOWNLOADIMAGE])
elif sensorbuffer == 'char':
elif sensorbuffer == "char":
self._send_packet([_DOWNLOAD, slot])
else:
raise RuntimeError('Uknown sensor buffer type')
raise RuntimeError("Uknown sensor buffer type")
if self._get_packet(12)[0] == 0:
self._send_data(data)
# print('datasize: ' + str(len(res)))
@ -238,16 +247,19 @@ class Adafruit_Fingerprint:
"""Requests the sensor to list of all template locations in use and
stores them in self.templates. Returns the packet error code or
OK success"""
import math
from math import ceil # pylint: disable=import-outside-toplevel
self.templates = []
self.read_sysparam()
temp_r = [0x0c, ]
for j in range(math.ceil(self.library_size/256)):
temp_r = [
0x0C,
]
for j in range(ceil(self.library_size / 256)):
self._send_packet([_TEMPLATEREAD, j])
r = self._get_packet(44)
if r[0] == OK:
for i in range(32):
byte = r[i+1]
byte = r[i + 1]
for bit in range(8):
if byte & (1 << bit):
self.templates.append((i * 8) + bit + (j * 256))
@ -261,52 +273,67 @@ class Adafruit_Fingerprint:
last model generated. Stores the location and confidence in self.finger_id
and self.confidence. Returns the packet error code or OK success"""
# high speed search of slot #1 starting at page 0x0000 and page #0x00A3
#self._send_packet([_HISPEEDSEARCH, 0x01, 0x00, 0x00, 0x00, 0xA3])
# self._send_packet([_HISPEEDSEARCH, 0x01, 0x00, 0x00, 0x00, 0xA3])
# or page #0x03E9 to accommodate modules with up to 1000 capacity
#self._send_packet([_HISPEEDSEARCH, 0x01, 0x00, 0x00, 0x03, 0xE9])
# self._send_packet([_HISPEEDSEARCH, 0x01, 0x00, 0x00, 0x03, 0xE9])
# or base the page on module's capacity
self.read_sysparam()
capacity = self.library_size
self._send_packet([_HISPEEDSEARCH, 0x01, 0x00, 0x00, capacity >> 8,
capacity & 0xFF])
self._send_packet(
[_HISPEEDSEARCH, 0x01, 0x00, 0x00, capacity >> 8, capacity & 0xFF]
)
r = self._get_packet(16)
self.finger_id, self.confidence = struct.unpack('>HH', bytes(r[1:5]))
self.finger_id, self.confidence = struct.unpack(">HH", bytes(r[1:5]))
# print(r)
return r[0]
##################################################
def finger_search(self):
"""Asks the sensor to search for a matching fingerprint starting at
slot 1. Stores the location and confidence in self.finger_id
and self.confidence. Returns the packet error code or OK success"""
self.read_sysparam()
capacity = self.library_size
self._send_packet(
[_FINGERPRINTSEARCH, 0x01, 0x00, 0x00, capacity >> 8, capacity & 0xFF]
)
r = self._get_packet(16)
self.finger_id, self.confidence = struct.unpack(">HH", bytes(r[1:5]))
# print(r)
return r[0]
##################################################
def _get_packet(self, expected):
""" Helper to parse out a packet from the UART and check structure.
Returns just the data payload from the packet"""
res = self._uart.read(expected)
#print("Got", res)
# print("Got", res)
if (not res) or (len(res) != expected):
raise RuntimeError('Failed to read data from sensor')
raise RuntimeError("Failed to read data from sensor")
# first two bytes are start code
start = struct.unpack('>H', res[0:2])[0]
start = struct.unpack(">H", res[0:2])[0]
if start != _STARTCODE:
raise RuntimeError('Incorrect packet data')
raise RuntimeError("Incorrect packet data")
# next 4 bytes are address
addr = [i for i in res[2:6]]
addr = list(i for i in res[2:6])
if addr != self.address:
raise RuntimeError('Incorrect address')
raise RuntimeError("Incorrect address")
packet_type, length = struct.unpack('>BH', res[6:9])
packet_type, length = struct.unpack(">BH", res[6:9])
if packet_type != _ACKPACKET:
raise RuntimeError('Incorrect packet data')
raise RuntimeError("Incorrect packet data")
# we should check the checksum
# but i don't know how
# not yet anyway
#packet_sum = struct.unpack('>H', res[9+(length-2):9+length])[0]
#print(packet_sum)
#print(packet_type + length + struct.unpack('>HHHH', res[9:9+(length-2)]))
# packet_sum = struct.unpack('>H', res[9+(length-2):9+length])[0]
# print(packet_sum)
# print(packet_type + length + struct.unpack('>HHHH', res[9:9+(length-2)]))
reply = [i for i in res[9:9+(length-2)]]
#print(reply)
reply = list(i for i in res[9 : 9 + (length - 2)])
# print(reply)
return reply
def _get_data(self, expected):
@ -315,38 +342,38 @@ class Adafruit_Fingerprint:
as fingerprint image, etc. Returns the data payload."""
res = self._uart.read(expected)
if (not res) or (len(res) != expected):
raise RuntimeError('Failed to read data from sensor')
raise RuntimeError("Failed to read data from sensor")
# first two bytes are start code
start = struct.unpack('>H', res[0:2])[0]
start = struct.unpack(">H", res[0:2])[0]
# print(start)
if start != _STARTCODE:
raise RuntimeError('Incorrect packet data')
raise RuntimeError("Incorrect packet data")
# next 4 bytes are address
addr = [i for i in res[2:6]]
addr = list(i for i in res[2:6])
# print(addr)
if addr != self.address:
raise RuntimeError('Incorrect address')
raise RuntimeError("Incorrect address")
packet_type, length = struct.unpack('>BH', res[6:9])
#print(str(packet_type) + ' ' + str(length))
packet_type, length = struct.unpack(">BH", res[6:9])
# print(str(packet_type) + ' ' + str(length))
# todo: check checksum
if packet_type != _DATAPACKET:
if packet_type != _ENDDATAPACKET:
raise RuntimeError('Incorrect packet data')
raise RuntimeError("Incorrect packet data")
if packet_type == _DATAPACKET:
res = self._uart.read(length-2)
res = self._uart.read(length - 2)
# todo: we should really inspect the headers and checksum
reply = [i for i in res[0:length]]
reply = list(i for i in res[0:length])
self._uart.read(2) # disregard checksum but we really shouldn't
reply += self._get_data(9)
elif packet_type == _ENDDATAPACKET:
res = self._uart.read(length-2)
res = self._uart.read(length - 2)
# todo: we should really inspect the headers and checksum
reply = [i for i in res[0:length]]
reply = list(i for i in res[0:length])
self._uart.read(2) # disregard checksum but we really shouldn't
# print(len(reply))
# print(reply)
@ -367,7 +394,7 @@ class Adafruit_Fingerprint:
packet.append(checksum >> 8)
packet.append(checksum & 0xFF)
#print("Sending: ", [hex(i) for i in packet])
# print("Sending: ", [hex(i) for i in packet])
self._uart.write(bytearray(packet))
def _send_data(self, data):

View file

@ -2,7 +2,8 @@
import os
import sys
sys.path.insert(0, os.path.abspath('..'))
sys.path.insert(0, os.path.abspath(".."))
# -- General configuration ------------------------------------------------
@ -10,9 +11,9 @@ sys.path.insert(0, os.path.abspath('..'))
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.intersphinx',
'sphinx.ext.viewcode',
"sphinx.ext.autodoc",
"sphinx.ext.intersphinx",
"sphinx.ext.viewcode",
]
# Uncomment the below if you use native CircuitPython modules such as
@ -20,29 +21,32 @@ extensions = [
# autodoc module docs will fail to generate with a warning.
# autodoc_mock_imports = ["micropython"]
intersphinx_mapping = {'python': ('https://docs.python.org/3.4', None),'CircuitPython': ('https://circuitpython.readthedocs.io/en/latest/', None)}
intersphinx_mapping = {
"python": ("https://docs.python.org/3.4", None),
"CircuitPython": ("https://circuitpython.readthedocs.io/en/latest/", None),
}
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
templates_path = ["_templates"]
source_suffix = '.rst'
source_suffix = ".rst"
# The master toctree document.
master_doc = 'index'
master_doc = "index"
# General information about the project.
project = u'Adafruit Fingerprint Library'
copyright = u'2017 ladyada'
author = u'ladyada'
project = "Adafruit Fingerprint Library"
copyright = "2017 ladyada"
author = "ladyada"
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = u'1.0'
version = "1.0"
# The full version, including alpha/beta/rc tags.
release = u'1.0'
release = "1.0"
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@ -54,7 +58,7 @@ language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '.env', 'CODE_OF_CONDUCT.md']
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", ".env", "CODE_OF_CONDUCT.md"]
# The reST default role (used for this markup: `text`) to use for all
# documents.
@ -66,7 +70,7 @@ default_role = "any"
add_function_parentheses = True
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
pygments_style = "sphinx"
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
@ -80,59 +84,62 @@ todo_emit_warnings = True
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
on_rtd = os.environ.get("READTHEDOCS", None) == "True"
if not on_rtd: # only import and set the theme if we're building docs locally
try:
import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), '.']
html_theme = "sphinx_rtd_theme"
html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), "."]
except:
html_theme = 'default'
html_theme_path = ['.']
html_theme = "default"
html_theme_path = ["."]
else:
html_theme_path = ['.']
html_theme_path = ["."]
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_static_path = ["_static"]
# The name of an image file (relative to this directory) to use as a favicon of
# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#
html_favicon = '_static/favicon.ico'
html_favicon = "_static/favicon.ico"
# Output file base name for HTML help builder.
htmlhelp_basename = 'AdafruitFingerprintLibrarydoc'
htmlhelp_basename = "AdafruitFingerprintLibrarydoc"
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'AdafruitFingerprintLibrary.tex', u'AdafruitFingerprint Library Documentation',
author, 'manual'),
(
master_doc,
"AdafruitFingerprintLibrary.tex",
"AdafruitFingerprint Library Documentation",
author,
"manual",
),
]
# -- Options for manual page output ---------------------------------------
@ -140,8 +147,13 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'AdafruitFingerprintlibrary', u'Adafruit Fingerprint Library Documentation',
[author], 1)
(
master_doc,
"AdafruitFingerprintlibrary",
"Adafruit Fingerprint Library Documentation",
[author],
1,
)
]
# -- Options for Texinfo output -------------------------------------------
@ -150,7 +162,13 @@ man_pages = [
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'AdafruitFingerprintLibrary', u'Adafruit Fingerprint Library Documentation',
author, 'AdafruitFingerprintLibrary', 'One line description of project.',
'Miscellaneous'),
(
master_doc,
"AdafruitFingerprintLibrary",
"Adafruit Fingerprint Library Documentation",
author,
"AdafruitFingerprintLibrary",
"One line description of project.",
"Miscellaneous",
),
]

View file

@ -10,12 +10,12 @@ led.direction = Direction.OUTPUT
uart = busio.UART(board.TX, board.RX, baudrate=57600)
# If using with a computer such as Linux/RaspberryPi, Mac, Windows with USB/serial converter:
#import serial
#uart = serial.Serial("/dev/ttyUSB0", baudrate=57600, timeout=1)
# import serial
# uart = serial.Serial("/dev/ttyUSB0", baudrate=57600, timeout=1)
# If using with Linux/Raspberry Pi and hardware UART:
#import serial
#uart = serial.Serial("/dev/ttyS0", baudrate=57600, timeout=1)
# import serial
# uart = serial.Serial("/dev/ttyS0", baudrate=57600, timeout=1)
finger = adafruit_fingerprint.Adafruit_Fingerprint(uart)
@ -31,10 +31,11 @@ def get_fingerprint():
if finger.image_2_tz(1) != adafruit_fingerprint.OK:
return False
print("Searching...")
if finger.finger_fast_search() != adafruit_fingerprint.OK:
if finger.finger_search() != adafruit_fingerprint.OK:
return False
return True
# pylint: disable=too-many-branches
def get_fingerprint_detail():
"""Get a finger print image, template it, and see if it matches!
@ -81,6 +82,7 @@ def get_fingerprint_detail():
print("Other error")
return False
# pylint: disable=too-many-statements
def enroll_finger(location):
"""Take a 2 finger images and template it, then store in 'location'"""
@ -95,7 +97,7 @@ def enroll_finger(location):
if i == adafruit_fingerprint.OK:
print("Image taken")
break
elif i == adafruit_fingerprint.NOFINGER:
if i == adafruit_fingerprint.NOFINGER:
print(".", end="", flush=True)
elif i == adafruit_fingerprint.IMAGEFAIL:
print("Imaging error")
@ -154,6 +156,7 @@ def enroll_finger(location):
##################################################
def get_num():
"""Use input() to get a valid number from 1 to 127. Retry till success!"""
i = 0
@ -168,7 +171,7 @@ def get_num():
while True:
print("----------------")
if finger.read_templates() != adafruit_fingerprint.OK:
raise RuntimeError('Failed to read templates')
raise RuntimeError("Failed to read templates")
print("Fingerprint templates:", finger.templates)
print("e) enroll print")
print("f) find print")
@ -176,14 +179,14 @@ while True:
print("----------------")
c = input("> ")
if c == 'e':
if c == "e":
enroll_finger(get_num())
if c == 'f':
if c == "f":
if get_fingerprint():
print("Detected #", finger.finger_id, "with confidence", finger.confidence)
else:
print("Finger not found")
if c == 'd':
if c == "d":
if finger.delete_model(get_num()) == adafruit_fingerprint.OK:
print("Deleted!")
else:

View file

@ -1,25 +1,26 @@
import time
import board
#import busio
import serial
import board
# import busio
from digitalio import DigitalInOut, Direction
import adafruit_fingerprint
led = DigitalInOut(board.D13)
led.direction = Direction.OUTPUT
#uart = busio.UART(board.TX, board.RX, baudrate=57600)
# uart = busio.UART(board.TX, board.RX, baudrate=57600)
# If using with a computer such as Linux/RaspberryPi, Mac, Windows with USB/serial converter:
#import serial
#uart = serial.Serial("/dev/ttyUSB0", baudrate=57600, timeout=1)
# import serial
# uart = serial.Serial("/dev/ttyUSB0", baudrate=57600, timeout=1)
# If using with Linux/Raspberry Pi and hardware UART:
#import serial
#uart = serial.Serial("/dev/ttyS0", baudrate=57600, timeout=1)
# import serial
# uart = serial.Serial("/dev/ttyS0", baudrate=57600, timeout=1)
# If using with Linux/Raspberry Pi 3 with pi3-disable-bt
#import serial
# import serial
uart = serial.Serial("/dev/ttyAMA0", baudrate=57600, timeout=1)
finger = adafruit_fingerprint.Adafruit_Fingerprint(uart)
@ -36,10 +37,11 @@ def get_fingerprint():
if finger.image_2_tz(1) != adafruit_fingerprint.OK:
return False
print("Searching...")
if finger.finger_fast_search() != adafruit_fingerprint.OK:
if finger.finger_search() != adafruit_fingerprint.OK:
return False
return True
# pylint: disable=too-many-branches
def get_fingerprint_detail():
"""Get a finger print image, template it, and see if it matches!
@ -86,6 +88,7 @@ def get_fingerprint_detail():
print("Other error")
return False
# pylint: disable=too-many-statements
def enroll_finger(location):
"""Take a 2 finger images and template it, then store in 'location'"""
@ -100,7 +103,7 @@ def enroll_finger(location):
if i == adafruit_fingerprint.OK:
print("Image taken")
break
elif i == adafruit_fingerprint.NOFINGER:
if i == adafruit_fingerprint.NOFINGER:
print(".", end="", flush=True)
elif i == adafruit_fingerprint.IMAGEFAIL:
print("Imaging error")
@ -156,14 +159,16 @@ def enroll_finger(location):
return True
def save_fingerprint_image(filename):
"""Scan fingerprint then save image to filename."""
while finger.get_image():
pass
# let PIL take care of the image headers and file structure
from PIL import Image
img = Image.new('L', (256, 288), 'white')
from PIL import Image # pylint: disable=import-outside-toplevel
img = Image.new("L", (256, 288), "white")
pixeldata = img.load()
mask = 0b00001111
result = finger.get_fpdata(sensorbuffer="image")
@ -194,6 +199,7 @@ def save_fingerprint_image(filename):
##################################################
def get_num(max_number):
"""Use input() to get a valid number from 0 to the maximum size
of the library. Retry till success!"""
@ -209,13 +215,13 @@ def get_num(max_number):
while True:
print("----------------")
if finger.read_templates() != adafruit_fingerprint.OK:
raise RuntimeError('Failed to read templates')
raise RuntimeError("Failed to read templates")
print("Fingerprint templates: ", finger.templates)
if finger.count_templates() != adafruit_fingerprint.OK:
raise RuntimeError('Failed to read templates')
raise RuntimeError("Failed to read templates")
print("Number of templates found: ", finger.template_count)
if finger.read_sysparam() != adafruit_fingerprint.OK:
raise RuntimeError('Failed to get system parameters')
raise RuntimeError("Failed to get system parameters")
print("Size of template library: ", finger.library_size)
print("e) enroll print")
print("f) find print")
@ -226,28 +232,28 @@ while True:
print("----------------")
c = input("> ")
if c == 'e':
if c == "e":
enroll_finger(get_num(finger.library_size))
if c == 'f':
if c == "f":
if get_fingerprint():
print("Detected #", finger.finger_id, "with confidence", finger.confidence)
else:
print("Finger not found")
if c == 'd':
if c == "d":
if finger.delete_model(get_num(finger.library_size)) == adafruit_fingerprint.OK:
print("Deleted!")
else:
print("Failed to delete")
if c == 's':
if c == "s":
if save_fingerprint_image("fingerprint.png"):
print("Fingerprint image saved")
else:
print("Failed to save fingerprint image")
if c == 'r':
if c == "r":
if finger.empty_library() == adafruit_fingerprint.OK:
print("Library empty!")
else:
print("Failed to empty library")
if c == 'q':
if c == "q":
print("Exiting fingerprint example program")
raise SystemExit

View file

@ -7,6 +7,7 @@ https://github.com/pypa/sampleproject
# Always prefer setuptools over distutils
from setuptools import setup, find_packages
# To use a consistent encoding
from codecs import open
from os import path
@ -14,47 +15,38 @@ from os import path
here = path.abspath(path.dirname(__file__))
# Get the long description from the README file
with open(path.join(here, 'README.rst'), encoding='utf-8') as f:
with open(path.join(here, "README.rst"), encoding="utf-8") as f:
long_description = f.read()
setup(
name='adafruit-circuitpython-fingerprint',
name="adafruit-circuitpython-fingerprint",
use_scm_version=True,
setup_requires=['setuptools_scm'],
description='CircuitPython library for UART fingerprint sensor.',
setup_requires=["setuptools_scm"],
description="CircuitPython library for UART fingerprint sensor.",
long_description=long_description,
long_description_content_type='text/x-rst',
long_description_content_type="text/x-rst",
# The project's main homepage.
url='https://github.com/adafruit/Adafruit_CircuitPython_Fingerprint',
url="https://github.com/adafruit/Adafruit_CircuitPython_Fingerprint",
# Author details
author='Adafruit Industries',
author_email='circuitpython@adafruit.com',
install_requires=['Adafruit-Blinka', 'pyserial'],
author="Adafruit Industries",
author_email="circuitpython@adafruit.com",
install_requires=["Adafruit-Blinka", "pyserial"],
# Choose your license
license='MIT',
license="MIT",
# See https://pypi.python.org/pypi?%3Aaction=list_classifiers
classifiers=[
'Development Status :: 3 - Alpha',
'Intended Audience :: Developers',
'Topic :: Software Development :: Libraries',
'Topic :: System :: Hardware',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"Topic :: Software Development :: Libraries",
"Topic :: System :: Hardware",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
],
# What does your project relate to?
keywords='adafruit uart fingerprint finger print sensor hardware micropython circuitpython',
keywords="adafruit uart fingerprint finger print sensor hardware micropython circuitpython",
# You can just specify the packages manually here if your project is
# simple. Or you can use find_packages().
py_modules=['adafruit_fingerprint'],
py_modules=["adafruit_fingerprint"],
)