LoginSignup
88
104

More than 5 years have passed since last update.

Raspberry PiにNFCリーダを接続してSuicaを読み取る

Last updated at Posted at 2017-12-17

このエントリは「Raspberry Piでスマートロックつくった」の解説3つめになります。
スマートロックなのでカッコよくしたいです。なのでNFCリーダを使い、ドアの外からSuicaをタッチしたらカギを開閉できるようにします。このエントリではSONYのNFCリーダPaSoRi RC-S380をRaspberry Piに接続し、SuicaカードをタッチしてIDmを取り出すまでをやってみます。

準備

RC-S380はAmazonなどで3000円くらいで買えます。家電量販店でもたまに売ってます。
PythonでNFCリーダを取り扱うライブラリとしてnfcpyというのがあるのでインストールします。

$ sudo pip install nfcpy

また、Githubからサンプルコードも頂戴しておきます。
nfcpy | Github
それではさっそくRC-S380をRaspberry PiにUSB接続し、examples/tagtool.pyを実行してみます。なおnfcpyはPython2.xで動作します。

$ sudo python2 examples/tagtool.py

うまく行けば、「** waiting for a tag **」と表示されます。ここでSuica等のNFCタグをタッチすると、そのタグを読み込んだ結果が表示されます。Suicaに限らずPasmoやNanacoやマイナンバーカード等、身近にある色んなNFCタグをタッチしてみて下さい。

IDmを取り出す

SuicaやPasmo等のFeLiCaタグにはすべてIDmというユニークなIDが割り振られています。これはいわゆる製造番号のようなものだそうで、これを使えばタッチしたカードの個別な識別が可能になります。※ただしこのIDmはFeLiCaカードのエミュレーションにより偽装できてしまう点は留意しておくべきです。単なるパスワードとして考え厳重に管理し、それをタッチするだけで入力できるのがFeLiCaカード、と考えておくとよいでしょう。
さて、それではSuicaがタッチされた時にIDmを取り出すプログラムを動かしてみます。

suica.py
# -*- coding: utf-8 -*-
import binascii
import nfc
import time
from threading import Thread, Timer

# Suica待ち受けの1サイクル秒
TIME_cycle = 1.0
# Suica待ち受けの反応インターバル秒
TIME_interval = 0.2
# タッチされてから次の待ち受けを開始するまで無効化する秒
TIME_wait = 3

# NFC接続リクエストのための準備
# 212F(FeliCa)で設定
target_req_suica = nfc.clf.RemoteTarget("212F")
# 0003(Suica)
target_req_suica.sensf_req = bytearray.fromhex("0000030000")

print 'Suica waiting...'
while True:
    # USBに接続されたNFCリーダに接続してインスタンス化
    clf = nfc.ContactlessFrontend('usb')
    # Suica待ち受け開始
    # clf.sense( [リモートターゲット], [検索回数], [検索の間隔] )
    target_res = clf.sense(target_req_suica, iterations=int(TIME_cycle//TIME_interval)+1 , interval=TIME_interval)

    if target_res != None:

        #tag = nfc.tag.tt3.Type3Tag(clf, target_res)
        #なんか仕様変わったっぽい?↓なら動いた
        tag = nfc.tag.activate_tt3(clf, target_res)
        tag.sys = 3

        #IDmを取り出す
        idm = binascii.hexlify(tag.idm)
        print 'Suica detected. idm = ' + idm

        print 'sleep ' + TIME_wait + ' seconds'
        time.sleep(TIME_wait)
    #end if

    clf.close()

#end while

実行するには管理者権限が必要です。

sudo python2 suica.py

Suicaをタッチしてみて、IDmが表示されれば成功です。
自分が普段使うSuicaのIDmを覚えさせておき、次回以降同じカード=同じIDmがタッチされた時はサーボを回してカギを開ける、という風に実装すればいよいよスマートロックっぽくなってきます。



なお、nfcpyではよくconnect()メソッドを使ってタグ検知する手法が紹介されていますが、これではApple PayのExpress Cardに登録されたSuicaを検知できないようです。sense()を使うことでApple Pay内Suicaを検知できますが、今度は逆にconnect()で検知できていた各種NFCカードが検知できないようです。使用目的やお持ちのカードに合わせて選択すると良いかと思います。(参考:nfcpy で Apple Pay のエクスプレスカードを扱う - Qiita

管理者権限なしで動かす

実行する時にsudoしなくてもいいようにします。
まずlsusbコマンドを打って接続されているRC-S380のIDを調べます。

$ lsusb
Bus 001 Device 004: ID XXXX:YYYY Sony Corp.

上記のXXXX、YYYYという部分に表示されるIDを使って、下記のとおりコマンドを実行します。

$ sudo sh -c 'echo SUBSYSTEM==\"usb\", ACTION==\"add\", ATTRS{idVendor}==\"XXXX\", ATTRS{idProduct}==\"YYYY\", GROUP=\"plugdev\" >> /etc/udev/rules.d/nfcdev.rules'

これでsudo無しでもRC-S380を使えるようになりました。
Next:Raspberry PiでHueを操作する

88
104
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
88
104