PaSoRiでNFCタグとFeliCaを読み込んで出力


はじめに

NFCタグ、FeliCaで読み取りを行った時の備忘です。
ndefのデータ読み取りがpretty()での例が多かったので、登録したままのテキストだけを取り出すがゴールです。
Raspberry Piへの設定とnfcpyの仕様確認が大事です。

使用したデバイス

Raspberry Pi3
PaSoRi RC-S380
NFCタグ

Raspberry Pi3

VNC Viewer経由でコードを書いていたのでWifi(通常時)とイーサネットでの有線接続(Raspberry Pi設定)、PaSoRiを使うを理由に使ったものです。

USBのハブがあればRaspberry Pi Zero(W)などでも可能かと思います。色々揃えると値段的に同じくらいになるかも?

PaSoRi

RC-S380以外での動作確認はなしです。

NFCタグ

カード状の板にNFCタグのシールを貼ったり、板状のNFCが安くなっているようです。

Raspberry piの設定

USBで繋いだパソリの確認

$ lsusb

nfcpyの設定

なかなか入らなくて、bzr branch lp:nfcpy したり、gitで元ソースをcloneしてました。
使えるようになった決め手がはっきりしていないです。

参考にしたサイトのURLを記載します。
https://devadjust.exblog.jp/23018234/
https://github.com/nfcpy/nfcpy
http://pongsuke.hatenablog.com/entry/2017/05/17/164317

実装

nfcpyの仕様

出力仕様

  • FeliCaを読み込んでIDmを出力
  • NFCタグを読み込んで、書き込んだテキストを読み込み出力。テキストが同じ場合はまとめる
  • FeliCaを最後にタッチすると終了

コード

こちらの記事を参考にさせてもらいました。
https://qiita.com/undo0530/items/89540a03252e2d8f291b#idm%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99

私が書き換えたpythonのコード構成は雑なので参考までに
try ~ catch ~ finallyを入れた方がいいかなとかは別途進めていただけると。

# coding: utf-8
import nfc
import binascii
import time
from threading import Thread, Timer

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

# NFC接続リクエストのための準備
# 212F(FeliCa)で設定
target_req_felica = nfc.clf.RemoteTarget("212F")

# 106A(NFC type A)で設定
target_req_nfc = nfc.clf.RemoteTarget("106A")

def check_FeliCa():
    print  'FeliCa waiting...'
    # USBに接続されたNFCリーダに接続してインスタンス化
    clf = nfc.ContactlessFrontend('usb')
    # clf.sense( [リモートターゲット], [検索回数], [検索の間隔] )
    target_res = clf.sense(target_req_felica, iterations=int(TIME_cycle//TIME_interval)+1 , interval=TIME_interval)
    if not target_res is None:
        tag = nfc.tag.activate(clf, target_res)

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

        #sleepなしでは次の読み込みが始まって終了する
        print 'sleep ' + str(TIME_wait) + ' seconds'
        time.sleep(TIME_wait)

    clf.close()

def check_NFC():
    print  'NFC and FeliCa waiting...'
    # USBに接続されたNFCリーダに接続してインスタンス化
    clf = nfc.ContactlessFrontend('usb')

    mydict = {}
    while True:
        target_res = clf.sense(target_req_nfc,target_req_felica, iterations=int(TIME_cycle//TIME_interval)+1 , interval=TIME_interval)
        if not target_res is None:
            tag = nfc.tag.activate(clf, target_res)
            print 'TAG type: ' + tag.type

            # FeliCaカードをタッチしたら読み込みをやめる
            if tag.type == "Type3Tag":
                break
            # Type1,Type2:NFCタグ、Type4:Android端末でのNFCなど
            else:
                # NFCタグに埋めたtextを読む
                records = tag.ndef.records
                for record in records:
                    print 'NFC detected. record.text = ' + record.text
                    # str()で変換するとユニコードオブジェクトにならない
                    key = str(record.text)
                    mydict[key] = key

                print 'sleep ' + str(TIME_wait) + ' seconds'
                time.sleep(TIME_wait)
    for dic in mydict :
        print(dic)

    clf.close()

check_FeliCa()
check_NFC()

最後に

材料はほぼAmazonで揃いますし、家電量販店でも取り置きサービスなどがあるので細かいパーツを探す苦労がなくなりました。
当初iPhoneアプリで作成する予定がFeliCaの読み取りがうまくできず、ラズパイの利用となりました。
iPhoneでCore NFCでFeliCaの読み取りができればなと・・・。
http://www.itmedia.co.jp/mobile/articles/1802/08/news030_2.html