2018年01月6日

树莓派+MFRC522 rfid读卡器+Docker的设置

作者 非鱼

走了不少弯路,写个最终版给大家参考。

之前网上的文章大部分使用的是https://github.com/mxgxw/MFRC522-python.git 这个项目作为读卡器驱动,但是这个库已经四五年没维护了,有几个比较大的问题,比如它依赖SPI-Py项目,而不是spidev库,对Python3支持不友好,另外它没有用到读卡器上的IRQ接口,使用死循环的方式读卡,在树莓派上导致CPU占用80%以上,即使加了0.1秒的sleep,也要占用40%以上的CPU(树莓派3B)。

所以,最终找到更好用的一个库:https://github.com/ondryaso/pi-rc522 它本身是基于MFRC522库重写的,去掉了SPI-Py的依赖,只使用spidev库。而且使用IRQ接口的事件驱动读卡动作,CPU几乎没有占用。

1、首先生成一个Docker镜像,Dockerfile内容:

FROM arm32v7/python:3
RUN pip install --no-cache-dir spidev rpi.gpio redis
WORKDIR /app

然后docker build自己的镜像,假设tag是pythongpio。

2、开启树莓派的SPI和I2C接口
在Terminal中输入raspi-config 在Advanced Options中打开SPI和I2C。

3.连接树莓派与RC522读卡器

PIN NUM RC522 PIN NAME
24 SDA GPIO8
23 SCK GPIO11
19 MOSI GPIO10
21 MISO GPIO9
18 IRQ GPIO24
6 GND Ground
22 RST GPIO25
1 3.3V 3V3

4、
git clone https://github.com/ondryaso/pi-rc522.git
可以不用按照它的说明那样安装到系统里,直接将自己的代码放在它的项目目录里就可以。

5、按照它的说明写自己的read程序。如果只是读UID的话,它的Demo就够了,如果要读卡里的内容的话,要根据MFRC522的代码来调整一下。
读卡里的内容部分如下:

data = []
text_read = ''
for block_num in [8,9,10]:
block = rdr.read(block_num)
if not block[0]:
data += block[1]
if data:
text_read = ''.join(chr(i) for i in data)

6、启动程序:

docker run --rm -it --privileged -v $PWD:/app pythongpio python rfidreader.py

一定要加privileged参数,否则不能操作硬件。
另外实际测试使用docker-compose启动docker的话,privileged貌似不起作用,不加这个参数会报设备不存在的错误,加了这个参数不报错,但也读取不到卡。

7、补充
为了在读到卡以后处理其它业务并不中断读卡动作,使用了Redis的消息分发模式,用docker启动一个redis,再用docker启动一个redis的订阅者,读卡程序作为redis的消息发布者,读卡成功以后publish一条消息,然后继续读卡就可以了,订阅者收到消息以后去处理其它业务逻辑。因为不能使用docker-compose,所以需要单独一个个启动docker容器,为了固定redis连接需要使用–network=host参数,这样大家都使用localhost来连接就可以了。