NFCpyにUIをつけたい


動機

リーダーの上に何か載せたら情報が表示されるものがつくりたい
例えば、薬を載せたら何に使うものか表示されたり、いろいろ使えそう

構成

簡単にできるかと思ったのですが、技量不足のため難儀しました
結果から話すと、UIとReaderを分け、watchdogでテキスト監視し変化があったら内容を読み取る方式にしました
ダメだったのは、1ファイルで同じループ内に書くとどちらかが止まる、Scocket通信でも止まりました

スクリプト

実行ファイルと同じ階層にtemp/nfc.txtがあり、
Reader -> nfc.txt 書き込み
UI   -> nfc.txt 監視 変化があれば内容を読む tag1,2,3であれば対応した静止画を表示

Reader

nfcsimple.py
import nfc
import binascii
import sys
import os

globalDirpath = os.path.dirname(__file__)
txtpath = globalDirpath+'/temp/nfc.txt'

def on_connect(tag):

    if tag.ndef:
        if tag.ndef.length > 0:
            print("NDEF Message:")
            for i, record in enumerate(tag.ndef.records):
                print(record.text) #tag1
                with open(txtpath, mode='w') as f:
                    f.write(record.text)

    return True



def main():

    while True:
        with nfc.ContactlessFrontend("usb") as clf:
            rdwr = {
                'on-connect': on_connect
            }
            clf.connect(rdwr=rdwr)


if __name__ == '__main__':
    main()

UI

ui.py
import pygame
import sys
import os
from pygame.locals import *
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import threading

imgBtlBG = pygame.image.load("img/bg.jpg")
imgBtl1 = pygame.image.load("img/01.jpg")
imgBtl2 = pygame.image.load("img/02.jpg")
imgBtl3 = pygame.image.load("img/03.jpg")

globalDirpath = os.path.dirname(__file__)
dirpath = globalDirpath+'/temp/'

class ChangeHandler(FileSystemEventHandler):

    isPlay = False
    NfcTag = "None"

    def StopOverlay(self):
        self.isPlay = False
        self.NfcTag = "None"

    def on_modified(self, event):
        filepath = event.src_path
        filename = os.path.basename(filepath)
        if filename=="nfc.txt":
            with open(filepath) as f:
                s = f.read()
                print(s)
                self.isPlay = True
                self.NfcTag = s
                t=threading.Timer(3,self.StopOverlay)
                t.start()


event_handler = ChangeHandler()
observer = Observer()
observer.schedule(event_handler, dirpath, recursive=True)
observer.start()

def draw(bg):
    global isPlay,NfcTag

    if event_handler.isPlay:
        if  event_handler.NfcTag=="tag1":
            bg.blit(imgBtl1, [0,0])
        elif event_handler.NfcTag=="tag2":
            bg.blit(imgBtl2, [0,0])
        elif event_handler.NfcTag=="tag3":
            bg.blit(imgBtl3, [0,0])
    else:
        bg.blit(imgBtlBG, [0, 0])



def main():
    pygame.init()
    pygame.display.set_caption("Title")
    flags = pygame.DOUBLEBUF | pygame.HWSURFACE | pygame.FULLSCREEN
    screen = pygame.display.set_mode((0, 0), flags)
    clock = pygame.time.Clock()

    while True:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                observer.stop()
                observer.join()
                pygame.quit()
                sys.exit()


        draw(screen)
        pygame.display.update()

        clock.tick(30)

if __name__ == '__main__':
    main()

実行

cd /projectdir
python3 nfcsimple.py & python3 ui.py

gif

youtube 全パターン

タグに書き込む場合、こちら