タイムレコーダごっこ--カードのかわりにEEPROMを使う
2003年9月13日 - 2003年9月14日
バーコードやカードを読み取れる機械を作ると、面白いおもちゃに発展させることができます。今回は、8ピンのEEPROMを押し当てると、そのデータを読み取って記録することで、タイムレコーダや宝探しゲーム、オリエンテーリングなどで遊べそうな機械を作ってみました。読み取ったデータは時刻情報とともにパソコンに転送できるので、本当のタイムレコーダとしても使えてしまえそうなしろものです。
1024ビットのEEPROMはカードの代わり
タイムレコーダーを作ろう!と思いました。でも、難しいのはカードの部分です。普通のタイムレコーダーは、キャッシュカードみたいなカードを使うのですが、この手のカードを読み書きする機械は、一般の人は買えません。というか、みだりに持っていると、それだけでカード偽造団の犯人と疑われてしまいそうなので、使うべきではないでしょう。
そこで、この作品では秋葉原で1個50円で売られている8ピンのEEPROMに、固有のIDを書き込んで、さながらカードのように使ってしまおうというアイデアで、作ってみることにしました。
作品の概要としては、PIC16F84AにEIA-574インターフェース(世間でRS-232と呼ばれているもの)と外付け1Mbitメモリー(EEPROM)を備え、1024ビットの8ピンEEPROMが「タッチ」されると、そのデータを読み取って、読み取ったIDと時刻を1Mbitメモリーに記録していくというものです。特定のIDを持つEEPROMをタッチすると、蓄積されたデータをパソコンに転送できます。
使い方
電源を入れるとまず、本体に内蔵されている1Mbitメモリーに最後に記録したアドレスを検索します。見つかると、通常の動作に移ります。ちなみに、この装置はメモリーがいっぱいになると、古いデータを上書きしながら記録を続けるように作られています。
基本的には、8ピンのEEPROM「93C46」を「タッチ」するだけで、全ての操作ができるように作られています。
- 8ピンのEEPROM「93C46」を正しい向きにセットする(タッチする)と、青色LEDが約1秒間点灯して、EEPROMに書き込まれているIDと時刻を、本体に記録します。青色LEDが点灯したら、すぐに93C46のチップは取り外します。(そうしないと、何回も読んでしまう可能性があります)
- IDが「7ffe」のメモリーでタッチすると、EIA-574のコネクタから以前に読み取った全ての情報が、パソコンに転送されます。パソコンの側では、「8ビット」「ハードウエアフロー制御あり」「ストップビット1ビット」「38400bps」のように設定しておけば、データを受信できます。
- IDが「7fff」のメモリーでタッチすると、以前読み取った情報を全て破棄します。「7ffe」でパソコンへの転送が成功したら、こちらの「7fff」を使って情報を消しておくとよいでしょう。
写真では、電源に電池を使っています。据え置きで使うのであれば、電圧安定化回路を内蔵したACアダプタがおすすめできます。
回路の仕組み
こちらが回路図です。今回は液晶ディスプレーがありませんし、ボタンもほとんどありませんが、EIA-574という難しいものが加わっておりまして、それなりのものになっています。
- EIA-574の回路は、使わない時は電源を切っています。使う時だけ電源を入れて、データを転送します。フロー制御に対応させるために、パソコン側からの入力も1ピンぶん確保しています。
- 1メガビットメモリー24C1024へは、クロックとデータの2ピンだけがつながっています。2-wire EEPROMというだけのことはあります。データピンに限っては、オープンドレインの論理になっていて、プルアップ抵抗を共有することで、双方向の通信を行っています。
- 1024ビットメモリ「93C46」を受け入れるソケットには、4本のI/Oをつないでいます。ここにはたえずアクセスをかけていて、メモリが到着するとアクセスが成立するので、読み取りが行われます。
- クロックには4MHzの発振子を使っています。けっこう速いので、パソコンにも38400bpsで送出ができるわけです。一方で、時間の単位が1.048576秒(有効数字はこんなにはありません)という中途半端な値になってしまっています。時計用の発振子ではないので、これはパソコンの側でデータを補正してもらうことにしました。
ソフトウエアの仕組み
- 全体としては、時刻を刻みつつ、8ピンの1024ビットメモリが来るたびに、その内容を記録して、必要に応じて送信するような内容になっています。
- EIA-574にデータを送る部分では、Sendbyteルーチンなどが活躍しています。
- 1メガビットメモリとのやりとりをする部分では、「E1024」で始まる名前のルーチンが使われています。
- 8ピンの1024ビットメモリからデータを読む部分には、「E3」で始まるルーチンが使われています。
こちらがソースコードです。3種類ある外部素子とのインターフェースがけっこうたいへんなので、それなりに長いものになっています。
データのフォーマット
1024ビットメモリへ書き込むIDのフォーマットと、パソコンへ転送するデータのフォーマットをメモしておきます。
1024ビットメモリのデータ形式
カードの代わりに使う1024ビットメモリ(8ピン)には、15ビットぶんのIDが書き込まれています。IDが1024ビットあってもよいのですが、とりあえず個人で使う用途としては、15ビットぶんあれば32768個まで対応できるので、いいかなあと思ってそうしています。
- このメモリには8ビットモードと16ビットモードがありますが、16ビットモードでアクセスするので、記録は16ビットモードで行います。
- 16進数で「53XX XX45」となるように記録します。XX XXにIDが入ります。「53XX」と書いた場合、いちばんMSB側の位になるのが「5」です。「53」はASCIIコードの"S"、「45」はASCIIコードの"E"で、「スタートコード」「ストップコード」と呼んでいます。
- IDの値は、「00 00」から「7f ff」までの32768通りがありえます。
- 「XX XX」の部分が次の値になるものは、特殊なIDとして意味を持ちます。
- 「7f fe」は「送信指令」で、そのメモリーをソケットに差すと、通常の記録動作に加えて、今まで記録した内容を全て、EIA-574インターフェースから出力します。
- 「7f ff」は、「送信成功」で、このIDが記録された以前の情報は今後送信の対象とはならなくなります。「送信指令」で送信に成功したら、同じデータを重複して送信したくないでしょうから、「送信成功」を当てて古いデータを無効化しておくとよいでしょう。
- ちなみに、1024ビットメモリーのうちで、使っているのは最初の2ワード(32ビット)だけです。けっこう単純なものでしょう。
パソコンに送信するデータの形式
パソコンのシリアル端子を通じて、情報をパソコンに取り込むことができます。送られる情報のフォーマットを書き留めておきました。
通信形式
- 38400bps
- パリティービットなし
- スタートビット1ビット
- ストップビット1ビット
- ハードウェアフロー制御あり(装置→パソコン方向のみ)
データの内容
データの内容は全てテキストデータです。UNIXの改行コード(0x0a)で区切られています。
以下に実例を示しますので、これを見ながら説明を読んでみましょう
送られるデータの内容は、次のようになっています。
- まずは、2つの空行(改行のみ)から始ります。
- 「HELO」の行があります。通信を開始する意味です。
- 「V=0002」の行があります。ファームウエアのバージョンです。
- 「A=XXXX」の行があります。「XXXX」には、4桁の16進数が入ります。これは、1Mbitメモリでの、転送を開始するアドレス値(16ビットごとに1進むものとして)に1を加えたものです。(ffffに1を加えると、0000になります)
- 「D」の行があります。この次の行から、記録されているデータ本体となります。
- 「XXXX」の行が続きます。「XXXX」は、4桁の16進数で、記録されたデータ本体を意味します。新しい情報ほど先に送出されます。だんだん古い情報へ向かっていくため、1Mbitメモリのアドレスは、少しずつ小さくなる方向にアクセスされていきます。
- MSBが0になっているものは、差し込まれた8ピンEEPROMが持っていたIDです。
- 最初に送られるのは、必ず「送信指令」(7ffe)となっているはずです。「送信指令」などの機能を持ったメモリーにもIDがあり、送信を開始する直前にIDが記録されています。
- 最後に送られるものは、「送信成功」のID(7fff)か、またはデータ終了符合の「ffff」となっているはずです。
- MSBが1になっているものは、差し込まれた8ピンEEPROMのID以外の情報です。
- 「fffe」は、マイコンがリセットされるなどして、起動した時点で記録されるIDです。
- 「ffff」は、マイコンが記録を行っている最新のデータの1つ先のアドレスに記録される値で、最新のデータと最も古いデータとを区別するためのセパレータとしての意味を持っています。この「ffff」かまたは「7fff」(送信成功)を送信すると、送信は終わります。
- 「feXX」は、時間の経過を意味します。「XX」の部分は、単位時間(1.048576秒)を単位とした、時間の経過を意味します。時間の流れがデータが送られる順序とは反対になっていることに気をつけましょう。例えば
0002
fe0a
0001
となっていれば、「0001」のメモリが差し込まれて、次におよそ10.5秒経過して、それから「0002」のメモリが差し込まれたと分かります。
- データが終わると、「P=XXXX」の行になります。「XXXX」は、最後に送信したデータが入っていた1Mbitメモリのアドレス(16ビットごとに1進む形式)です。
- その次に「END」の行があり、送信を終了します。「END」の行も、最後に改行していますので、その改行コードが最後に送られるデータになります。
データ形式を決める途中で書いた詳しい企画書がありますので、よろしければご覧になってください。
パソコン側のプログラムの例
パソコンの側で、この装置からの情報を受け取るためのプログラムを作ってみました。かつてのパソコン通信用ソフトでも使えるとは思いますが、Linuxで楽しみたい場合は、こちらが参考になるかもしれません。
なお、このプログラムは「The Linux Serial Programming HOWTO」(Peter H. Baumannさん作、 藤原輝嘉さん訳)にあるサンプルプログラムを改造したものです。再配布・改造などはお好きにどうぞ。ただし、内容に責任は持てません。
デバイスファイルを指定する部分("/dev/cua0"など)の部分で、COMポートを指定していますので、うまくいかない場合は"/dev/cua1"に変えてみたりするとよいかもしれません。
やってみましょう
- 一般に、電子工作は危険を伴う遊びです。けがや、やけどをしないように、また、作った品物が火事の原因にならないように、安全には十分気を付けましょう。なお、この記事には間違いがある可能性もありますが、お読みになることにより生じた不都合や事故などに対しては、筆者は責任を負いかねます。ご自身の責任において、お楽しみください。
- 外付けの大容量メモリーと、EIA-574インターフェースを用いた通信とを組み合わせて、何か面白いアイデアの作品を作ってみてはいかがですか?
- パソコンに送出されるデータのフォーマットを調べてみましょう。自分でフォーマットを考えるというのも、それなりに楽しい遊びだったりしますよね。
としおの部屋 ->
PICマイコンを楽しむ電子工作 ->
タイムレコーダごっこ--カードのかわりにEEPROMを使う
製作・著作:杉原俊雄(すぎはら としお)
(c)2003 Sugihara Toshio. All rights reserved.