PasoriとRaspberryPiで計測した時間をGUIで表示 #柏の葉高校
見出し画像

PasoriとRaspberryPiで計測した時間をGUIで表示 #柏の葉高校

千葉県立柏の葉高等学校 情報理数科

目次
1)使用した機材,開発環境
2)GUIとは
3)PasoriでICチップタッチ時の時間を計測する方法
4)Tkinterで計測した時間を表示する方法

1)使用した機材,開発環境

• RaspberryPi4(Model B)
• Pasori(Model RC-S380)
• ICカード(Pasmo等)
• Python(ver2.7または3.5以降)
• tkinter

2)GUIとは

Graphical User Interface の略で,マウスなどのポインティングデバイスで操作できるインターフェースのことです。現在のインターフェースは,ほぼすべてGUIを採用している。

3)PasoriでICチップタッチ時の時間を計測する

RaspberryPiを起動してPasoriと接続してください。また,このときRaspberry Piはネットワークに接続しておきましょう。
その後コマンドプロンプトを開き(↓画像の >_ マークのやつ)

図1

lsusb

と入力してPasoriと接続できているか確認してください, Sony Corp. と書かれたデバイスがあれば大丈夫です。


次にnfcpyのインストールをします。

sudo pip3 install nfcpy

このままだと sudo と毎回最初に入力する必要があるので省略をします。

sudo nano /etc/udev/rules.d/nfcdev.rules

上記のコードを実行するとコードを保存できるテキストエディタが出てきます。
そこに以下のコードを入力して保存してください,保存は Ctrl+O+Enter です。

SUBSYSTEM=="usb",ACTION=="add",ATTRS{idVendor}=="054c",ATTRS{idProduct}=="06c3", GROUP="plugdev" # Sony RC-S380/P

保存をしたら Ctrl+X でテキストエディタを閉じてください。再起動したら sudo を入力する必要がなくなります。

次にICチップの着脱に反応するアプリを作ります。

nano ファイル名.py

と入力してエディタを開いてください。
その際に nfc.py というファイル名にすると不具合が生じます。
以下のコードがアプリのコードです。

import binasciiimport nfcimport osclass MyCardReader(object):
   def on_connect(self, tag):        #タッチ時の処理
       print("【 Touched 】")        #タグ情報を全て表示
       print(tag)        #IDmのみ取得して表示
       self.idm = binascii.hexlify(tag._nfcid)
       print("IDm : " + str(self.idm))        #特定のIDmだった場合のアクション
       if self.idm == "00000000000000":
           print("【 登録されたIDです 】")
       return True
   def read_id(self):
       clf = nfc.ContactlessFrontend('usb')
       try:
           clf.connect(rdwr={'on-connect': self.on_connect})
       finally:
           clf.close()if __name__ == '__main__':
       cr = MyCardReader()    while True:        #最初に表示
       print("Please Touch")        #タッチ待ち
       cr.read_id()        #リリース時の処理
       print("【 Released 】")

このアプリを実行する際は

python3 test-1.py

と入力して実行してください。
終了する際は別のコマンドプロンプトを開き

pkillKILLf test-1.py

と入力し実行してください
次に接着時間を計測できるように改造していきます。

import binascii
import nfc
import os
from datetime import datetime as dt
import time
global t1
class MyCardReader(object):
   def on_connect(self, tag):
       #タッチ時の処理
       print("【 Touched 】")
       global t1
       t1 = dt.now()
       #タグ情報を全て表示
       #IDmのみ取得して表示
       self.idm = binascii.hexlify(tag._nfcid)
       print("IDm : " + str(self.idm))
       #特定のIDmだった場合のアクション
       if self.idm == b'01010801741e2410':
       print("【 登録されたIDです 】")
       return True
   def read_id(self):
       clf = nfc.ContactlessFrontend('usb')
   try:
       clf.connect(rdwr={'on-connect': self.on_connect})
   finally:
       clf.close()
if __name__ == '__main__':
   cr = MyCardReader()
   while True:
       #最初に表示
       #タッチ待ち
       cr.read_id()
       #リリース時の処理
       t2 = dt.now()
       t3 = t2-t1
       print(t3)

変更点としては
• Import に datetime とtime を追加したこと
• global 変数を作成したこと
• タッチ時に作成した global 変数に現在時刻を入れたこと
• リリース時の処理に新たに作成した変数に現在時刻を入れたこと
• 新たに作成した変数に上記の変数の差分を入れたこと
• print で差分を入れた変数を表示したこと
• 多少不必要だと判断した部分を削除したこと

4)Tkinterで計測した時間を表示する方法

上記のコードのままでは計測した時間はコマンドプロンプト内でしか見られないので tkinter で 表示用のGUI を作成します。

import binascii
import nfc
import os
import datetime as dt
import time
import tkinter as tk
import tkinter.font as tkFont
global t1
class MyCardReader(object):
   def on_connect(self, tag):
       #タッチ時の処理
       print("【 Touched 】")
       global t1
       t1 = dt.datetime.now()
       print(t1)
       #IDmのみ取得して表示
       self.idm = binascii.hexlify(tag._nfcid)
       print("IDm : " + str(self.idm))
       #特定のIDmだった場合のアクション
       if self.idm == b'01010801741e2410':
       print("【 登録されたIDです 】")
       return True
   def read_id(self):
       clf = nfc.ContactlessFrontend('usb')
   try:
       clf.connect(rdwr={'on-connect': self.on_connect})
   finally:
       clf.close()
if __name__ == '__main__':
   cr = MyCardReader()
   while True:
       #タッチ待ち
       cr.read_id()
       #リリース時の処理
       t2 = dt.datetime.now()
       t3 = t2-t1
       app = tk.Tk()
       app.title("test")
       app.geometry("1500x1000")
       fontStyle = tkFont.Font(family = "Lucida Grande", size=200)
       label = tk.Label(app,text="00:00",font=fontStyle)
       label.config(text = str(t3).split('.')[0])
       label.pack()
       app.mainloop()

変更点としては
• import に tkinter と tkinter.font を追加したこと
• 変数に時間の差分を入れた以降にコードを追加したこと
注意点としては
lavel.pack() と app.mainloop() の記述がないとウィンドウが表示されないことです。

これで GUIでPasoriとRaspberryPiで計測した時間を表示できるようになりました。

図1

これが実際に作動した時の画像です。

みんなにも読んでほしいですか?

オススメした記事はフォロワーのタイムラインに表示されます!
生徒のモチベーションにも繋がります!
千葉県立柏の葉高等学校 情報理数科
千葉県立柏の葉高等学校 情報理数科の公式note / 全国専門学科「情報科」高等学校長会 事務局 / 日本で唯一の「情報理数科」の高校 / 【投稿内容】◇専門教科「情報」の授業 ◇情報理数科独自の取り組み ◇Google Workspace&Microsoft Teamsの活用