RaspberryPi で NFC RFID-RC522 を Python3 で使う

(Felica/Mifare/NFC チャレンジシリーズ) その他の記事はこちら 「Felica/Mifare/NFC でいろいろ実験」
https://qiita.com/nanbuwks/items/1f416d6e45a87250ee0a

-----

# NFC RFID-RC522 格安モジュール






## 搭載チップ

NXP MFRC522
https://www.nxp.com/docs/en/data-sheet/MFRC522.pdf

NXC MFRC522 は Mifare の読み書きに対応。 Felica は読み書きできない。
電源定格は2.5V~3.6V. Typ.3.3V.
 
ホストインターフェースは 

- SPI up to 10 Mbit/s
- I2C-bus interface up to 400 kBd in Fast mode, up to 3400 kBd in High-speed mode
- RS232 Serial UART up to 1228.8 kBd, with voltage levels dependant on pin
voltage supply

## モジュール

モジュール上には特にレギュレーターなど載っていないので、モジュールへの電源供給は上記チップの定格内で動かす必要がある。

インタフェースは SPI 固定みたい。

# 環境

- Raspbian Buster Lite
- Raspberry Pi 3 Model B Ver.2
- NFC RFID-RC522 格安モジュール




# 配線


 (2020/03/10 修正:初期に投稿したものはMOSIとMISOの配線が間違っていました。Sorry!)

```

 +------+-----+---------------+---Pi 3B--+---------------+-----+------+
 | RC522| wPi |   Name        | Physical | Name          | wPi |RC522 |
 +------+-----+---------------+----++----+---------------+-----+------+
 | 3.3v |     |          3.3v |    ||    | 5v            |     |      |
 |      |   8 | GPIO.02/SDA.1 |  3 || 4  | 5v            |     |      |
 |      |   9 | GPIO.03/SCL.1 |  5 || 6  | 0v            |     |      |
 |      |   7 | GPIO.04       |  7 || 8  | GPIO.14/TxD   | 15  |      |
 | GND  |     |            0v |  9 || 10 | GPIO.15/RxD   | 16  |      |
 |      |   0 | GPIO.17       | 11 || 12 | GPIO.18       | 1   |      |
 |      |   2 | GPIO.27       | 13 || 14 | 0v            |     |      |
 |      |   3 | GPIO.22       | 15 || 16 | GPIO.23       | 4   |      |
 |      |     |          3.3v | 17 || 18 | GPIO.24       | 5   | IRQ  |
 | MOSI |  12 | GPIO.10/MOSI  | 19 || 20 | 0v            |     |      |
 | MISO |  13 | GPIO.09/MISO  | 21 || 22 | GPIO.25       | 6   | RST  |
 |  SCK |  14 | GPIO.11/SCLK  | 23 || 24 | GPIO.08/CE0   | 10  | SDA  |
 |      |     |            0v | 25 || 26 | GPIO.07/CE1   | 11  |      |
 |      |  30 |         SDA.0 | 27 || 28 | SCL.0         | 31  |      |
 |      |  21 | GPIO.05       | 29 || 30 | 0v            |     |      |
 |      |  22 | GPIO.06       | 31 || 32 | GPIO.12       | 26  |      |
 |      |  23 | GPIO.13       | 33 || 34 | 0v            |     |      |
 |      |  24 | GPIO.19       | 35 || 36 | GPIO.16       | 27  |      |
 |      |  25 | GPIO.26       | 37 || 38 | GPIO.20       | 28  |      |
 |      |     |            0v | 39 || 40 | GPIO.21       | 29  |      |
 +------+-----+---------------+----++----+---------------+-----+------+
 | RC522| wPi |   Name        | Physical | Name          | wPi |RC522 |
 +------+-----+---------------+---Pi 3B--+---------------+-----+------+
```

# SPIの有効化

 Raspberry Pi の SPI機能を有効にします。

```

　sudo raspi-config 
```

として、

```

  5 Interfacing Options  Configure connections to peripherals   
```
を選び、

```

  P4 SPI         Enable/Disable automatic loading of SPI kernel module 
```
を選びます。

```

Would you like the SPI interface to be enabled?
```
  でYesとします。
その後raspi-configを終了して再起動します。



参考サイトには、

>　そして、A5 Device Treeを選択して
　・the kernel to use Device Tree?
　で Noを選択します。（コレ重要！）

とありますが、現在はこれは設定しなくても良いみたいです

# ソフトウェア

Python3で使うやり方を調べてみました。

- mxgxw / MFRC522-python (lucassarcanjo/MFRC522-python) を使うやり方
- pimylifeup / MFRC522-pythonm を使うやり方
- ondryaso / pi-rc522 を使うやり方

2つ目と3つ目は、1つ目からフォークしているもののようです。

## mxgxw / MFRC522-python (lucassarcanjo/MFRC522-python) を使うやり方

http://www.neko.ne.jp/~freewing/raspberry_pi/raspberry_pi_3_spi_nfc_rfid_rc522/
を元に作業していきます。
執筆時点 2020/03/03 時点での、アップデートを含んだ記録です。

SPI-py を先にインストールする必要があります。

### SPI-py ライブラリインストール

```

$ git clone https://github.com/lthiery/SPI-Py.git
$ cd SPI-Py
$ sudo python setup.py install
```
### MFRC522-python を使ってアクセス

https://github.com/mxgxw/MFRC522-python
を使いますが、そのまま使うと Python3 に対応してなかったり最新の SPI-Py に対応できてなかったりして悲しい感じ。

https://github.com/mxgxw/MFRC522-python/issues/83
issueが出てました。

対応する tree が作られていて、こちらでは両方共解決しています。
https://github.com/lucassarcanjo/MFRC522-python/tree/python3-spi-updates



```

$ git clone -b python3-spi-updates https://github.com/lucassarcanjo/MFRC522-python.git

```

として修正版をダウンロードします。

### カードリード

```

$ cd MFRC522-python/
$ python3 Read.py
```
実行。

```

Welcome to the MFRC522 data read example
Press Ctrl-C to stop.
```
待受になりました。

```

Card read UID: 242,195,43,51
Size: 8
Sector 8 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Card detected
Card read UID: 242,195,43,51
Size: 8
Sector 8 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Card detected
```

カードを押し当てると反応しました。


## pimylifeup / MFRC522-pythonm を使うやり方

こちらは、先の mxgxw / MFRC522-python からフォークしているもののようです。
SimpleMFRC522 クラスを追加して簡単にアクセスできるようにした他、Python3に対応、また安定性も向上しているらしいです。

「How to setup a Raspberry Pi RFID RC522 Chip」
https://pimylifeup.com/raspberry-pi-rfid-rc522/
を元に作業しました。

pipでmfrc522をインストールします。spidevも一緒にインストールされます。
ソースは https://github.com/pimylifeup/MFRC522-python にあるらしいです。

```

$ sudo pip3 install mfrc522
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting mfrc522
  Downloading https://files.pythonhosted.org/packages/d5/b5/d33c0634cece0931c3c4e0978b0db58f248045c3b379ccf2d512b76fe044/mfrc522-0.0.7-py3-none-any.whl
Requirement already satisfied: RPi.GPIO in /usr/local/lib/python3.7/dist-packages (from mfrc522) (0.7.0)
Collecting spidev (from mfrc522)
  Using cached https://www.piwheels.org/simple/spidev/spidev-3.4-cp37-cp37m-linux_armv7l.whl
Installing collected packages: spidev, mfrc522
Successfully installed mfrc522-0.0.7 spidev-3.4
```

プログラム作成

```

#!/usr/bin/env python3

import RPi.GPIO as GPIO
from mfrc522 import SimpleMFRC522

reader = SimpleMFRC522()

try:
        id, text = reader.read()
        print(id)
        print(text)
finally:
        GPIO.cleanup()
```

simpleMFRC522Read.py として保存した後、実行権を付けます。

```

$ chmod 755 simpleMFRC522Read.py
```

### 実行

```
$ ./simpleMFRC522Read.py 
1042627113835
```



## ondryaso/pi-rc522 を使うやり方

https://github.com/ondryaso/pi-rc522 にあるライブラリを使います。

こちらも先の mxgxw / MFRC522-python からフォークしているもののようです。
これが今回試した3つの中では最も頻繁に更新されている感じです。
今回の実験では以下のように行いましたが、これをより安定性を確保してつかうやりかたを別稿に書きました。

→「RaspberryPi + ondryaso/pi-rc522 ライブラリで MyFare を操作する」
https://qiita.com/nanbuwks/items/9cbf05609974870e9088

インストールはpipから行えます。

```

 sudo pip3 install pi-rc522
```

githubにあるサンプルプログラムを使ってみます


```

from pirc522 import RFID
rdr = RFID()

while True:
  rdr.wait_for_tag()
  (error, tag_type) = rdr.request()
  if not error:
    print("Tag detected")
    (error, uid) = rdr.anticoll()
    if not error:
      print("UID: " + str(uid))
      # Select Tag is required before Auth
      if not rdr.select_tag(uid):
        # Auth for block 10 (block 2 of sector 2) using default shipping key A
        if not rdr.card_auth(rdr.auth_a, 10, [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF], uid):
          # This will print something like (False, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
          print("Reading block 10: " + str(rdr.read(10)))
          # Always stop crypto1 when done working
          rdr.stop_crypto()

# Calls GPIO cleanup
rdr.cleanup()

```

動かしてみました。

```

Tag detected
UID: [242, 193, 107, 51, 107]
Reading block 10: (False, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
Tag detected
UID: [242, 193, 107, 51, 107]
Reading block 10: (False, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
Tag detected
UID: [242, 193, 107, 51, 107]
Reading block 10: (False, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
Tag detected
UID: [242, 193, 107, 51, 107]
Reading block 10: (False, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
Tag detected
UID: [242, 193, 107, 51, 107]
Reading block 10: (False, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
Tag detected
UID: [242, 193, 107, 51, 107]
Reading block 10: (True, [0])
```