RaspberryPiで交通系ICカードを読み取る(RC-S380の接続)
以前、交通系ICカードの読み取りをWindows8.1&Androidにて行うというセッションをまどべんよっかいちさんでさせていただきましたが、 RaspberryPiでもできないかと思いやってみました。WindowsではC#を用いてAPIを呼び出しカード内のIDmの読み込みを行っていましたが、 RaspberryPiではpythonを使うことにします。pythonはなんとなく読める程度の知識しかないのでかなり不安はありますが何とかなるかなという軽い気持ちで。
【参考】まどべんよっかいち資料(タイトルを気にしてはいけない)
www.slideshare.net接続に使ったリーダー
使用したリーダは↓です。2000~3000円ぐらいで購入できると思いますが、中古市場で買えばもっと安く手に入ると思います。
RC-S380接続から認識まで
実は接続するとあっさり認識します。
接続前のlsusb
の内容
~ $ lsusb Bus 001 Device 006: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode) Bus 001 Device 005: ID 2019:1201 PLANEX Bus 001 Device 004: ID 05e3:0608 Genesys Logic, Inc. USB-2.0 4-Port HUB Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp. LAN9500 Ethernet 10/100 Adapter / SMSC9512/9514 Hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
接続後のlsusb
の内容
~ $ lsusb Bus 001 Device 007: ID 054c:06c3 Sony Corp. Bus 001 Device 006: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode) Bus 001 Device 005: ID 2019:1201 PLANEX Bus 001 Device 004: ID 05e3:0608 Genesys Logic, Inc. USB-2.0 4-Port HUB Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp. LAN9500 Ethernet 10/100 Adapter / SMSC9512/9514 Hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 007: ID 054c:06c3 Sony Corp.
が追加されているのがわかります。
ちなみにdmesgの結果は以下が追加されています。
(中略) [ 100.229467] usb 1-1.3: new full-speed USB device number 7 using dwc_otg [ 100.334131] usb 1-1.3: New USB device found, idVendor=054c, idProduct=06c3 [ 100.334171] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=4 [ 100.334191] usb 1-1.3: Product: RC-S380/P [ 100.334208] usb 1-1.3: Manufacturer: SONY [ 100.334223] usb 1-1.3: SerialNumber: ????????
(注)SerialNumberは伏せてあります。
デバイスの認識としてはこれで完了です。おめでとうございます。
設定の追加
このままでも使用することはできるのですが、一般ユーザはsudo
経由でしか使用することができません。そこで、一般ユーザからでも使用可能なように以下のファイルを作成します。
~ $ sudo vim /etc/udev/rules.d/nfcdev.rules
ファイルの内容は以下になります。違うデバイスを使用するときにはidVendorとidProductの値を変更してください。
SUBSYSTEM=="usb", ACTION=="add", ATTRS{idVendor}=="054c", ATTRS{idProduct}=="06c3", GROUP="plugdev"
ファイルの編集が終了すると、ディレクトリは以下のようになります。
~ $ ls /etc/udev/rules.d/* -l -rw-r--r-- 1 root root 114 3月 18 17:45 /etc/udev/rules.d/40-scratch.rules -rw-r--r-- 1 root root 506 1月 14 03:44 /etc/udev/rules.d/99-com.rules -rw-r--r-- 1 root root 117 4月 22 20:58 /etc/udev/rules.d/nfcdev.rules
python側の設定
pythonのものはRaspbianにすでにインストールされているので、実行時に読み込むモジュール類のインストールを行うことになります。NFC関連のモジュールはnfcpyを使用します。
【参考】http://nfcpy.readthedocs.org/en/latest/topics/get-started.html
ネットをみるとbzr
で設定することが多いようなのですが、あまり詳しくないので行き当たりばったりで設定をチャレンジして見ました。事前にpython-usb
をインストールし、サイトからnfcpyモジュールのソースをwget
して展開をします。
~ $ sudo apt-get install python-usb
(途中経過は略)
~ $ wget https://launchpad.net/nfcpy/0.11/0.11.0/+download/nfcpy-0.11.0.tar.gz
(途中経過は略)
~ $ tar xvzf nfcpy-0.11.0.tar.gz
(途中経過は略)
展開したディレクトリに移動し、その中のexample
ディレクトリにあるtagtool.py
を実行します。
~/nfcpy-0.11.0 $ ls HISTORY.rst LICENSE README.rst docs examples nfc setup.py tests tools ~/nfcpy-0.11.0 $ cd examples/ ~/nfcpy-0.11.0/examples $ ls __init__.py llcp-dta-iut.py phdc-test-manager.py beam.py llcp-dta-test.py rfstate.py cli.py llcp-test-client.py sense.py handover-test-client.py llcp-test-server.py snep-test-client.py handover-test-server.py ndeftool.py snep-test-server.py listen.py phdc-test-agent.py tagtool.py ~/nfcpy-0.11.0/examples $ sudo python tagtool.py
これでうまくいくのかなと思ったのですが…以下のような表示がでます。
~/nfcpy-0.11.0/examples $ sudo python tagtool.py Traceback (most recent call last): File "tagtool.py", line 37, in <module> from cli import CommandLineInterface File "/home/pi/nfcpy-0.11.0/examples/cli.py", line 35, in <module> import nfc File "/home/pi/nfcpy-0.11.0/nfc/__init__.py", line 28, in <module> from clf import ContactlessFrontend File "/home/pi/nfcpy-0.11.0/nfc/clf/__init__.py", line 35, in <module> from . import device File "/home/pi/nfcpy-0.11.0/nfc/clf/device.py", line 39, in <module> from . import transport File "/home/pi/nfcpy-0.11.0/nfc/clf/transport.py", line 34, in <module> raise ImportError("missing usb1 module, try 'pip install libusb1'") ImportError: missing usb1 module, try 'pip install libusb1'
最後の一文をみると「usb1
というモジュールをpipをつかってインストールしてね」ってことらしいです。インストールしてみます。(pytonに詳しくないのでかなり手さぐりです)
~/nfcpy-0.11.0/examples $ sudo pip install libusb1 Downloading/unpacking libusb1 Downloading libusb1-1.5.0.tar.gz (45kB): 45kB downloaded Running setup.py (path:/tmp/pip-build-HsYzk_/libusb1/setup.py) egg_info for package libusb1 Installing collected packages: libusb1 Running setup.py install for libusb1 Successfully installed libusb1 Cleaning up... ~/nfcpy-0.11.0/examples $
無事にインストールできたみたいです。では気を取り直して実行してみます。
~/nfcpy-0.11.0/examples $ sudo python tagtool.py [nfc.clf] searching for reader on path usb [nfc.clf] using SONY RC-S380/P NFC Port-100 v1.11 at usb:001:007 ** waiting for a tag ** Type3Tag 'FeliCa Standard (RC-SA00/1)' ID=??????????????? PMM=???????????????? SYS=???? ~/nfcpy-0.11.0/examples $
実行すると読み込み待ち状態になるのでFelicaカードを読み込んでみるとIDなどが表示されます。 無事に動作したようです。(値が?になっていますが伏せているだけで実際には値が表示されます)
もう、動作したのですが折角なのでpythonプログラムから動作するところまでやってみます。このあたりは公式サイトに使い方が乗っているのですが、自分のやり方ではbzr
を使ってなかったのではまってしまいましたので、念のための記述になります。
~/nfcpy-0.11.0/examples $ python Python 2.7.9 (default, Mar 8 2015, 00:52:26) [GCC 4.9.2] on linux2 Type "help", "copyright", "credits" or "license" for more information.
通常であれば、import nfc
だけでよいのですが、自分のやった方法ではnfcモジュールが読み込めないエラーが発生します。そこで、先ほどのtagtool.py
をのぞいてみたところ、importをする前にパスにnfcpyのモジュールパスをインストールしていることがわかりました。sys.path.insert処理がそれにあたります。
そこでimport nfc
を行う前に
>>> import sys >>> sys.path.insert(1, '/home/pi/nfcpy-0.11.0')
を行うことにします。'/home/pi/nfcpy-0.11.0'
の部分を自分の作業したPathに変更してください。
【実行例】
>>> import sys >>> sys.path.insert(1, '/home/pi/nfcpy-0.11.0') >>> import nfc >>> clf = nfc.ContactlessFrontend('usb') >>> print(clf) SONY RC-S380/P on usb:001:005 >>> def connected(tag): print(tag); return False ... >>> clf.connect(rdwr={'on-connect': connected}) Type3Tag 'FeliCa Standard (RC-S???)' ID=???????????????? PMM=???????????????? SYS=???? <nfc.tag.tt3_sony.FelicaStandard object at 0x????????> >>> clf.close()
これで読み込みができました。
公式サイトの設定例と違うことをしたのではまってしまいましたが、そのままやればもう少し楽ができたのかもしれません。今後はpythonにも触れていこうと思います。
【参考】