FrontPage 2009/01/09からのアクセス回数 13946 はじめに †評価キットも高価で簡単に手の出せなかったICタグですが、基板タイプのリーダー/ライターが安価に入手できましたので、例題を説明しながらご紹介します。 ここでは、以下の手順で説明します。
ICタグを使った例題のゴールは、
としました。 本当はICタグのテストプログラム †今回ご紹介するICタグを使った例題は、元々はSun SpotにICタグ・リーダー/ライターを接続するためのテストプログラムです。 そのため、ICタグ・リーダー/ライターの選定では、Sun Spotとの接続を考慮して以下の制限を付けました。
ICタグ・リーダー/ライターを探す †ICタグ・リーダー/ライターは、以下の条件でGoogle検索しました。
この結果、大信機器のHF-04SR( http://www.daishin-kiki.com/products.html ) *1 にしました(サンプルのICタグが付いてきました)、価格も1万円程度です。電圧は5Vと3.3Vがありますので、購入の際には接続するシステムに合わせてください。 次に、使用するICタグですが、本やシートに貼ることを考慮して
なものを探しました。 販売量の多いメーカの方が、安く購入できると見込んで「ICタグ」でGoogleに広告を出している 「リンテック」に問い合わせてみました(サンプルのICタグを送っていただきました)。 その結果、TS-Lシリーズ( http://www.lintec.co.jp/e-dept/britem/ictag/products/tsdc_ts.html ) *2 は100枚から注文を受け付けるとの回答を頂き、サンプルのICタグをHF-04SRで動作確認後、TS-L102JCを100枚購入しました。 ICタグ・リーダー/ライターの動作確認 †プログラムに接続する前に、ターミナルからシリアル接続し、 ICタグ・リーダー/ライターの動作を確認します。 秋月のUSB-シリアル変換モジュール †TTLレベルのRS-232C通信をテストする場合、レベルコンバータとUSB-シリアル変換モジュールが 必要ですが、秋月のAE-UM232R( http://akizukidenshi.com/catalog/items2.php?q=AE-UM232 )は、USBから電源(5V, 3.3V)を供給し、買ってすぐにブレッドボード上で 接続できるすぐれものです(これで950円は安い)。 写真1は、ブレッドボードにAE-UM232RとHF-04SRを接続したところです。 AE-UM232RとHF-04SRの結線は、 図1*3 のようにしてください。HF-04SRからでている4本のケーブルにコネクタを付けて接続しています。 AE-UM232Rのジャンパーは、以下のように設定してください。
デバイスドライバーのインストール †AE-UM232Rに組み込まれているUSB・シリアル変換チップはFT232RLで、 Future Technology Devices International Ltd.(http://www.ftdichip.com/Drivers/VCP.htm) のサイトからドライバーをダウンロードします。
からインストールしてください。 ドライバーの確認 †次にドライバーが正常に動作しているか確認します。 AE-UM232RのUSBケーブルをパソコンに接続します。 MacOSXの場合 †アプリケーション/ユーティリティのターミナルを起動し、以下のコマンドを入力します(プロンプト$を除く)。 $ ls /dev/cu.usb* /dev/cu.usbserial-A5002yHm のように/dev/cu.usbserial-xxxxxx と表示されることを確認し、この名前をメモしてください。 Windowsの場合 †
図2のように、ポート(COMとLPT)にUSB Serial Port(COMx)が追加されたことを確認し、COMxの名前をメモしてください。 接続確認 †MacOSXの場合 †MacOSXでは、デフォルトの通信ソフトで手頃なものがないので、 「Macにシリアル(RS-232C)ポート」のサイト( http://www.zone0.ne.jp/2006/osxserial01.html ) から、Jerminal8095.dmgをダウンロードしました。 ターミナルからJerminal(jermコマンド)を以下のオプションで起動します。最後の/dev/cu.usbserial-A5002yHmは、先ほどメモした名前に変更してください。 $ jerm -b 38400 -p none -d 8 -s 1 /dev/cu.usbserial-A5002yHm
接続が完了すると以下のように表示されます。 Jerminal v0.8095 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 candy Type "Ctrl-M ~ ." to exit. ispeed 38400 ospeed 38400 +IGNBRK -BRKINT -IGNPAR -PARMRK -INPCK -ISTRIP -INLCR -IGNCR -ICRNL -IXON -IXOFF -IXANY -IMAXBEL -OPOST -ONLCR -OXTABS -ONOEOT cs8 -CSTOPB +CREAD -PARENB -PARODD +HUPCL +CLOCAL -CCTS_OFLOW -CRTSCTS -CRTS_IFLOW -MDMBUF -ECHOKE -ECHOE -ECHO -ECHONL -ECHOPRT -ECHOCTL -ISIG -ICANON -ALTWERASE -IEXTEN -EXTPROC -TOSTOP -FLUSHO -NOKERNINFO -PENDIN -NOFLSH ICタグ・リーダー/ライターとの接続を確認するために、バージョン表示コマンド V Ctrl-M を入力します(端末のようにエコーバックはしないので、VとCtrl-Mは表示されません)。 15693 V03.07 これで、ICタグ・リーダー/ライターとの接続が確認できました。使用したICタグ・リーダー/ライターのバージョンは、V03.07で、対応しているタグはISO15693です。 Windowsの場合 †プログラム→アクセサリ→通信からハイパーターミナルを起動します。 接続ポートは、先ほどメモしたCOMxを選択してください。 ポートの設定は、図3のようにします。 ハイパーターミナルの画面からV Ctrl-Mを入力すると図4のようにバージョンが表示されます。 JavaからICタグ・リーダー/ライターを制御する †すべての準備が整ったところで、JavaからICタグ・リーダー/ライターを制御することにします。 Javaでシリアル通信をする †Javaからシリアルポート、パラレルポートを使用するためのAPIがSunの提供する Java Communications API です。 残念ながらSunの提供するAPIは、SPARC Solaris/x86 Solaris/x86 Linux版のみなのでMacOSXや Windowsでは使えません。 そこで、Java Communications APIに準拠したオープンソースのライブラリRXTXを使用します。*4
RXTXのサイトからrxtx-2.1-7-bins-r2.zipをダウンロードし、解凍します。
を取り出し使用しました。 使用するICタグ制御コマンド †javaで使用するICタグコマンドは
としました。詳しくは、HF-04SRに付属の「コマンド編MF4_V03_07.pdf」を参照してください。 各コマンドの書式では
ICタグ制御クラスHF04SL †ICタグ制御クラスHF04SLに各コマンドの処理を実装します。 ICタグオープンメソッド †最初にICタグのオープンですが、バージョン情報を使って接続先がICタグかどうかをチェックします。今回はISO-15693のICタグを対象としているので、バージョン情報の15693の文字列をキーワードとしました。 public boolean openICTag(String pname){ if(openSerialPort(pname)){ String returnCode=""; for (int i = 0; i < RETRY_COUNT && (returnCode.indexOf("15693") < 0); i++){ try{ write("V\r"); returnCode = readWithTimer(3000); } catch (TimeoutException e1) {} catch (Exception e2){ e2.printStackTrace(); break; } } return true; } return false; } 連続スキャンメソッド †ICタグの読み込みを逐次チェックするよりも連続スキャンを使ってICタグの検出を待つようにした方が、 処理が簡単になります。 連続スキャンの処理は以下のようになります。 public String contScanICTag() throws IOException { write("2XS\r"); String res = read(3); if (res.equals("01,")) { String id = read(16); read(1); // skip [CR] return (id); } else { read(2); // skip remain None[CR] return (null); } } 複数ブロック書込メソッド †書込もコマンドの仕様通りです。 public boolean writeICTag(int tagNo, int blokNo, byte[] data) throws IOException { int numBlock = (data.length + 3) / 4; StringBuffer buf = new StringBuffer(); buf.append("2WM,"); buf.append(String.format("%02x,", tagNo)); buf.append(String.format("%02x,", blokNo)); buf.append(String.format("%02x,", numBlock)); for (int i = 0; i < data.length; i++) buf.append(String.format("%02x", data[i])); buf.append("\r"); write(buf.toString()); read(3); // skip tt, String result = read(2); read(1); // skip [CR] return (result.equals("OK")); } 読出メソッド †読出は、ちょっと長くなりましたが、ほとんど仕様どおりです。ICタグの読み出しに失敗した場合には、空のリストを返します。 public String[] readICTag(int tagNo) throws IOException { StringBuffer buf = new StringBuffer(); buf.append("2R,"); buf.append(String.format("%02d,00,0F\r", tagNo)); write(buf.toString()); String numStr = read(2); if (numStr.equals("00")) { return (new String[0]); } else { List<String> list = new ArrayList<String>(); int numTag = Integer.parseInt(numStr); String str; int count = 1; for (int i = 0; i < numTag; i++) { if (count++ != 1) { numStr = read(2); } str = read(1); // skip ',' String lenStr = read(2); str = read(1); // skip ',' or [CR] int len = Integer.parseInt(lenStr, 16); if (len > 0) { String data = read(len*2); str = read(1); // skip ',' or [CR] list.add(data); } } return (list.toArray(new String[0])); } } テストプログラム †必要な部品がそろったので、テストプログラムで動作を確認します。 public static void main(String[] args) { HF04SL ictag = new HF04SL(); try { ictag.openICTag("/dev/cu.usbserial-A5002yHm"); System.out.println(ictag.contScanICTag()); System.out.println(ictag.writeICTag(1, 1, "0123456789ABCDEF".getBytes())); String[] tagData = ictag.readICTag(1); System.out.println(tagData[0]); System.out.println(ictag.hexToString(tagData[0], 4, 16)); } catch (Exception e) { e.printStackTrace(); } finally { ictag.closeICTag(); } } 実行結果は、 Stable Library ========================================= Native lib Version = RXTX-2.1-7 Java lib Version = RXTX-2.1-7 1A8FA410000104E0 true 000000003031323334353637383941424344454630303030000000000000 000000000000740069006F006E0020002000000000000000000000000000 0123456789ABCDEF Experimental: JNI_OnLoad called. のように出力されます。
と期待通りの結果を表示しています。 サンプルプログラム †ICタグのサンプルプログラムとして「書籍管理システム」を作りました。 書籍管理システムでは、
の処理をします。 書籍登録の処理の流れ †ICタグは、本の表紙裏左上(背表紙の上部に近く)にセットします(写真2)。 *5 ICタグをリーダー/ライターにかざし、バーコードリーダでISBNをスキャンします(写真3)。 BookダイアログでISBN 検索ボタンを押すと、Amazon Web Serviceから書籍情報を取得し、 ダイアログに表示します。4文字の棚番号を入力し、OKボタンを押すと棚番号がICタグに書き込まれます(図5)。 サンプルプログラムの構成 †サンプルプログラムは、図6のような構成となっています。
画面説明 †簡単に各画面の使い方を説明します。 書籍画面 †プログラム起動時に、書籍画面が表示されます(図7)。書籍画面には、メニューと書籍の登録された書籍の一覧が表示されます。書籍一覧で書籍を選択し、ダブルクリックするとBookダイアログが表示され、書籍情報の修正が可能です。 メニューバーには、「ファイル」メニュー1つで、以下の項目があります。
Bookダイアログ †Bookダイアログには、ICタグID, ISBN番号、書籍情報、棚番号が表示されます(図5)。 書籍登録の場合、
棚番号表示ダイアログ †メニューから「棚番号表示」を選択し、ICタグ・リーダー/ライターに書籍を近づけると、ICタグから棚番号を読み取り、表示します(図8)。 開発環境 †サンプルプログラムは、Eclipseのプロジェクトになっており、コンパイルには、以下のツールが必要です。
http://java.sun.com/javase/downloads/index.jsp からJava SE Development Kit (JDK)6 Update 11 の Downloadボタンを押して、プラットフォームにあった JDKをダウンロードして、インストールしてください。
http://www.eclipse.org/ から、Download Eclipseをクリックして、 Eclipse IDE for Java DevelopersのWindowsを選択してダウンロードして解凍すれば利用可能になります。 GUIの構築 †GUIは、Eclipseのプラグインの一つであるVisula Editorを使って作成しました。 画面でボタンやフィールドをマウスで配置しますので、初心者でも画面の編集ができるようになります(図9)。 ISBN検索ボタンの処理 †ISBN番号から書籍の情報を取得するのは、アマゾンのAWS APIを利用しました。*7 AWSへのアクセス*8 と書籍情報XMLの解析は、JXPath *9 を使いました。
こんなに簡単にAWS APIを使って書籍情報を取得できることに驚かれる方も多いのはないでしょうか。 private void searchISBN() { String requestUrl = "http://webservices.amazon.co.jp/onca/xml?Service=AWSECommerceService&SubscriptionId=" + DataBaseHelper.getAwsAccessKeyID() + "&Operation=ItemSearch&ResponseGroup=Medium&SearchIndex=Blended&Keywords=" + getIcbnField().getText(); try { DocumentContainer container = new DocumentContainer(new URL( requestUrl)); container.setNamespaceAware(true); JXPathContext context = JXPathContext.newContext(container); context.registerNamespace("aws", "http://webservices.amazon.com/AWSECommerceService/2005-10-05"); String title = context.getValue("//aws:Title").toString(); String author = context.getValue("//aws:Author").toString(); int numOfAuthor = (int)Double.parseDouble(context.getValue("count(//aws:Author)").toString()); for (int i = 1; i < numOfAuthor; i++) { String nextAuthor = "//aws:Author[" + (i+1) + "]"; author = author + "; " + context.getValue(nextAuthor).toString(); } String publisher = context.getValue("//aws:Manufacturer").toString(); String publicationDate = context.getValue("//aws:PublicationDate").toString(); String noPages = context.getValue("//aws:NumberOfPages").toString(); String listPrice = context.getValue("//aws:Amount").toString(); titleArea.setText(title); authorArea.setText(author); publisherField.setText(publisher); publicationDateField.setText(publicationDate); noPagesField.setText(noPages); listPriceField.setText(listPrice); } catch (Exception e) { e.printStackTrace(); } } プログラムの実行 †AWS(Amazon Web Service)アカウントの作成 †ISBNから書籍の情報を取得するのに、AWSのAPIを使っていますので、AWSのAccess Key IDが必要となります。
http://www.amazon.com/gp/aws/registration/registration-form.html にアクセスして、必要な項目を入力し、登録ボタンを押すと完了です。
AWSのアカウントの登録が完了すると、Welcome to Amazon Web Services というタイトルのメールが届きます。 メールに記載されている、以下のサイトにアクセスします。 http://aws-portal.amazon.com/gp/aws/developer/account/index.html?action=access-key Sign In画面で登録したメールアドレスとパスワードを入力すると、割り当てられたAccess Key IDが表示 されます。 プログラムのダウンロード †ソースおよびプログラム一式は、ZIPファイルとしてictag.zipに圧縮してあります。 ictag.zip ictag.zipを解凍すると、ictagディレクトリに ictag/ +src/ +lib/ +data/ +ictag-1.0.jar +db.properties +librxtxSerial.jnilib +librxtxSerial.so +rxtxSerial.dll があります。
db.propertiesの設定 †db.propertiesの設定情報について説明します。 JDBCドライバー情報 †初期設定では、JDBCドライバー情報としてHSQLDBを使用する設定になっています。 ictag-1.0.jarのライブラリのパスに登録してあるデータベースドライバーは、
です。上記以外のドライバーを使用する場合には、ドライバーのjarファイルをクラスパスにセットしてください。 db.url=jdbc:hsqldb:data/book db.driver=org.hsqldb.jdbcDriver db.username=sa db.password=
SQL文の設定 †データベースによってSQL文に若干違いがあるため、使用するSQLを設定できるようにしました。 初期設定はHSQLDBを使ってCSVファイルをテーブルと扱うようになっています。 db.createTable=CREATE TEXT TABLE Book (ID IDENTITY, ICTAG VARCHAR, ISBN VARCHAR, TITLE VARCHAR, AUTHOR VARCHAR, PUBLISHER VARCHAR, PUBLICATIONDATE VARCHAR, NOPAGES VARCHAR, LISTPRICE VARCHAR, SHELFID VARCHAR); SET TABLE Book SOURCE "book.csv;encoding=Shift_JIS"; db.insertSQL=INSERT INTO Book (id, icTag, isbn, title, author, publisher, publicationDate, noPages, listPrice, shelfId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?); db.updateSQL=UPDATE Book SET id=?, icTag=?, isbn=?, title=?, author=?, publisher=?, publicationDate=?, noPages=?, listPrice=?, shelfId=? WHERE id=?; db.selectAllSQL=SELECT * FROM Book; db.selectWhereSQL=SELECT * FROM Book WHERE title like ? OR author like ?;
AWS Access Key ID †先にAmazonから取得したAWS Access Key IDは、 aws.access.keyID=ここに取得したAccessKeyIDをセットしてください に設定します。 ICタグ・リーダー/ライター使用の有無 †ICタグ・リーダー/ライター使用の有無を指定します。 初期設定は、ICタグ・リーダー/ライターを使用する設定になっています。 ICタグ・リーダー/ライターを使用しないで、書籍の管理をする場合には、 use.ictag=false に変更してください。 プログラムの起動 †プログラムの起動は、ターミナルまたはコンソールから $ java -jar ictag-1.0.jar シリアルデバイス名 を入力します。 例)MacOSXでの起動例 $ java -jar ictag-1.0.jar /dev/cu.usbserial-A5002yHm Experimental: JNI_OnLoad called. Stable Library ========================================= Native lib Version = RXTX-2.1-7 Java lib Version = RXTX-2.1-7 書籍データベース †登録した書籍情報は、データベースに登録されます。 初期設定では、HSQLDBを使ってdata/Book.csvファイルに書籍情報が保存されるようになっています。 文字コードをShift_JISに設定してありますので、そのままExcelで開いて編集できます。 本格的なデータベースを使う例として、MySQLを使う場合の設定を以下に示します。 MySQLで日本語を扱う場合、データベース作成後に ALTER DATABASE データベース名 CHARACTER SET SJIS; のように使用する文字コードをSJISに変更します。 次にdb.propertiesの設定では、db.urlで文字コード指定が必要となります。 db.url=jdbc:mysql://localhost/ictag?useUnicode=true&characterEncoding=SJIS db.driver=com.mysql.jdbc.Driver db.username=ictag db.password=ictag テーブルの作成は、以下のように変更します。 db.createTable=CREATE TABLE Book (ID LONG, ICTAG VARCHAR(16), ISBN VARCHAR(13), TITLE VARCHAR(255), AUTHOR VARCHAR(255), PUBLISHER VARCHAR(64), PUBLICATIONDATE VARCHAR(10), NOPAGES VARCHAR(5), LISTPRICE VARCHAR(5), SHELFID VARCHAR(4)); あとがき †ICタグを使ったサンプルプログラムでは、
を紹介しました。 大信機器株式会社の野村秀夫さん、リンテック株式会社の佐藤誠子さんには、ICタグおよびリーダー/ライターの購入に際し、お世話になりました。感謝申し上げます。永山純一さん、橋本あづささん、戸張一夫さんには原稿に対し貴重なコメントを頂きました。感謝申し上げます。 Tweet |