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
|
||||
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.
|
||||
data = bytearray(2 + len(params))
|
||||
data[0] = _HOSTTOPN532
|
||||
|
@ -306,12 +319,21 @@ class PN532:
|
|||
self._write_frame(data)
|
||||
except OSError:
|
||||
self._wakeup()
|
||||
return None
|
||||
return False
|
||||
if not self._wait_ready(timeout):
|
||||
return None
|
||||
return False
|
||||
# Verify ACK response and wait to be ready for function response.
|
||||
if not _ACK == self._read_data(len(_ACK)):
|
||||
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):
|
||||
return None
|
||||
# Read response bytes.
|
||||
|
@ -348,15 +370,41 @@ class PN532:
|
|||
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.
|
||||
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:
|
||||
response = self.call_function(
|
||||
_COMMAND_INLISTPASSIVETARGET,
|
||||
params=[0x01, card_baud],
|
||||
response_length=19,
|
||||
timeout=timeout,
|
||||
response = self.send_command(
|
||||
_COMMAND_INLISTPASSIVETARGET, params=[0x01, card_baud], timeout=timeout
|
||||
)
|
||||
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 response is 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