Tech:pic:gc:timer

出典: Tariki

目次

geocaching用問題発生器(1) 一定時間LEDを光らせる

これはマルチキャッシュのイニシャルに設置し、LEDが光る時間を計測しファイナルの座標を求めてもらおう、という趣旨のキャッシュのための装置である。『取るのに特殊な道具が必要なキャッシュ』シリーズとして3つ目に置こうと構想していた。ちなみにこのシリーズのNo. 1は、イニシャルにある石の重さを量ってファイナルの座標を求めてもらう、というキャッシュなので、取るのに秤が必要であるが、イニシャルのモノは特にハイテク(?)でもなくてよかった。

ちなみにこのシリーズNo. 2は、同じ神奈川のジオキャッシャーであるYukiさんに置かれてしまった(笑)。私も考えていた、いにcシャルにあるモノの長さを測ってファイナルの座標を計算、という趣旨である。

当初考えていたシリーズNo. 2は (この上のページに書いたように) また別の装置を使ってキャッシュの座標を得るためのモノの企画だったのであるが、まだ出来ていないので割愛する。したがって、このキャッシュは予定どおり (?) シリーズNo. 3の設置となった。

さて要求仕様は以下のようなものである。

  • スイッチ2つ、または1つの倒す向きによって、2つの異なる時間だけ (色も変えたい) LEDが光る
  • イニシャルは手にとって操作できる装置である。したがって
    • 電源スイッチがあり電池で働くものでよい →小型にしたいのでリチウムイオン電池 (CR2032)を使った

簡単である。あまりに簡単だから、手元にあって使いやすい8ピンのPIC12F675を使った。

両側に倒れるDIP SWの2回路のものを使い、1回路は電源、もう1回路はPICの入力ピン (GP0) に接続し向きを検出すれば良い。出力は電流制限用の抵抗を介して、LED (RG二色) のそれぞれ (GP1/GP2) に接続する (あまりに簡単なので回路図略)。

作ってみた

回路そのものは簡単であるが、フィルムケース (フジの135フィルムのケース) に収めることにしたので、2回路3接点の両オンのDIP SWを使って、フィルムケースの蓋に基板ごと固定する。フィルムケースは防水性があるが、DIP SWを外に出してしまう(穴をあける)ので防水性は失われる。これ自体をジップロック袋に入れてマグネットでイニシャルに固定するつもりであったが、まあ家に大量に余っているし、穴をあけてもなおそこそこの防水性があるだろう。したがって、ボディ側にはマグネットを数個、PP/PE OKの接着剤で固定する (実はこれが曲者であった。回路そのものは磁石の近くでも問題ないが、リチウム電池が磁石にくっついてしまうので、蓋を開けるときには必ず電池が外れてしまう(笑))。

LEDは底面~側面下を照射するようにした。光量は少ないが、どっちみちPICのピン直接だから20mAくらいしか取れない。直射日光下でジオキャッシングする場合は、日陰に入ってもらおう。これを作っているときは気づかなかったが、そのほかリチウム電池から取れる電流の問題もあることに後日、気づいた。

プログラム

プログラムは簡単である。起動直後にスイッチの向きを読み取り、それに応じたLEDを一定時間光らせて終わりである。

ここでちょっと問題がある。まず、簡単なスイッチONで起動という回路だと、パワーオンリセットを有効にする必要がある (PICのconfigビットで、プログラム時に _PWRTE_ON を立てる)。

それからスイッチのチャタリングも問題だ。パワー側の接点は複数回ON-OFFしたところで、最後のONが有効になるだけだろうが、起動直後のポートを読んだ瞬間にスイッチを倒す側の信号回路が入っていないと、誤った側と読み取ってしまうおそれがある。当然これを回避するには、起動後ちょっと (10msくらい) 遅延してからポートを読めばよいが、モノが「光る時間を測れ」という回路なので、1/100秒の遅延は問題を出す側のプライドに関わる(笑)。また、遅延後読み取るまでLEDを光らせないのであれば、計測に不便を生じると思われる (たいていのひとはスイッチをオンにすると同時にストップウォッチをスタートするだろう)。

実際この程度の誤差は問題はないだろうが、以下のように解決することにした。

  1. パワーオンリセット(これはμ秒オーダなので問題ない)後
  2. まず両方のLEDを光らせる(笑)
  3. 数ms程度遅延して
  4. ポートを読み取る
  5. 倒れている側のLEDを残し、もう一方を消す

人間の目には、起動直後から正しい側のLEDが光っているように見えるはずだ(笑)。

最後の処理をどうするか。実はこの回路、電源ON-OFFが伴っている。ユーザからみると単なるスタートキーにみえるだろうが、OFF (両側トグルの中立) に戻してもらわないと、PICが電源を食い尽くしてしまう。

いちおう安全を期して、プログラムの最後はSLEEPにしてみた。これなら数μAのオーダまで消費電流が落ちるので、スイッチを戻し忘れた訪問者がいたとしても、単純計算で10-20日は電池が上がらないだろう (といっても10-20日に一回メンテするわけでもないので、効果の程は怪しいが)。

ところがこのおかげで思わぬ副作用が出た。プログラムを最後まで実行してSLEEPすると、0.01μの (ええ、わずか0.01μですとも) パスコンに溜まった電荷で、電源OFF後もPICが数十秒動作 (っていってもSLEEP) し続けてしまうのだ(笑)。したがってその間に再度電源を入れても、リセットされないことになる。これを回避するには ブラウンアウトリセット有効 = _BODEN_ON にすればよさそうなものであるが、あいにくブラウンアウトリセットは3.何ボルトを切ると動作してしまうので、そもそもリチウム電池の3Vでは無効にしなければシステムが動かない。

ということで、注意書きに『一回使ったら20秒くらい待ってください』と書き加えることにした(笑)。

時間の校正

回路を簡単にするため、PICは内蔵CRによる4MHz発振 (_INTRC_OSC_NOCLKOUT)を使った。基本的にCR発振なので、PICの個体差がある。なおPIC個体ごとのCR発振の校正値は出荷時に計測、EEPROMのある番地(3FFh)に書きこまれているので、これをレジスタOSCCALに書きこむと4MHzになるらしいのだが、気温や電圧条件で異なるだろう。実際測ってみたら、4.0082MHzくらい (+0.02%) だったから、数秒~数十秒の計測ならこれでも有意差にはならない。しかしほかに、ループの定数という問題もある。

上では書かなかったが、プログラムではまず、0.001秒遅延のサブルーチンを書いて、それを複数回呼び出すことで任意の時間をプログラムできるようにした (ちなみにgeocachingの公式ページでの座標表記法『度・分 (下3桁まで)』に従うと、いちばん細かい桁は0.06秒となる)。このための遅延ループは、クロック4MHz = 1Mインストラクションサイクルだと1000命令実行時間程度 (ループ250回程度) なので、あまり微調整は効かない。

こういったもろもろの誤差を校正する方法として、上記のルーチンを使ってLEDを点滅させるテストプログラムを書き、LED出力をデジタルオシロの簡易周波数測定機能で計測する。このときの実測結果と、PICIDEのシミュレーションでの経過時間を比べると、CR発振の誤差が分かる。いったん実際のクロック周波数が分かったところで、これをシミュレータにセットし、LED ON時間の定数をセットしてやれば、シミュレータ上で実に正確な『○分○.○○○』秒が得られる。

温度関係の誤差は、データシートから調べた。まあイニシャルのPIC装置が置かれる場所は、冬の極寒の日でも0度C、夏に炎天下で測定しても40度Cくらいだろう。このくらいなら、計測結果は1%程度の誤差となる見通しなので、ファイナルの座標に換算すれば数m、GBなら十分探せる範囲だ。

ということで、装置は完成し、設置した。

訪れてもらって

『道具が必要』シリーズNo. 2のオーナーのYukiさんがFTFであったが、彼はiPhoneのストップウォッチで20回近く計測を繰り返して値を得たそうだ。余談になるが、PDAで計測したらどうなるかということでAndroidでは試していた(タッチパネルの誤差は、気持よくカチッと言わないことを除けばそれほど問題ないようだ)が、iPhoneは持っていないので知らない。たまたま設置の日にファイナル近くで出会ったkerokkoさんにiPhoneを借りてクロノグラフと比べてみたが、そのときiPhone標準のストップウォッチは1/10秒までしか測れないことを知った。まあそれでも座標にして10m程度の誤差で済むのだが、Yukiさんはわざわざ他のアプリケーションを用意して望んでくれたようだ。

STFのfunazoさんにいたってはひどい(笑)。1/100秒まで測れる装置を持っていながら、1/10秒以下の桁を丸めて秒単位で計測して、それでファイナルをみつけてしまった。さすがにこれは最悪30m程度の範囲を捜索しないといけないので、おすすめはできないのだが(笑)。