Merge pull request #37 from dunkmann00/listen-for-passive-target
Add support to 'listen' for tags
This commit is contained in:
commit
1d6dec350a
2 changed files with 123 additions and 8 deletions
|
@ -295,6 +295,19 @@ class PN532:
|
||||||
for a response and return a bytearray of response bytes, or None if no
|
for a response and return a bytearray of response bytes, or None if no
|
||||||
response is available within the timeout.
|
response is available within the timeout.
|
||||||
"""
|
"""
|
||||||
|
if not self.send_command(command, params=params, timeout=timeout):
|
||||||
|
return None
|
||||||
|
return self.process_response(
|
||||||
|
command, response_length=response_length, timeout=timeout
|
||||||
|
)
|
||||||
|
|
||||||
|
def send_command(
|
||||||
|
self, command, params=[], timeout=1
|
||||||
|
): # pylint: disable=dangerous-default-value
|
||||||
|
"""Send specified command to the PN532 and wait for an acknowledgment.
|
||||||
|
Will wait up to timeout seconds for the acknowlegment and return True.
|
||||||
|
If no acknowlegment is received, False is returned.
|
||||||
|
"""
|
||||||
# Build frame data with command and parameters.
|
# Build frame data with command and parameters.
|
||||||
data = bytearray(2 + len(params))
|
data = bytearray(2 + len(params))
|
||||||
data[0] = _HOSTTOPN532
|
data[0] = _HOSTTOPN532
|
||||||
|
@ -306,12 +319,21 @@ class PN532:
|
||||||
self._write_frame(data)
|
self._write_frame(data)
|
||||||
except OSError:
|
except OSError:
|
||||||
self._wakeup()
|
self._wakeup()
|
||||||
return None
|
return False
|
||||||
if not self._wait_ready(timeout):
|
if not self._wait_ready(timeout):
|
||||||
return None
|
return False
|
||||||
# Verify ACK response and wait to be ready for function response.
|
# Verify ACK response and wait to be ready for function response.
|
||||||
if not _ACK == self._read_data(len(_ACK)):
|
if not _ACK == self._read_data(len(_ACK)):
|
||||||
raise RuntimeError("Did not receive expected ACK from PN532!")
|
raise RuntimeError("Did not receive expected ACK from PN532!")
|
||||||
|
return True
|
||||||
|
|
||||||
|
def process_response(self, command, response_length=0, timeout=1):
|
||||||
|
"""Process the response from the PN532 and expect up to response_length
|
||||||
|
bytes back in a response. Note that less than the expected bytes might
|
||||||
|
be returned! Will wait up to timeout seconds for a response and return
|
||||||
|
a bytearray of response bytes, or None if no response is available
|
||||||
|
within the timeout.
|
||||||
|
"""
|
||||||
if not self._wait_ready(timeout):
|
if not self._wait_ready(timeout):
|
||||||
return None
|
return None
|
||||||
# Read response bytes.
|
# Read response bytes.
|
||||||
|
@ -348,15 +370,41 @@ class PN532:
|
||||||
otherwise a bytearray with the UID of the found card is returned.
|
otherwise a bytearray with the UID of the found card is returned.
|
||||||
"""
|
"""
|
||||||
# Send passive read command for 1 card. Expect at most a 7 byte UUID.
|
# Send passive read command for 1 card. Expect at most a 7 byte UUID.
|
||||||
|
response = self.listen_for_passive_target(card_baud=card_baud, timeout=timeout)
|
||||||
|
# If no response is available return None to indicate no card is present.
|
||||||
|
if not response:
|
||||||
|
return None
|
||||||
|
return self.get_passive_target(timeout=timeout)
|
||||||
|
|
||||||
|
def listen_for_passive_target(self, card_baud=_MIFARE_ISO14443A, timeout=1):
|
||||||
|
"""Send command to PN532 to begin listening for a Mifare card. This
|
||||||
|
returns True if the command was received succesfully. Note, this does
|
||||||
|
not also return the UID of a card! `get_passive_target` must be called
|
||||||
|
to read the UID when a card is found. If just looking to see if a card
|
||||||
|
is currently present use `read_passive_target` instead.
|
||||||
|
"""
|
||||||
|
# Send passive read command for 1 card. Expect at most a 7 byte UUID.
|
||||||
try:
|
try:
|
||||||
response = self.call_function(
|
response = self.send_command(
|
||||||
_COMMAND_INLISTPASSIVETARGET,
|
_COMMAND_INLISTPASSIVETARGET, params=[0x01, card_baud], timeout=timeout
|
||||||
params=[0x01, card_baud],
|
|
||||||
response_length=19,
|
|
||||||
timeout=timeout,
|
|
||||||
)
|
)
|
||||||
except BusyError:
|
except BusyError:
|
||||||
return None # no card found!
|
return False # _COMMAND_INLISTPASSIVETARGET failed
|
||||||
|
return response
|
||||||
|
|
||||||
|
def get_passive_target(self, timeout=1):
|
||||||
|
"""Will wait up to timeout seconds and return None if no card is found,
|
||||||
|
otherwise a bytearray with the UID of the found card is returned.
|
||||||
|
`listen_for_passive_target` must have been called first in order to put
|
||||||
|
the PN532 into a listening mode.
|
||||||
|
|
||||||
|
It can be useful to use this when using the IRQ pin. Use the IRQ pin to
|
||||||
|
detect when a card is present and then call this function to read the
|
||||||
|
card's UID. This reduces the amount of time spend checking for a card.
|
||||||
|
"""
|
||||||
|
response = self.process_response(
|
||||||
|
_COMMAND_INLISTPASSIVETARGET, response_length=19, timeout=timeout
|
||||||
|
)
|
||||||
# If no response is available return None to indicate no card is present.
|
# If no response is available return None to indicate no card is present.
|
||||||
if response is None:
|
if response is None:
|
||||||
return None
|
return None
|
||||||
|
|
67
examples/pn532_simplelisten.py
Normal file
67
examples/pn532_simplelisten.py
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
"""
|
||||||
|
This example shows connecting to the PN532 with I2C (requires clock
|
||||||
|
stretching support), SPI, or UART. SPI is best, it uses the most pins but
|
||||||
|
is the most reliable and universally supported. In this example, we also connect
|
||||||
|
IRQ and poll that pin for a card. We don't try to read the card until we know
|
||||||
|
there is one present. After initialization, try waving various 13.56MHz RFID
|
||||||
|
cards over it!
|
||||||
|
"""
|
||||||
|
|
||||||
|
import time
|
||||||
|
import board
|
||||||
|
import busio
|
||||||
|
from digitalio import DigitalInOut
|
||||||
|
|
||||||
|
#
|
||||||
|
# NOTE: pick the import that matches the interface being used
|
||||||
|
#
|
||||||
|
from adafruit_pn532.i2c import PN532_I2C
|
||||||
|
|
||||||
|
# from adafruit_pn532.spi import PN532_SPI
|
||||||
|
# from adafruit_pn532.uart import PN532_UART
|
||||||
|
|
||||||
|
# I2C connection:
|
||||||
|
i2c = busio.I2C(board.SCL, board.SDA)
|
||||||
|
|
||||||
|
# Non-hardware
|
||||||
|
# pn532 = PN532_I2C(i2c, debug=False)
|
||||||
|
|
||||||
|
# With I2C, we recommend connecting RSTPD_N (reset) to a digital pin for manual
|
||||||
|
# harware reset
|
||||||
|
reset_pin = DigitalInOut(board.D6)
|
||||||
|
# On Raspberry Pi, you must also connect a pin to P32 "H_Request" for hardware
|
||||||
|
# wakeup! this means we don't need to do the I2C clock-stretch thing
|
||||||
|
req_pin = DigitalInOut(board.D12)
|
||||||
|
# Using the IRQ pin allows us to determine when a card is present by checking
|
||||||
|
# to see if the pin is pulled low.
|
||||||
|
irq_pin = DigitalInOut(board.D10)
|
||||||
|
pn532 = PN532_I2C(i2c, debug=False, reset=reset_pin, req=req_pin, irq=irq_pin)
|
||||||
|
|
||||||
|
# SPI connection:
|
||||||
|
# spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
|
||||||
|
# cs_pin = DigitalInOut(board.D5)
|
||||||
|
# pn532 = PN532_SPI(spi, cs_pin, debug=False)
|
||||||
|
|
||||||
|
# UART connection
|
||||||
|
# uart = busio.UART(board.TX, board.RX, baudrate=115200, timeout=100)
|
||||||
|
# pn532 = PN532_UART(uart, debug=False)
|
||||||
|
|
||||||
|
ic, ver, rev, support = pn532.firmware_version
|
||||||
|
print("Found PN532 with firmware version: {0}.{1}".format(ver, rev))
|
||||||
|
|
||||||
|
# Configure PN532 to communicate with MiFare cards
|
||||||
|
pn532.SAM_configuration()
|
||||||
|
|
||||||
|
# Start listening for a card
|
||||||
|
pn532.listen_for_passive_target()
|
||||||
|
print("Waiting for RFID/NFC card...")
|
||||||
|
while True:
|
||||||
|
# Check if a card is available to read
|
||||||
|
if irq_pin.value == 0:
|
||||||
|
uid = pn532.get_passive_target()
|
||||||
|
print("Found card with UID:", [hex(i) for i in uid])
|
||||||
|
# Start listening for a card again
|
||||||
|
pn532.listen_for_passive_target()
|
||||||
|
else:
|
||||||
|
print(".", end="")
|
||||||
|
time.sleep(0.1)
|
Loading…
Reference in a new issue