Raspberry PiでPN532を使うメモ
使ったもの
- Raspberry Pi Zero W
- PN532 NFC MODULE V3(本体に書いてあった)
Raspberry Piのセットアップ
ここではPythonのライブラリであるnfcpyを使うので公式ドキュメントに従ってインストールします。
Python3やpipなどは前回と同じなのでそちらを参照して入れてください。
nfcpyをインストールする
nfcpyをインストールします。
~$ pip install -U nfcpy
ひとまず、呪文も入れておきます。
~$ sudo sh -c 'echo SUBSYSTEM==\"usb\", ACTION==\"add\", ATTRS{idVendor}==\"054c\", ATTRS{idProduct}==\"02e1\", GROUP=\"plugdev\" >> /etc/udev/rules.d/nfcdev.rules'
~$ sudo udevadm control -R # then re-attach device
raspi-configを変更する
raspi-configでシリアル通信をオンにします。
sudo raspi-config
3 Interface Options
→I6 Serial Port
Would you like a login shell to be accessible over serial?
と聞かれますがNo
を選択
そのあとにWould you like the serial port hardware to be enabled?
を聞かれるのでYes
を選択
最後にOK
を選択してEscで脱出します。
シリアル通信をしているインターフェースを確認する
とりあえず、dialoutグループに今ログインしているユーザーを追加します。
~$ sudo usermod -a -G dialout $USER
シリアル通信しているインターフェースを確認します。
~$ ls -l /dev/serial*
lrwxrwxrwx 1 root root 7 Apr 29 15:15 /dev/serial0 -> ttyAMA0
lrwxrwxrwx 1 root root 5 Apr 29 15:15 /dev/serial1 -> ttyS0
ttyAMA0
があることを確認します。
これはPN532とUARTを使ってシリアル通信するためのインターフェースです。
BluetoothとUARTが衝突しないようにBluetooth機能をオフにします。
~$ sudo nano /boot/config.txt
[all]
の下に以下の文を追加します。
[all]
enable_uart=1
dtoverlay=pi3-disable-bt
PN532を接続する
PN532を接続するためにシャットダウンします。
sudo shutdown -h now
画像のようにPN532のDIPスイッチをすべて下げます。
HSU(High Speed Uart)になるようにしてください。
そしてリストのように配線します。
GPIOの配置は画像を参照してください。
Raspi | PN532 |
---|---|
5V | 5V |
GND | GND |
TXD(GPIO14) | RXD(SCL) |
RXD(GPIO15) | TXD(SDA) |
このようにTXD RXDがそれぞれ対になるようにツイストで配線します。
nfcpyでテスト
正しく通信できるかテストします。
~$ python3 -m nfc --search-tty
This is the 1.0.4 version of nfcpy run in Python 3.9.2
on Linux-6.1.21+-armv6l-with-glibc2.31
I'm now searching your system for contactless devices
** found PN532v1.6 at /dev/ttyAMA0
ttyAMA0のインターフェースを使ってPN532と通信できたようです。
配線ミスをするとERROR:nfc.clf:no reader available on path tty:AMA0
が返されます。
nfcpyでカード情報を取得する
python3でプログラムを組んで実行してみます。
import nfc
def on_connect(tag):
print(tag)
print((' \n '.join(tag.dump())))
return True # 1枚だけ読み取って終了
def main():
try:
clf = nfc.ContactlessFrontend('tty:AMA0') #環境によってtty:S0 などに変更
clf.connect(rdwr={'on-connect': on_connect})
finally:
if clf:
clf.close()
if __name__ == "__main__":
main()
モバイルsuicaを読み取ると次のような感じに
~$ python3 card_dump.py
Type4ATag MIU=253 FWT=0.038664
情報が少なくて寂しいですが問題なく読み取れました。
余談
ほかのqiitaなどにあるコードを使用するとエラーが多発しました。
import nfc
clf = nfc.ContactlessFrontend("tty:AMA0")
tag = clf.connect(rdwr={'on-connect': lambda tag: False})
print(tag)
print((' \n '.join(tag.dump())))
タイミング等の何か理由があるんでしょうがよくわからないので使うことは避けたほうがいいでしょう。
Discussion