« 2011年7月17日 - 2011年7月23日 | トップページ | 2011年7月31日 - 2011年8月6日 »

2011年7月24日 - 2011年7月30日の1件の記事

2011年7月26日 (火)

ログ機能を持ったSparkFunガイガーカウンターのソース公開

内蔵EEPROMでも実用的な量のデータ保存ができる(7/18/2011)
 SparkFunのガイガーカウンターキットは、データを残すのに内蔵EEPROMでは小さすぎて現実的でないと思っていたがフラッシュROMを外付けしなくても、結構実用レベルまでログを溜められることがわかった。

 勘違いをしていた。最初はGM管のパルス間隔時間を記録することしか考えていなかったので、Mega328の1KバイトのEEPROMでは、僅かの時間(30分くらい)しか記録できないと思っていたが、パルス幅でなく1分ごとのパルス数(CPMそのもの)を記録することにすれば、1バイトづつ(256CPMまで)だと、17時間分も蓄積できる。

 1バイトを越える256CPM以上というと、18μsV/h以上ということだ。この数字は年間では157mSvというとんでもない値で、とてもこんな悠長なことはしておれない事態だが、測定器でこれ以上が測れないというのはもっと不安である。どんな大きい数字でも記録できないといけない。

 ということでデータサイズは2バイトにする。これでも512分(正確にはポインターが必要なので508分)、8時間以上残せる。その都度、平均も出すようにすれば、同じ場所に30分ほど置くだけで、その場所の環境数値らしいものがとれる。

 早速、プログラムの改修にかかった。EEPROMの操作は、4年近く前、初めてAVRを使って温度ロガーを開発したときに、EEPをストリームのように使えるライブラリを作ってあるので開発は楽だが、貯めたデータの表示や、消去したりする操作が自由にできるようにしなければならない。

 タクトスイッチかUARTで、こうしたユーザーインターフェースを実現していくわけだが、タクトスイッチはハードがからむのですぐには無理である。ということで、UARTの受信機能を作り始めた。USBを差せば仮想UARTコンソールが動く。当面はUARTのキーボードから指示を出すので十分だ。LCDと違って沢山のデータも出力できるし、画面をCOPY&PASTEすれば、PCですぐグラフ化も出来る。

UART受信が動かない。ロジアナの極小プローブを使う(7/19/2011)
 幸いオリジナルのソースにはUART受信関数がついており(使っていないが)、これを使ってコマンド入力機能を作る。ところがこれがうまく動かない。データシートを何度も見直し初期化のソースコードなどを調べるが、ガンとして動かない。割り込みもバッファーも何も使わない単純なUART受信関数である。コードの上ではもう調べるところがなくなった。

 通信機能というやつは、ALL OR NOTHINGで動かないとなると難儀である。どうもこれはハードを疑うしかない。USBシリアルアダプターのFT232RLから入るMega328の受信ピン(PD0)の信号をロジアナ(Zero Plus)で見ることにした。

S_p7234036 このロジアナは標準プローブでも0.8ミリピッチを挟めるそうだが、ここは販売元のお店(ストロベリーリナックス)が、少し高い製品以上に(LAP-C16128)におまけにつけている、0.5ミリピッチでも挟めるという極小プローブを使う良い機会だ。

 これだけでも買えば一万円以上するという触れ込みのプローブである。ケースから、プローブをとりだす。買った当座、ケーブルをつけておいたが、あらためて見てみるとこれは本当に小さい。ピンに挟み込むには拡大鏡なしでは無理である。ヘッドルーペをつけて送受信ピンに取り付ける。

 測定の結果は予想通りだった。受信ピンにPCからのデータが来ていない。これまでのピンの引き出し工作で不具合が起きたのだろうか。いや、ハンダ付けしたところはUARTピンから遠く離れている。この基板はFT232RLでUSBとつないでいる。ここがおかしくなったのだろうか。いや問題ない。

S_p7234034 あれこれ悩んでいたが、動かない原因は意外なところだった。PCのUARTコンソールのフロー制御だったのである。これを「なし」にすると全く問題なく動いた。えー、送信はフロー制御(ハードウエア)を設定していてもちゃんと動いている。それなのにどうして受信だけが駄目になるの?FT232RLの初期設定の関係だろうが、人騒がせな設定である。

EEPROMに多バイトデータを1バイトづつ記録するのは難しい(7/21/2011)
 とにかく、動けば問題ない。EEPROMのソースコードは、これまでのライブラリを少し手直しして使う。EEPROMサイズを512バイトから1024に広げるだけである。書き込みのタイミングは、1秒毎の処理イベントルーチンでカウンターを回し、1分単位にEEPROMにパルス回数を書き込む。難しい話でも何でもない。コードとしてはすぐに完成したが、正しいデータがEEPROMに入っていかないのである。0データしか入らないのには弱った。

 今度のデータサイズは1バイトではなく、2バイトバイナリーである。多バイトのデータ蓄積は結構厄介で、EEPROMはリングバッファー的に使うので、アライメントを合わせてやらないと折り返しでおかしくなる。そんなことより4バイトのバイナリーデータから、2バイト単位にデータを入れていく過程で既に正しいデータになっていない。

 ちょうど良い機会なのでC言語のキャストをあらためて勉強する。その結果、キャストについては基本的な間違いをしていたことがわかった。キャストをアセンブラーのアドレスポインター的に考え、4バイトデータを1バイトキャストするというのは、頭の1バイトが入るものだとばかり思っていたが、そうではなかったのである。

 しかも、リトルエンディアンか、ビッグエンディアンを考える必要はないのだ。AVRはリトルエンディアンなので、完全に頭からと考えていたが、キャストはあくまでも算術的にデータをとってくるだけである。実際のデータの位置には関係ない。そのとおり(ビッグエンディアンとして)ビットシフトの演算をしてデータを入れていけばよいということがわかった。

 理屈がわかったあとは早かった。手探りで良い加減に入れていたときとは段違いにバグが取れていく。フューズビットも書き換えてデバッグの度に既存データが初期化されるのを防ぐ。ほどなく、オープンして書き込むと次々にデータを追記していき、READするとデータを最初から次々に吐き出すしかけが完成した。

Eep_output とりあえず、ダンプ機能(頭から全部吐き出す)と、EEPROMのフラッシュ(全消去)コマンドを作って動かす。本当は、シーケンシャルファイル風にデータのセッションを分けたいのだが、リアルタイマークロックがないので余り意味がない。機能の拡張は当面先送りである。

USBとバッテリーとの電源自動切り替え(7/22/2011)
 USBがつながるときは、電池からの電源は切っておかないとUSBに悪影響が出る。今は、電池とUSBの給電は単につながっていて何の対策もとっていない。USBがつながった時には、自動的に電池からの供給が切れるような回路を作れば、このことに気を遣う必要はなくなる。FETかなにかでスイッチしたいところである。

 実は、この機能はウェブの情報(掲示板で時々おみかけするgomisaiさんのサイト)を頼りに、ブレッドボードで回路を作り既にテストしていた。オリジナルはFETを2つ使っているが、USB側からの電源分離をSB(ショットキーバリア)ダイオードにしてしまえばひとつ減らせる勘定だ。

Usb_bat_fet

 ブレッドボードのテストではうまくいった。ただ実装はためらっていた。電源小基板にもうスペースがなく、他に追加したい部品があったからである。(掲載の回路図はあくまでも素人の回路です。自己責任でお使い下さい。)

 まあ、電池の電源が、USBバスに重畳しても、そう大きな障害はないと思うのだが、万が一、PCのUSBインターフェースに悪さをして壊してしまうようなことが起きると、PCのマザーボード取替えなどという大げさな事態になりかねない。ここは慎重に考えた方が良い。

 それより、今のままでもUSB給電時は、バッテリー側のレギュレーターの出力側が、5Vに曝されている。心配なので電流計を間に入れてみる。0.6mAの電流がUSBからレギュレーターに向けて流れていることがわかった。この程度では、レギュレーターは全く変化はないが、いずれにしても出力側が入力側(0V)より恒常的に高いと言うのはレギュレーターにとっては嬉しくない。

 電源を切った時、出力側のコンデンサーに残る電荷をダイオードでシャントする回路があるくらいである。がた老AVR研究所にはレギュレーターのたたりもある。FETをこのあいだに入れれば、少なくともUSBからの電圧がレギュレーターにかかることはない。早めに作りこむことにした。

 しかしこの実装は、実は結構面倒なのである。USBからの5Vを基板上で分離しなければならないからだ。基板上のUSBソケットの電源パターンは見たところ1本だけで、ここを切れば分離できそうだが、ソケット下のパターンはわからない(裏面には行っていないようだ)。

 ただ、嬉しいことにこのSparkFunのキットは、Eagleの回路図データと基板データがクリエイティブコモンで提供されている。基板データ(.brdファイル)を見て、USBコネクターから出ているパターンを切るだけで分離できることが完全に確認できた。これは助かった。

 電源小基板との接続は、既にピンとして用意されているリセットピンを流用することにする。リセットピンを外で使う可能性はもう殆どないだろう。この接続をやはりカッターナイフで切り離し、リセットピンにUSBからの電源をUEW線で接続する。出来た。ここまで出来れば、あとは小基板での配線だけに専念できる。予想より楽に出来そうだ。

 小基板では、折角つけた日圧(JST)2ピンコネクターをとりはずし(ピンヘッダーをつけたので必要性が薄れた)、その空き地にFETとダイオードを組み込む。小さい基板のハンダ付けは結構面倒くさい。それに手持ちのFET(2SJ377)がリードタイプでなく、表面実装パッケージなのでリード線をつけなければならず難儀した。

S_p7234046

 何とか組み上げる。ブレッドボードでテストしたとおり、USBの電源が入ると、バッテリーからの電流は、FETできっちり遮断された。レギュレーターにも電流は流れ込まない(テスターで確認した)。完全を期するならバッテリー出力にもダイオードを入れたいところだが、バッテリーの方の電圧降下は嬉しくないのでやめた(追記: 心配なのでこのあとダイオードを追加した。また回路図でFETの方向が誤っていたので修正した。2つの回路図とも修正済み 7/28/2011)。

あちこちで測定する(7/24/2011)
 さて、出来上がったセットを色々な場所に置いて、動かしている。USBに接続するときバッテリー電源のことを考えずにできるというのは精神的にとても楽である。USBにつなぎながら、バッテリーをONにしてUSBを外しても、何の問題もなく測定を続ける。オシロで見ると、全くスパイクもなく、0.2Vくらいの差で電源が切り替わる(PCのUSBが5.2V近く出ている)。

 EEPROMの記録機能は、予想通り大変便利である。EEPROMをクリアしてから、測定したいところに小一時間、セットを放置し、そのあとPCに持ち込んで端末を動かして結果をコンソールで見る。統計をとりたければ、何度でも結果をUARTコンソール上に出せるので、適当なデータをコピーしてExcelなどに貼り付ける。

 ダンプした後の全データの平均値を出すようにしたので、とりあえずはこの値で、全体の平均が見える。あちこち測りまくる。家屋内より、やはり屋外が若干だが値は高い。セシウム137を核種とした換算で行くと(0.0073)、室内が0.084μsV/h、これは地下のPCルームも一階も変わらなかった。屋外では門扉の50センチほど上の植木鉢で、0.091μsV/hと少し高い。

 東京都の公式の発表値は、大分前から0.057μsV/h前後と変わらないが、この測定場所は地上18mというビルの上で(都庁の屋上ではなく百人町の都健康安全センタービルでした。失礼しました)、これより高くなるのはおかしくない。

 最近は都内23区の殆どの区が独自に学校の校庭などで環境放射線量の測定値をウェブなどで発表している。当研究所に近いところでは(東京西部)、0.07~0.09μsV/h(地上1m)ということなので、あながちここで測った値はデタラメではないだろう。

Geigercounter728_2011_2

 データのログ機能が入り少し実用性が出てきたので、SparkFunガイガーカウンターの修正部分の回路図とソースコードをこの記事で公開することにする。SparkFunはソースコードと回路図をクリエイティブコモンにしているので、ライセンスはここでもこれにならう(作者名を残せば、複製、配布、改変、商用可能)ことにする。

 ただソースコードの中には、ChaNさんのコンパクトな書式付print関数、xprintfを活用させてもらっている。いつもながらお世話になっているChaNさんにあらためてお礼を申し上げる。

以下に、ソースコードをAVRStudioのプロジェクトフォルダーの形で公開します。LCDは回路図の修正を行わないと動きませんが、EEPROMの機能はオリジナルの回路でも動きます。

「SparkGeiger725_2011.zip」をダウンロード

使い方の説明:
 使い方を、少し説明しておこう。USBをつないで仮想UART(9600bps 8bit 1stopbit、フロー制御なし)を立ち上げると、GM管のパルスが出る度に、LCD画面と同じ10回の移動平均値が出力されていく。このときリターンキーを押すと、プロンプトモードになり、この出力が停止する。

さらにこのあとスペースバーを押すと、EEPROMに入っているCPM値が、

レコードナンバー     CPM値
次のレコードナンバー  CPM値
    ・
    ・
Average: AA.BB CPM 0.0XY uSv/h for ZZ min

と出力される(必ずリターンキーを押してプロンプトモードにすること)。

1分単位なので、レコードナンバーは分で読み替えられる。508ポイント(分)以上蓄積すると、古いものから削除されていく。

蓄積されたデータを消去する時は、プロンプトモードで、f(小文字)キーを押下すると、

EEPROM will flushed Are you sure? enter (Y/y):

と出るので、消したい時は、Yかyを入力すると、

flushed EEPROM
>

でこれまでのデータがすべて消去される。それ以外の文字では、

No action...
>

と表示され消去されない。>は、プロンプトモードであることを表し、再度リターンキーを押すと、.(ピリオド)が表示され表示モードに戻る。画面データをコピーしたい時は、リターンキーを押して表示を止めておけば失敗しない。

| | コメント (5) | トラックバック (0)

« 2011年7月17日 - 2011年7月23日 | トップページ | 2011年7月31日 - 2011年8月6日 »