Bootstrap

K210人脸识别+RFID录入信息

K210系列教程
使用MaixPy IDE开发K210
K210实现人脸识别(附代码解读)
K210人脸识别+人脸信息存储
K210人脸识别+RFID录入信息


(置顶:有位码友看了这篇博客后尝试了RFID,结果始终读不到卡,换了引脚后,检查无误,也没有引脚占用,就是死活读不到。搞了两天,最后竟然是因为数据线的问题,换成了手机数据线就OK了。这个坑我也是没有遇到的,所以这里置顶一下,避免再有人采坑)

在上一个博客
https://blog.csdn.net/HuangChen666/article/details/114007001中留了一个疑问,就是
strnum:表示学号
strname:表示姓名
这两个值如何获取,一开始我想的是使用触摸屏直接输入,但是自带的LCD没有触摸的功能,如需触摸还得加个触摸芯片。
后来想到学校的人脸识别采集信息的时候会让我们排队,使用一卡通录入人脸信息,于是我选择了使用RFID来做信息的录入,这也符合真实生活中的场景。

一、RFID的购买
二、MaixPy例程仓库
三、RFID的代码获取
四、RFID的代码概解
       4.1 RFID初始化
       4.2 RFID的读取
       4.3 RFID的写入
       4.4 针对自定义IC卡的读取

一、RFID的购买

在这里插入图片描述
直接淘宝搜索RC522,这个也是我们之前实训的时候用到的一种,其中说明一下最主要的几个引脚:
SDA:位选引脚
SCL:时钟引脚
MOSI:主发从收
MISO:主收从发

显然使用的是SPI协议,虽然是SPI,但在MaixPy IDE中再也不用像以前开发STM32时配置那么麻烦了。
只想说python太好用了,怪不得说人生苦短,我用python。


二、MaixPy例程仓库

其实官网提供了许多外设的demo示例以及其他代码示例,就在官网上的简介里

在这里插入图片描述
所以说其实只要大家好好利用官网,可以发现许多新大陆,往往问题的解决方案就在眼前,还有官网上面的论坛,遇到问题第一时间可以去论坛看看有没有人遇到过,看看别人分享的解决办法。

如果还是有懒人或者觉得git上的下载速度慢,可以从通过以下网盘下载MaixPy的历程仓库:
链接:https://pan.baidu.com/s/1XoqO9pmRVgidhEDmzQvc9Q
提取码:rggs


三、RFID的代码获取

RFID的代码我放到了的网盘,请大家自行获取
链接:https://pan.baidu.com/s/1Om8TpCSM0nkN9xueB2vGXQ
提取码:2xmt
或者做完第二步已经下载好例程仓库的,也可以从仓库中获取源码。
在这里插入图片描述
获取到RFID代码后,其实前面四百多行可以不用看,直接翻到最下面的main部分

if __name__ == "__main__":
    time.sleep(2)
	from micropython import const
	    ################### config ###################
	    CS_NUM = const(20)
	    SPI_FREQ_KHZ = const(600)
	    SPI_SCK = const(21)
	    SPI_MOSI = const(8)
	    SPI_MISO = const(15)
	    #############################################
	    continue_reading = True
	    # 20: CS_NUM;
	    fm.register(CS_NUM, fm.fpioa.GPIOHS20, force=True)
	    # set gpiohs work mode to output mode
	    cs = GPIO(GPIO.GPIOHS20, GPIO.OUT)
	    spi1 = SPI(SPI.SPI_SOFT, mode=SPI.MODE_MASTER, baudrate=SPI_FREQ_KHZ * 1000,
	            polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=SPI_SCK, mosi=SPI_MOSI, miso=SPI_MISO)
	    # Create an object of the class MFRC522
	    MIFAREReader = MFRC522(spi1, cs)
	    # Welcome message
	    print("Welcome to the MFRC522 data read/write example")
	    # This loop keeps checking for chips. If one is near it will get the UID and authenticate
	    while continue_reading:
	        time.sleep_ms(300)
	        # Scan for cards
	        (status, ataq) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQALL)
	        # If a card is found
	        if status == MIFAREReader.MI_OK:
	            print("Card detected type: ",hex(ataq[0]<<8|ataq[1]))
	            # 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("Card read UID: " +str(uid[0])+","+str(uid[1])+","+str(uid[2])+","+str(uid[3]))
	                # This is the default key of M1(S50) 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, 0x12, key, uid)
	                # Check if authenticated
	                if status == MIFAREReader.MI_OK:
	                    data = []
	                    # Fill the data with 0~16
	                    for x in range(0, 16):
	                        data.append(x)
	                    # Write the data
	                    print("Sector 11 will now be filled with 1~16:")
	                    status = MIFAREReader.MFRC522_Write(0x12, data)
	                    if status == MIFAREReader.MI_OK:
	                        print("start to read")
	                        # read the data
	                        MIFAREReader.MFRC522_Read(0x12)
	                    # Stop
	                    MIFAREReader.MFRC522_StopCrypto1()
	                else:
	                	print("Authentication error")

想要快速使用一个外设,首先学会看源码,看主要部分,我们能够利用到并可以直接使用的部分。在这里插入图片描述
从上图可以看出(修改了原本demo中的引脚
CS_NUM是配置的SDA片选引脚(第18引脚)
SPI_SCK是配置的SCK时钟引脚(第19引脚)
SPI_MOSI是配置的MOSI引脚(第8引脚)
SPI_MISO是配置的MISO引脚(第15引脚)

所以说能否快速上手源码,就是考验你看代码的能力,所以你连接线的时候按照这里的引脚去接线即可,当然还有VCC和GND(那四个引脚也可以自己选择定义成板子上的其他引脚,但要注意不要产生冲突)。


四、RFID的代码概讲

4.1 RFID初始化

CS_NUM = const(20) 一行到 MIFAREReader = MFRC522(spi1, cs) 一行即RFID的初始化的代码。
所以你要做的并不是把这几百行代码全部复制到你的总项目代码中,而是暂时只需要复制初始化的一部分,前提需要先import demo_sp_rfid,为了能找到demo_sp_rfid.py,你需要提前把该文件拷贝到你的SD卡中,和总代码在同一目录下

4.2 RFID的读取

同样的道理,研究源码,找到它读卡的那一部分,很显然就是while循环里的那部分代码,配合注释研读一下,其过程就是
寻卡–验证秘钥–写扇区–读扇区。
我们要的是读取其内容(如何事先将数据写入卡下面再说),所以我们只需要寻卡–验证秘钥–读扇区这个过程即可,对应化简后的代码如下:

#寻卡	
(status, ataq) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQALL)
# 寻到卡
if status == MIFAREReader.MI_OK:
	#获取其UID
	(status, uid) = MIFAREReader.MFRC522_Anticoll()
	if status == MIFAREReader.MI_OK:
		print("Card read UID: " +str(uid[0])+","+str(uid[1])+","+str(uid[2])+","+str(uid[3]))
		key = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
		MIFAREReader.MFRC522_SelectTag(uid)
		# 验证秘钥
		status = MIFAREReader.MFRC522_Auth(
		MIFAREReader.PICC_AUTHENT1A, 0x12, key, uid)
		#验证秘钥成功,读取扇区数据
		if status == MIFAREReader.MI_OK:
			#一张IC卡中有16个扇区,1-16对应0(0x00)-15(0xff)
	    	MIFAREReader.MFRC522_Read(0x12)	#0x12等于10,代表第11个扇区

使用读取卡的代码时,可以对其进行封装,调用封装后的方法即可。
说明: 一张IC卡有16个扇区,源码是选择的第11扇区,你也可以选择其他扇区,且每个扇区可以写入16个字节的数据。

4.3 RFID的写入

假如我想要在IC卡里写入 “B17041666马云”(引号不包含在内) 的信息,前面是学号,后面是姓名,学号好说,可以’B’,170,4,66,66,这样写入,值得注意的是一个字节能表示的最多是255,所以我取了个巧,把170写入第二个字节,写入 ‘B’ 实际上就是写入B的 ascii码
但是姓名就不好办了,于是疯狂百度寻找解决办法,各种编码转化都试了,终于实现了姓名的存储,先看数据格式。

#马云 %e9%a9%ac%e4%ba%91
data = ['B',170,4,66,66,0xe9,0xa9,0xac,0xe4,0xba,0x91,0,0,0,0,0]

我这里使用了中文的HEX编码,一个汉字由三个字节表示,可以使用该网站进行转码 http://stool.chinaz.com/hex
在这里插入图片描述
输入姓名,点击 “Hex编码” 得到对应编码,将这六个字节复制到data列表中,即紧接着学号的后面 (该方法有个弊端,就是如果有人名字是四个字的话,正好缺一位,那就只能另寻他法,比如单独把姓名存入第12扇区,嗯哼,嗯这个方法不错)。

当然你不可能只拿一张卡测试,所以需要若干个这样的data列表,但是一个一个输入复制实在是挺慢的,所以这里把我自己写好的data贡献给大家,省得大家再费事了。

#马云 %e9%a9%ac%e4%ba%91
data = ['B',170,4,66,66,0xe9,0xa9,0xac,0xe4,0xba,0x91,0,0,0,0,0]
#马化腾 %e9%a9%ac%e5%8c%96%e8%85%be
#data = ['B',170,4,66,67,0xe9,0xa9,0xac,0xe5,0x8c,0x96,0xe8,0x85,0xbe,0,0]
#李四 %e6%9d%8e%e5%9b%9b
#data = ['B',170,4,66,68,0xe6,0x9d,0x8e,0xe5,0x9b,0x9b,0,0,0,0,0]
#王五 %e7%8e%8b%e4%ba%94
#data = ['B',170,4,66,69,0xe7,0x8e,0x8b,0xe4,0xba,0x94,0,0,0,0,0]
#赵六
#data = ['B',170,4,66,70,0xe8,0xb5,0xb5,0xe5,0x85,0xad,0,0,0,0,0]

这里就需要提前单独使用RFID的源码向IC卡中写入你准备好的信息,以留后面使用。
在这里插入图片描述

4.4 针对自定义IC卡的读取

直接上代码

datas = MIFAREReader.MFRC522_Read(0x12)
#读出卡中的id号
strnum = ' '
strnum = chr(datas[0])+str(datas[1])+str(datas[2])+str(datas[3])+str(datas[4])
#如果第一个字符不是B则说明卡错误
if chr(datas[0]) == 'B':
	#读出卡中的姓名
	if datas[11]==0: #名字两个字
		strname = "b'"+hex(datas[5])+hex(datas[6])+hex(datas[7])+hex(datas[8])+hex(datas[9])+hex(datas[10])+"'"
	else :          #名字三个字
		strname = "b'"+hex(datas[5])+hex(datas[6])+hex(datas[7])+hex(datas[8])+hex(datas[9])+hex(datas[10])+hex(datas[11])+hex(datas[12])+hex(datas[13])+"'"
	strname = eval(strname.replace('0','\\')).decode('utf8')

想必代码已经够明显了,其实最终的学号和姓名就是这样一个字节一个字节的组织起来的,不过要注意strname需要加上一个replace(‘0’,‘\’)的操作,将格式变成0x…而不是\x…,eval后再使用utf8编码decode一下就可以得到中文名字啦。
之前也没学过python,这也是我尝试了一个晚上才搞出来的,啊啊啊啊,当时编码转化快把我转疯了,事实证明,遇到问题还是需要冷静下来才能更快的解决。。。。。。

说明: 以上给出的只是解决方案和我对该问题的思考过程和结果( 事实上我觉得我已经说得很直白了,就差直接把我自己的代码整个贴上来了[捂脸哭] ),能否真正应用到你自己的项目当中,还需简单修改才行,切莫直接复制和胡乱粘贴,搞懂原理是第一。懂了原理和逻辑,自然而然你就知道下面的代码该怎么改,该放到你项目的哪个地方了。

至此,关于RFID的使用就到这里了,当然我自己想到的方法一定不是最好的,希望大家可以在借鉴的同时,可以对代码再进行优化,变成你们自己的东西。

;