SONY非接触型カードリーダーRC-S380とraspberry pi(実装編)NFCを読み込んでLCDにID表示まで

ニュース

SONY非接触型カードリーダーRC-S380とraspberry piの連携記事も3回目です。

集めたコードを利用してNFCタグを読み込んで、そのIDをLCDに表示させます。

経緯は前回までの記事を追っかけてください。

非プログラマーなので記事内のコードはアテにしないでください。一応動きますが。

メインプログラムの作成

先に結論としてハマった箇所があります。それはプログラムを書くのはいいけど、どういう環境・形式で作れば良いのかということです。

NFCはnfcpyで実行します。これはこれで単体の.pyファイルです。LCDの表示もサンプルファイルのi2clcda.pyを参考にコマンドを記述していきます。

Python以外のプログラム言語と同じように、他のpyファイルというかライブラリというか、そういう物を読み込んで実行するのだろうと、多少の経験と書籍からは理解しています。

しかし、実際にどうやって記述するのか皆目見当も尽きません。

特にディレクトリの構成がよく分かりません。全部が同じディレクトリなら分かり易いのですけど、nfcなどもディレクトリにまとまっていますし、場所が全部別なので・・・。

ディレクトリ構成

一応、画像のようにホームにまとめています。(Pimoroniは使っていません)

集めたコードから読み解いてみました。前回に書いたようにほぼ元となるコードでトライアンドエラーしてみました。必要無い部分を自分なりに削除して動く所までにしました。

それがこちら。

mymain.py

説明します。間違っていたらどなたか教えてください。一応動作します。

#!/usr/bin/env python #おまじない
# coding:UTF-8 #UTF8

import nfc #nfcのmoduleを読み込む
import binascii #IDの文字列取るのに利用するため
from i2clcda import * #これ微妙・・・
import time #参考コードの利用そのまま
from threading import Thread, Timer #参考コードの利用そのまま

LCDに表示させるmoduleは、名前?を無視できるので利用しました。本当は別のカタチで実現するのでしょうけど、分からないので全部?の意味で読み込んでいます。

多分、クラスの継承のことなんですけど、まだ理解できていません。

from i2clcda import *

参考Pythonによる大きなプログラムの作り方

とても参考になりました。ただ結局、これは使いませんでした。
LCDに表示するコードは今回のプログラムmymain.pyの中に書きました。

# 読み取り待ち受けの1サイクル秒
TIME_cycle = 10.0 #この感覚は別に1.0でも良いと思う
# 待ち受けの反応インターバル秒
TIME_interval = 0.2
# タッチされてから次の待ち受けを開始するまで無効化する秒
TIME_wait = 3

# NFC接続リクエストのための準備
# 212F(FeliCa)で設定 #テストでFeliCa残してあります。
target_req_felica = nfc.clf.RemoteTarget("212F")
# 106A(NFC type A)で設定
target_req_nfc = nfc.clf.RemoteTarget("106A")

これらは、参考先をほぼそのまま使っています。

LCDへの表示

今回、LCDの表示もしたいので、その部分を追加します。

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

mydict = {}
while True:
target_res = clf.sense(target_req_nfc,target_req_felica, iterations=int$
if not target_res is None:
tag = nfc.tag.activate(clf, target_res)
print 'TAG type: ' + tag.type
#購入したNFC Type2Tagのidを取得し表示
print str(tag.identifier).encode('hex').upper()
#そのIDを代入
t2id = str(tag.identifier).encode('hex').upper()
mmes = "I got it!" #2行目に文字列用意
#LCDの1行目にID、2行目に上記のメッセージを表示させる
lcd_string(t2id,LCD_LINE_1)
lcd_string(mmes,LCD_LINE_2)
break

for dic in mydict :
print(dic)

clf.close()
check_NFC()

以下の記述方法でtagのIDを取得しています。

print str(tag.identifier).encode('hex').upper()

参考nfcpyでType2Tag NXP NTAG213のIDを取得する方法

上記の「#購入したNFC Type2Tagのidを取得し表示」の部分で利用し、変数に代入しています。そして、前回の記事の通り、lcd_string(t2id,LCD_LINE_1)でLCDに表示させています。

コード全文

最終的なコードは以下になりました。

nfcpyはインストールされたライブラリみたいに利用する?ので、インポートして、timeなどはシステムライブラリ?なので、それもインポートです。

LCDへの表示は、mymain.pyに直接記述しています。

上からNFC関係、LCD関係にして、「def main():」行から読み取ったタグIDを表示させています。まだ無駄な部分や意味の無い部分はあると思いますが、これで一旦はOKにします。

これらをmymain.pyとして保存しました。(※以下コードはスペースのインデントがありません。コピペは気をつけてください)

#!/usr/bin/env python
# coding:UTF-8
import nfc
import binascii
import time
from threading import Thread, Timer
import smbus
import sys
# 読み取り待ち受けの1サイクル秒
TIME_cycle = 3.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")
# Define some device parameters
I2C_ADDR = 0x27 # I2C device address, if any error, change this address to 0x3f
LCD_WIDTH = 16 # Maximum characters per line
# Define some device constants
LCD_CHR = 1 # Mode - Sending data
LCD_CMD = 0 # Mode - Sending command
LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line
LCD_LINE_3 = 0x94 # LCD RAM address for the 3rd line
LCD_LINE_4 = 0xD4 # LCD RAM address for the 4th line
LCD_BACKLIGHT = 0x08 # On
#LCD_BACKLIGHT = 0x00 # Off
ENABLE = 0b00000100 # Enable bit
# Timing constants
E_PULSE = 0.0005
E_DELAY = 0.0005
#Open I2C interface
#bus = smbus.SMBus(0) # Rev 1 Pi uses 0
bus = smbus.SMBus(1) # Rev 2 Pi uses 1
def lcd_init():
# Initialise display
lcd_byte(0x33,LCD_CMD) # 110011 Initialise
lcd_byte(0x32,LCD_CMD) # 110010 Initialise
lcd_byte(0x06,LCD_CMD) # 000110 Cursor move direction
lcd_byte(0x0C,LCD_CMD) # 001100 Display On,Cursor Off, Blink Off
lcd_byte(0x28,LCD_CMD) # 101000 Data length, number of lines, font size
lcd_byte(0x01,LCD_CMD) # 000001 Clear display
def lcd_byte(bits, mode):
# Send byte to data pins
# bits = the data
# mode = 1 for data
# 0 for command
bits_high = mode | (bits & 0xF0) | LCD_BACKLIGHT
bits_low = mode | ((bits<<4) & 0xF0) | LCD_BACKLIGHT
# High bits
bus.write_byte(I2C_ADDR, bits_high)
lcd_toggle_enable(bits_high)
# Low bits
bus.write_byte(I2C_ADDR, bits_low)
lcd_toggle_enable(bits_low)
def lcd_toggle_enable(bits):
# Toggle enable
time.sleep(E_DELAY)
bus.write_byte(I2C_ADDR, (bits | ENABLE))
time.sleep(E_PULSE)
bus.write_byte(I2C_ADDR,(bits & ~ENABLE))
time.sleep(E_DELAY)
def lcd_string(message,line):
# Send string to display
message = message.ljust(LCD_WIDTH," ")
lcd_byte(line, LCD_CMD)
for i in range(LCD_WIDTH):
lcd_byte(ord(message[i]),LCD_CHR)
# Main program block
def main():
# Initialise display
lcd_init()
print 'NFC waiting...'
# USBに接続されたNFCリーダに接続してインスタンス化
clf = nfc.ContactlessFrontend('usb')
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
print str(tag.identifier).encode('hex').upper()
msg1 = str(tag.identifier).encode('hex').upper()
msg2 = "I got it!"
#LCDに表示
lcd_string(msg1,LCD_LINE_1)
lcd_string(msg2,LCD_LINE_2)
print 'sleep ' + str(TIME_wait) + ' seconds'
time.sleep(TIME_wait)
clf.close()
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
pass
finally:
# LCD_BACKLIGHT = 0x00
lcd_byte(0x01, LCD_CMD)
sys.exit(0)

Pythonってインデントが面倒くさい・・・。インデントのエラーでハマって何をしているのか分からなくなって時間掛かってしまいました。慣れるしかないですね。

エラーメッセージも分かり易いし、これまで僅かな知識があるプログラム言語よりも理解し易いと思いました。

動作テスト

こんな感じで実行できました。

——実行結果——

nfc動画gif

ここまでで、基本動作はOKですね。後は、NFCタグにメッセージが入れられますので、何かを書き込んで読み込むか、IDはユニーク(固有の)番号ですから、このままIDによって動作を変更させるプログラムを追加していきたいと思います。

NFCタグ内には少ない情報しか書き込めないので、プログラムの条件文のように何かのトリガーにするのが望ましいですね。

何かできたらまたご紹介します。

非接触型のカードリーダー、LCDキャラクタディスプレイも非常に安価で手に入ります。試してみてください。

Pythonで私でも分かりやすかった本

楽しいサンプル、わかりやすい例えとイラスト。トコトン丁寧な解説で、きほんの「き」からしっかり学べます。まったくのプログラミング未経験でも大丈夫。画面に打ち込む最初の1文字から、とにかくやさしく付き添います。
ラズパイダ

ラズパイダ

学べる楽しむ便利になる。小さいくせにヤケにパワフル。そんなRaspberry Pi をまだ知らない人に伝えたい。様々な場所で利用されているRaspberry Pi を知って「あっ、これもラズパイだっ!」だからラズパイダ!

関連記事

特集記事

コメント

この記事へのコメントはありません。

最近の記事 はじめて向け
  1. OMV5のアップデートエラー回避

  2. Raspberry Pi Pico マイコンボード、僅か4ドルで登場

  3. お掃除ルンバのアイロボットから教育用ロボット「Root」発表

  4. 【海外】プライステーション2の中にラズパイ4を組み込んで多目的マシン

  5. openSUSEがRaspberry Pi 4と400、Compute Module 4をサポート(まだバグあり)

  1. お掃除ルンバのアイロボットから教育用ロボット「Root」発表

  2. 【初心者向け】Raspberry Pi 4との接続方法(電源、HDMI)

  3. 【初心者向け】はじめてRaspberry Pi OS をダウンロードする人へ

おすすめの記事

  1. NextcloudとRaspberry Pi 3B+で作る自分専用クラウド

  2. TwisterOSで懐かしのWindows、最新macOSの見た目でラズパイを使う

  3. 非公式のLinuxディストリビューション〜Raspberry Pi で動く様々なOS一覧まとめ13種類!

  4. ラズパイ4にも対応している軽量でクールなOS「Manjaro」はアリ

  5. ラズパイ4で動いたOS一挙に10選とおすすめのデスクトップ代替OS

  6. これも動く、風変わりなOS〜Raspberry Pi で動く様々なOS一覧まとめ13種類!

今月の人気記事

  1. 1

    Raspberry Pi で動く様々なOS一覧まとめ13種類!

  2. 2

    ラズパイ4をUSB接続のSSDから起動する方法(USBブート)

  3. 3

    初心者でもラズパイでNASサーバーを作ってみよう!

  4. 4

    Raspberry Pi 4の初期設定2020年版

  5. 5

    Raspbian のWi-Fi設定(Raspberry Pi 初期設定)

  6. 6

    Raspberry Pi 4を起動したのにモニターに画面が映らない対処法

  7. 7

    ラズパイ4とOMV5(openmediavault5)で作る自宅NASサーバーの設定方法

  8. 8

    ラズパイ4はPCライクな性能になったけどPCではないよという話

  9. 9

    Raspberry Pi 4のOSをデスクトップPCとして使うためにUbuntuMATEをインストールしてみた

  10. 10

    ラズパイで使うmicroSDカードの選び方

記事ランキングページ

TOP