使用 RPi2 在 Python 中使用 RC522 和 USB SERIAL 读取标签 UID

Posted

技术标签:

【中文标题】使用 RPi2 在 Python 中使用 RC522 和 USB SERIAL 读取标签 UID【英文标题】:Reading tags UID with RC522 and USB SERIAL in Python with RPi2 【发布时间】:2019-06-28 14:09:54 【问题描述】:

我有一个带有两个 RFID 阅读器的 RPi2 (Python 2.7)。一个阅读器是 USB SERIAL hex Gigatek MF7(连接到串行端口),另一个是 RFID-RC522(连接到 GPIO 引脚)。 RC522 按照pimylifeup.com/raspberry-pi-rfid-rc522 上的说明正确接线。阅读器都工作和阅读标签,但它们的输出字符串对于同一个标签是不同的。

我知道要从 Gigatek 读取的数据结构(串行 ASCII)和波特率:9600,N,8,1 - link。我的脚本从串口读取 12 个字符的字符串并从中提取 UID reply_rfid_1[1:9]

#!/usr/bin/env python2
# -*- coding: utf-8 -*-

"""
Convenient python function to read RFID tags with GIGATEK MF7
    """

############################

#from collections import defaultdict
#import csv
import sys
import serial
import time
from datetime import datetime



# define variables
global value_rfid, reply_rfid, refTime



# assign values
refTime = datetime.now()



# open the serial port /dev/ttyUSB1 and check if the port is really open
rfid_port_1 = serial.Serial("/dev/ttyUSB1", 9600)    # omit if not in use
print 'rfid_read.py -> rfid reader on port', rfid_port_1.name
rfid_port_1.isOpen()



def Read_Tag():
    # define variables
    global value_rfid_1, reply_rfid_1, tag
    
    # read port
    while int((datetime.now()-refTime).seconds) < 5:
        if (rfid_port_1.inWaiting() > 0):
            reply_rfid_1 = rfid_port_1.read(12)
            value_rfid_1 = str(reply_rfid_1[1:9])
            tag = str(value_rfid_1)
            print 'rfid_read.py -> tag hex', tag
            tag = int(tag, 16)
            print 'rfid_read.py -> tag dec ', tag
            break
        else:
            tag = None
    return tag



def Output_Tag():
    if tag == None:
        print 'rfid_read.py -> no tag'



def Flush_Port():
    rfid_port_1.flushInput()        # Clear input buffer
    time.sleep(0.1)



Read_Tag()
Output_Tag()
Flush_Port()
exit()

要从 RC522 读取,我使用以下代码:

reader = SimpleMFRC522()

print("Hold a tag near the reader")

try:
    id, text = reader.read()
    print(id)
    print(text)

finally:
    GPIO.cleanup()

我可以确定从 SERIAL 阅读器输出的字符串的长度和数字格式,但对于 RC522,我无法做到。我在github.com/mxgxw/MFRC522-python、github.com/pimylifeup/MFRC522-python 这些页面上找到了一些关于这些库的信息,但无法破译输出块的数据结构,我非常感谢您对此事的帮助。

更新 1. 7. 2019

如下所示是两个输出和 SPI 状态。

USB 阅读器的输出为 HEX 和 DEC 数字格式:

rfid_read.py -> rfid reader on port /dev/ttyUSB1
rfid_read.py -> tag hex AC8C5E0A
rfid_read.py -> tag dec  2894880266

RC522阅读器对于同一个TAG的输出是:

Hold a tag near the reader
44535950452

SPI状态:

pi@raspberrypi:~ $ lsmod | grep spi
spidev                 20480  0
spi_bcm2835            20480  0

【问题讨论】:

你能添加你从 RC522 得到的输出吗?您是否在 Pi 上启用了 SPI 总线?并验证您的接线是否正确?如果您还没有查看any good tutorial 并仔细检查 @MarcosG.,我添加了输出。 RC522 按照pimylifeup.com/raspberry-pi-rfid-rc522 上的说明进行接线。 谢谢 parovelb。您是否为 Gigatek 使用 Python 2.x 为 RC522 使用 Python 3.x?你确定 Gigatek 给你正确的标签号码。根据manual,您应该阅读value_rfid = str(reply_rfid[1:8]),现在您正在将\r 添加到标签号,我不知道这是否有效果,因为您没有显示HEX 到INT 的转换在你的代码上... @MarcosG.,我发布了 GIGATEK 的整个脚本,其中包含可见的转换 HEX 和 DEC。这两个脚本都是用 Python 2.7 编写的。我还有一个单独的外部 M301 桌面 RFID 阅读器,它输出与 GIGATEK 脚本相同的标签号。所以我不确定[1:8] 【参考方案1】:

我按照raspberrypi-spy.co.uk/2018/02/rc522-rfid-tag-read-raspberry-pi 的说明使用库github.com/mxgxw/MFRC522-python 尝试了不同的方法。使用此库作为我拥有的标签的输出 UID 是:

Card read UID: 86,209,188,187

而同一标签的GIGATEK MF7阅读器的输出UID为:

hex: BBBCD156
dec: 3149713750

结论 11. 7. 2019 使用MFRC522-python 库的输出是正确的,但会翻转并且不是正确的数字格式:

BB BC D1 56 = 187 188 209 86

因此我修改了库文件附带的Read.py标签UID读取脚本,以像我想要的那样将输出转换为十进制:

86 209 188 187 -> 56 D1 BC BB -> 3149713750

工作脚本:

def Read_Tag(self):
    # read with MFRC522 on GPIO
    # define variables
    global value_rfid_2, reply_rfid_2, tag, refTime
        
    # assign values
    refTime = datetime.now()
        
    # Create an object of the class MFRC522
    MIFAREReader = MFRC522.MFRC522()
        
    # read port
    while int((datetime.now()-refTime).seconds) < 5:
        # Scan for cards    
        (status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)
        
        # If a card is found
        if status == MIFAREReader.MI_OK:
            print "Card detected"
            
        # Get the UID of the card
        (status,uid) = MIFAREReader.MFRC522_Anticoll()
        
        # If we have the UID, continue
        if status == MIFAREReader.MI_OK:
        
            # Print UID
            print "tag UID: %s,%s,%s,%s" % (uid[0], uid[1], uid[2], uid[3])
            tag_endian = (uid[3], uid[2], uid[1], uid[0])
            print 'tag endian:', tag_endian
            tag_hex = hex(uid[3]), hex(uid[2]), hex(uid[1]), hex(uid[0])
            print 'tag hex:', tag_hex
            tag_str = str(hex(uid[3])[2:]), str(hex(uid[2])[2:]), str(hex(uid[1])[2:]), str(hex(uid[0])[2:])
            print 'tag string:', tag_str
            tag_str = str(hex(uid[3])[2:])+str(hex(uid[2])[2:])+str(hex(uid[1])[2:])+str(hex(uid[0])[2:])
            print 'tag hex string concatenated:', tag_str
            tag = int(tag_str, 16)
            print 'tag dec:', tag
                
            # This is the default key for authentication
            key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
               
            # Select the scanned tag
            MIFAREReader.MFRC522_SelectTag(uid)
        
            # Authenticate
            status = MIFAREReader.MFRC522_Auth(MIFAREReader.PICC_AUTHENT1A, 8, key, uid)
        
            # Check if authenticated
            if status == MIFAREReader.MI_OK:
                MIFAREReader.MFRC522_Read(8)
                MIFAREReader.MFRC522_StopCrypto1()
            else:
                print "Authentication error"
                
    GPIO.cleanup()      # Clear input buffer
    time.sleep(0.1)
    return tag

【讨论】:

以上是关于使用 RPi2 在 Python 中使用 RC522 和 USB SERIAL 读取标签 UID的主要内容,如果未能解决你的问题,请参考以下文章

RPi 2B python opencv camera demo example

8051单片机实战分析(以STC89C52RC为例) | 12 - 串行口中断的使用

8051单片机实战分析(以STC89C52RC为例) | 11 - 定时器中断的使用

51单片机之STC89C52RC最小系统板烧录说明

STC89C52RC单片机额外篇 | 05 - 把NOP指令封装成微秒级延时函数

8051单片机实战分析(以STC89C52RC为例) | 08 - 矩阵按键驱动