Raspberry Pi で libnfc + PN532 NFC RFID module


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


「PN532 NFC RFID module について調べる」
https://qiita.com/nanbuwks/items/ac02bb307c9850b5e5c4
のモジュールを Raspberry Pi に接続して、 FeliCa を読んでみます。

環境

  • Raspberry Pi Model B+ V1.2
  • PN532 NFC Module SPI I2C Reader/Writer Breakout Board
  • Raspberry Pi OS Lite armhf-2020-12-04

libnfc

ソフトウェアとして、libnfc で試してみました。

なお、ホームページとして昔の資料ではこちらが示されているようですが、2022・03・10現在アクセスできませんでした。
http://www.nfc-tools.org/
現在のホームページはこちらかな?
https://nfc-tools.github.io/
コードはこちら
https://github.com/nfc-tools/libnfc
ドキュメントは Kali Linux のページが充実しているようです。
https://www.kali.org/tools/libnfc/

なお、この記事の初出では勘違いして nfcpy と誤記していました→修正しました。
USB 接続の PaSoRi リーダーだけではなく SPI / I2C / 高速シリアル接続の PN5321 でも使用できるので柔軟性が高いです。

今回はインターフェースに I2C および SPI でを使って試すこととします。

準備

  • sudo apt コマンドなどで update を済ませておきます。
  • sudo apt-get install libusb-dev で必要なライブラリをインストールしておきます。
  • sudo raspi-config で I2C 機能を有効にしておきます。
  • 再起動を済ませておきます。

インストール

libnfc のインストールは以下のサイト手順に沿って行っています。
「Raspberry Pi 3に I2C通信方式の NFCリーダライタ PN532を接続して NFC FeliCaカードを読む方法 (ラズパイ3に NXP PN532 RFIDリーダライタを接続してFeliCaや NFCカードを読み込む方法 nfcpy)」
http://www.neko.ne.jp/~freewing/raspberry_pi/raspberry_pi_3_i2c_nfc_rfid_pn532/

まず、作業場所を作りそこに移動します。


$ mkdir nfc
$ cd nfc

次に以下ページで、libnfc の最新のリリースを確認。

libnfc-1.8.0.tar.bz2 のリンク先をコピーして、以下のようにダウンロード。

$ wget https://github.com/nfc-tools/libnfc/releases/download/libnfc-1.8.0/libnfc-1.8.0.tar.bz2

解凍します。


$ bunzip2 libnfc-1.8.0.tar.bz2 
$ ls
libnfc-1.8.0.tar
$ tar xvf libnfc-1.8.0.tar 
libnfc-1.8.0/
$ ls
libnfc-1.8.0  libnfc-1.8.0.tar
$ cd libnfc-1.8.0/
$ ls
aclocal.m4      compile       contrib      HACKING.md          ltmain.sh               NEWS.md
ar-lib          config.guess  COPYING      include             m4                      README.md
AUTHORS         config.h.in   depcomp      install-sh          Makefile.am             README-Windows.md
ChangeLog       config.sub    Doxyfile     libnfc              Makefile.in             test
cmake           configure     Doxyfile.in  libnfc.conf.sample  mingw-cross-compile.sh  test-driver
CMakeLists.txt  configure.ac  examples     libnfc.pc.in        missing                 utils

コンパイル。


$ ./configure --prefix=/usr --sysconfdir=/etc

とすると、


.
.
.
Selected drivers:
   pcsc............. no
   acr122_pcsc...... no
   acr122_usb....... yes
   acr122s.......... yes
   arygon........... yes
   pn53x_usb........ yes
   pn532_uart....... yes
   pn532_spi.......  yes
   pn532_i2c........ yes
   pn71xx........... no

と出てきました。今回使いたかった PN5321の SPI、I2C は対応できているようですね。


$ make

設定ファイルを作る


$ sudo mkdir /etc/nfc
$ sudo vim /etc/nfc/libnfc.conf

として、先の記事に記されている
「Raspberry Pi 3に I2C通信方式の NFCリーダライタ PN532を接続して NFC FeliCaカードを読む方法 (ラズパイ3に NXP PN532 RFIDリーダライタを接続してFeliCaや NFCカードを読み込む方法 nfcpy)」
http://www.neko.ne.jp/~freewing/raspberry_pi/raspberry_pi_3_i2c_nfc_rfid_pn532/

libnfc.conf を作成、保存します。

I2C で物理接続

先の libnfc.conf は I2C 接続の設定になっています。
冒頭の写真のように、VCC、GND、SDA、SCL を接続します。

動作確認


$ ./utils/nfc-scan-device -v
/home/pi/nfc/libnfc-1.8.0/utils/.libs/nfc-scan-device uses libnfc 1.8.0
1 NFC device(s) found:
- Itead_PN532:
    pn532_i2c:/dev/i2c-1
chip: PN532 v1.6
initator mode modulations: ISO/IEC 14443A (424 kbps, 212 kbps, 106 kbps), FeliCa (424 kbps, 212 kbps), ISO/IEC 14443-4B (106 kbps), ISO/IEC 14443-4B' (106 kbps), ISO/IEC 14443-2B ST SRx (106 kbps), ISO/IEC 14443-2B ASK CTx (106 kbps), ISO/IEC 14443-2B-3B iClass (Picopass) (106 kbps), Innovision Jewel (106 kbps), Thinfilm NFC Barcode (106 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
target mode modulations: ISO/IEC 14443A (424 kbps, 212 kbps, 106 kbps), FeliCa (424 kbps, 212 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
$ ./examples/nfc-poll -v
/home/pi/nfc/libnfc-1.8.0/examples/.libs/nfc-poll uses libnfc 1.8.0
NFC reader: Itead_PN532 opened
NFC device will poll during 36000 ms (20 pollings of 300 ms for 6 modulations)

待ち受けになったので 手持ちの nfc タグを近づけてみます。


ISO/IEC 14443A (106 kbps) target:
    ATQA (SENS_RES): 00  04  
* UID size: single
* bit frame anticollision supported
       UID (NFCID1): b3  4a  16  89  
      SAK (SEL_RES): 08  
* Not compliant with ISO/IEC 14443-4
* Not compliant with ISO/IEC 18092

Fingerprinting based on MIFARE type Identification Procedure:
* MIFARE Classic 1K
* MIFARE Plus (4 Byte UID or 4 Byte RID) 2K, Security level 1
* SmartMX with MIFARE 1K emulation
Other possible matches based on ATQA & SAK values:
Waiting for card removing...nfc_initiator_target_is_present: Target Released
done.


手持ちの Suica を読ませてみました。

$ ./examples/nfc-poll -v
/home/pi/nfc/libnfc-1.8.0/examples/.libs/nfc-poll uses libnfc 1.8.0
NFC reader: Itead_PN532 opened
NFC device will poll during 36000 ms (20 pollings of 300 ms for 6 modulations)
FeliCa (424 kbps) target:
        ID (NFCID2): 01  12  04  12  a8  1a  15  08  
    Parameter (PAD): 05  31  43  45  46  82  b7  ff  
   System Code (SC): 00  00  
Waiting for card removing...nfc_initiator_target_is_present: Target Released
done.

インストール終了

$  sudo make install

SPI 接続で試してみる

SPI設定

sudo raspi-confi でSPIを有効にしておきます。
PN532 NFC RFID module 上のスイッチをSPI側にしておきます。

/etc/libnfc.conf のサンプルは以下の通り。
https://github.com/nfc-tools/libnfc/blob/master/libnfc.conf.sample

SPI接続のときにはどうしたらいいかな? 旧い記述は archive.org から見えるが・・・
https://web.archive.org/web/20210302140438/http://nfc-tools.org/index.php?title=Libnfc:configuration

上の記述を元に、/etc/libnfc.conf の接続設定を以下のように修正。


#device.connstring = "pn532_i2c:/dev/i2c-1"
device.connstring = "pn532_spi:/dev/spidev0.0:500000"

コメントなどを除いた libnfc.conf を表示すると


$ grep -v -e '^#' -e '^\s*$' /etc/nfc/libnfc.conf 

以下の通り。

allow_autoscan = true
allow_intrusive_scan = false
log_level = 1
device.name = "Itead_PN532"
device.connstring = "pn532_spi:/dev/spidev0.0:500000"

物理接続

RaspberryPi RPN532 サンプル接続のケーブル色
3.3v VCC
GND GND
SPI0 MOSI(PIN 19) MOSI
SPI0 MISO(PIN 21) MISO
SPI0 SCLK(PIN 23) SCK
SPI0 CE0 (PIN 24) SDA

動作チェック


$ nfc-scan-device  -v
nfc-scan-device uses libnfc 1.8.0
1 NFC device(s) found:
- Itead_PN532:
    pn532_spi:/dev/spidev0.0:500000
chip: PN532 v1.6
initator mode modulations: ISO/IEC 14443A (424 kbps, 212 kbps, 106 kbps), FeliCa (424 kbps, 212 kbps), ISO/IEC 14443-4B (106 kbps), ISO/IEC 14443-4B' (106 kbps), ISO/IEC 14443-2B ST SRx (106 kbps), ISO/IEC 14443-2B ASK CTx (106 kbps), ISO/IEC 14443-2B-3B iClass (Picopass) (106 kbps), Innovision Jewel (106 kbps), Thinfilm NFC Barcode (106 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
target mode modulations: ISO/IEC 14443A (424 kbps, 212 kbps, 106 kbps), FeliCa (424 kbps, 212 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)

認識しています

読んでみる

NFC タグを認識させてみました


$ nfc-poll -v
nfc-poll uses libnfc 1.8.0
NFC reader: Itead_PN532 opened
NFC device will poll during 36000 ms (20 pollings of 300 ms for 6 modulations)
ISO/IEC 14443A (106 kbps) target:
    ATQA (SENS_RES): 00  04  
* UID size: single
* bit frame anticollision supported
       UID (NFCID1): b3  4a  16  89  
      SAK (SEL_RES): 08  
* Not compliant with ISO/IEC 14443-4
* Not compliant with ISO/IEC 18092

Fingerprinting based on MIFARE type Identification Procedure:
* MIFARE Classic 1K
* MIFARE Plus (4 Byte UID or 4 Byte RID) 2K, Security level 1
* SmartMX with MIFARE 1K emulation
Other possible matches based on ATQA & SAK values:
Waiting for card removing...nfc_initiator_target_is_present: Target Released
done.

I2C で読んだ時と同じ結果が得られたので OK.

I2C vs SPI ?

今回使ったモジュールとは別ですが、Adafruit の Adafruit PN532 RFID/NFC Breakout and Shield の解説記事
「Python & CircuitPython | Adafruit PN532 RFID/NFC Breakout and Shield | Adafruit Learning System」
https://learn.adafruit.com/adafruit-pn532-rfid-nfc/python-circuitpython

This breakout is designed to work with I2C, SPI and UART, however I2C AND UART DO NOT WORK RELIABLY ON RASPBERRY PI. If you're using the PN532 with Raspberry Pi, use SPI!

とありました。

Adafruit PN532 RFID/NFC Breakout and Shield の構成は PN532 NFC RFID module とほぼ変わらないようです。
なので RaspberryPi では SPI を使うのが良さそうです。