我计划在我的项目中使用Adafruit PN532 nfc https://www.adafruit.com/product/364突破卡。
有没有办法在python中编写非阻塞代码(使用中断)?如何避免循环,如下面的代码示例所示?
发布于 2017-04-10 21:12:19
(关于我的评论.)虽然asyncio的重量稍微轻一些,但threading也有一个事件调用系统,并且目前文档化得更好一些(线程处理的时间要比异步长一些,并且不那么抽象)。据我所知,您希望能够在执行其他任务时从阻塞资源中读取数据。在这种情况下,我们将创建一个线程来等待卡片被读取,同时缓慢地打印一个文本文件到stdout。这只是一个如何做这样的事情的例子。有许多方法可以实现类似的结果。
import binascii
import time
import threading
from collections import deque #use as a fifo queue
queue = deque() #queue to pass information from thread to main process
queue_lock = threading.Lock() #prevent possible issues from
txt_file = '50_shades_of_grey.txt' #don't ask ;)
running = True
def nfc_reader():
#copied from adafruit example
import Adafruit_PN532 as PN532
CS = 18
MOSI = 23
MISO = 24
SCLK = 25
pn532 = PN532.PN532(cs=CS, sclk=SCLK, mosi=MOSI, miso=MISO)
pn532.begin()
ic, ver, rev, support = pn532.get_firmware_version()
print(f'Found PN532 with firmware version: {ver}.{rev}')
pn532.SAM_configuration()
# Main loop to detect cards and read a block.
print('Waiting for MiFare card...')
while True:
if not running: #cheap way to kill a thread nicely (cheap ain't pretty)
return
#don't bother specifying a timeout, they forgot to support it in the library
uid = pn532.read_passive_target()
# Try again if no card is available.
if uid is None:
continue
print('Found card with UID: 0x{0}'.format(binascii.hexlify(uid)))
# Authenticate block 4 for reading with default key (0xFFFFFFFFFFFF).
if not pn532.mifare_classic_authenticate_block(uid, 4, PN532.MIFARE_CMD_AUTH_B,
[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]):
print('Failed to authenticate block 4!')
continue
# Read block 4 data.
data = pn532.mifare_classic_read_block(4)
if data is None:
print('Failed to read block 4!')
continue
# make sure our queue is free
with queue_lock:
# replaced print with deque.append
queue.append(f'Read block 4: 0x{binascii.hexlify(data[:4])}')
#optionally emit some sort of signal that data is ready. In our case the main loop will chech periodically on it's own
# Main program
nfc_thread = threading.Thread(target=nfc_reader)
nfc_thread.start()
with open(txt_file, 'r') as f:
while True: #also cheap, but easy
if queue: #bool(deque) works like bool(list)
with queue_lock:
print("we found a card!")
print(queue.popleft())
continue
try:
print(next(f)) #otherwise go back to more interesting matters
except StopIteration:
running = False
nfc_thread.join()
break
time.sleep(.9) #notice loop time will be less than timeout on nfc read.
# you could put the printing of the *book* into another thread
# and use events to immediately call your return from your
# nfc reader发布于 2017-04-12 21:26:42
以下是我尝试过的基于@Aaron答案的代码
import binascii
import time
import threading
from collections import deque #use as a fifo queue
import RPi.GPIO as GPIO
import Adafruit_PN532 as PN532
queue = deque() #queue to pass information from thread to main process
queue_lock = threading.Lock() #prevent possible issues from
running = True
def nfc_reader():
CS = 18
MOSI = 23
MISO = 24
SCLK = 25
pn532 = PN532.PN532(cs=CS, sclk=SCLK, mosi=MOSI, miso=MISO)
pn532.begin()
ic, ver, rev, support = pn532.get_firmware_version()
print('Found PN532 with firmware version: {0}.{1}'.format(ver, rev))
pn532.SAM_configuration()
while True:
if not running: #cheap way to kill a thread nicely (cheap ain't pretty)
return
uid = pn532.read_passive_target()
if uid is None:
continue
#print('card read')
message = 'Read card\n{0}'.format(binascii.hexlify(uid))
# make sure our queue is free
with queue_lock:
# replaced print with deque.append
queue.append(message)
time.sleep(1)
#optionally emit some sort of signal that data is ready. In our case the main loop will chech periodically on it's own
# Main program
nfc_thread = threading.Thread(target=nfc_reader)
nfc_thread.start()
while True: #also cheap, but easy
if queue: #bool(deque) works like bool(list)
with queue_lock:
print("we found a card!")
print(queue.popleft())
continue
time.sleep(.9) #notice loop time will be less than timeout on nfc read.
# you could put the printing of the *book* into another thread
# and use events to immediately call your return from your
# nfc readerhttps://stackoverflow.com/questions/43331956
复制相似问题