Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python非阻塞pn532标记读取_Python_Raspberry Pi_Nfc - Fatal编程技术网

Python非阻塞pn532标记读取

Python非阻塞pn532标记读取,python,raspberry-pi,nfc,Python,Raspberry Pi,Nfc,我计划在我的项目中使用Adafruit PN532 nfc突破卡 有没有一种方法可以在python中编写非阻塞代码(使用中断?),从而避免出现本代码示例中的循环 (关于我的评论…)虽然重量稍轻,但也有一个事件调用系统,并且目前有更好的文档记录(线程比asyncio更长,抽象性稍低)。据我所知,您希望能够在执行其他任务时读取阻塞资源。在这种情况下,我们将创建一个线程来等待读卡,同时缓慢地将文本文件打印到标准输出。这只是一个这样做的例子。有许多方法可以实现类似的结果 import binascii

我计划在我的项目中使用Adafruit PN532 nfc突破卡

有没有一种方法可以在python中编写非阻塞代码(使用中断?),从而避免出现本代码示例中的循环

(关于我的评论…)虽然重量稍轻,但也有一个事件调用系统,并且目前有更好的文档记录(线程比asyncio更长,抽象性稍低)。据我所知,您希望能够在执行其他任务时读取阻塞资源。在这种情况下,我们将创建一个线程来等待读卡,同时缓慢地将文本文件打印到标准输出。这只是一个这样做的例子。有许多方法可以实现类似的结果

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
(关于我的评论…)While重量稍微轻一点,也有一个事件调用系统,并且目前有更好的文档记录(线程比asyncio要长一点,抽象程度稍低一点)。据我所知,您希望能够在执行其他任务时读取阻塞资源。在这种情况下,我们将创建一个线程来等待读卡,同时缓慢地将文本文件打印到标准输出。这只是一个这样做的例子。有许多方法可以实现类似的结果

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

这是我根据@Aaron answer尝试的代码

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 reader

这是我根据@Aaron answer尝试的代码

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 reader

您需要查找事件循环和事件驱动的编码样式。Python3.x的asyncio模块内置了一个基本的事件处理程序类。最终,必须有东西阻塞才能等待事件,事件处理程序将该事件发送到正确的回调函数进行处理。只要回调立即返回*,就没有问题。如果您需要从api修补解决方案,您不能或不想更改。将阻塞调用放在一个线程内,让线程更新一个值,并让回调轮询该值(使用锁和任何您想要的安全工具)。有趣的是,adafruit库中的timeout关键字是ignored您需要查找事件循环和事件驱动的编码样式。Python3.x的asyncio模块内置了一个基本的事件处理程序类。最终,必须有东西阻塞才能等待事件,事件处理程序将该事件发送到正确的回调函数进行处理。只要回调立即返回*,就没有问题。如果您需要从api修补解决方案,您不能或不想更改。将阻塞调用放在线程内,让线程更新一个值,回调轮询该值(使用锁和任何您想要的安全工具)。有趣的是,adafruit库中的timeout关键字是ignoredI在没有“book reading”基的情况下尝试了您的代码:)谢谢您的回答。现在我在问自己,如何在不运行内核无限循环的情况下保持程序。如果主线程在任何子线程之前退出,那么将产生孤儿。它们可能会继续运行,直到遇到错误(无声)或内存不足(孤儿院没有足够的空间)。最终,在完成额外线程之前,必须保持主线程运行。请注意,虽然主线程必须保持活动状态,但这并不意味着它必须占用大量cpu或ram。。。事件侦听器可以在静默等待的同时将cpu降低到接近0%。或者,您可以将线程分类为“守护进程”,一旦主线程完成,它就会被随意删除。像文件读/写这样的事情不应该在守护进程线程中进行,因为如果线程在错误的时间终止,文件句柄可能会保持打开状态。@Obsurmoirage我还忘了添加一些东西来在我们的书结束时停止一切。。。我会很快做的谢谢,真的很有帮助!尝试使用asyncio来实现这一点让我头疼。我确实尝试了您的代码,但没有使用“book reading”(读书)基:)谢谢您的回答。现在我在问自己,如何在不运行内核无限循环的情况下保持程序。如果主线程在任何子线程之前退出,那么将产生孤儿。它们可能会继续运行,直到遇到错误(无声)或内存不足(孤儿院没有足够的空间)。最终,在完成额外线程之前,必须保持主线程运行。请注意,虽然主线程必须保持活动状态,但这并不意味着它必须占用大量cpu或ram。。。事件侦听器可以在静默等待的同时将cpu降低到接近0%。或者,您可以将线程分类为“守护进程”,一旦主线程完成,它就会被随意删除。像文件读/写这样的事情不应该在守护进程线程中进行,因为如果线程在错误的时间终止,文件句柄可能会保持打开状态。@Obsurmoirage我还忘了添加一些东西来在我们的书结束时停止一切。。。我会很快做的谢谢,真的很有帮助!试图用asyncio实现这一点让我头疼