(日々の記録)デジタルオシロを買った。(水)音響パルス間隔測定機の実装へ実用化に程遠い計測成功確率(10/2/08)前の記事のコメントを見ていただければわかるように、Tiny861のADコンバーターの入力インピーダンスが60Ωしかないと騒いでいた事件は、kugaさんの一言で一気に解決した。LEDのノイズをさけるため慌ててAD入力のピンを移動した際、ポートの入出力方向を決めるレジスターDDRを出力(1)にしたまま動かしていたのである。MCUのこういう多目的の入出力ポートは、特定の機能を持たせたときはDDRは無関係になるという誤った先入観があって、全く無頓着だった。最初の頃は、Web記事に忠実に、真面目に設定していたと思うが、慣れてくるにしたがって横着したのが良くない。あのコメントを見て、慌ててDDRを修正し動かしたら、ぴったりハイインピーダンスになり、10KΩ以上の抵抗を入れたLPFでも全く電圧降下なしにオペアンプからの出力がピンに出てくるようになった。これでオペアンプのゲインを増やさなくて済む。それにしてもブログを開設して始めてのコメントらしいコメントがこんな大当たりのコメントだったのに感激する。kugaさんありがとうございました。それにしてもADコンバーターが出力ポートにしておいても動くとは全く考えもしていなかった。その後の間隔測定は順調とはいえない。絶対値でなく前後の差で劇的に成功率が高くなったとはいえ、少し長く測っているとやっぱり時々間違える。誤り率が波形の正確な電子式で特に多い。入力ピンがハイインピーダンスになって出力電圧が上がりLPFで自由に波形を整形できるようになったが、電子式に最適になるようにすると、機械式がおかしくなり、機械式に合わせると、電子式がエラーだらけになる。実用になるレベルではない。大体、電子式の音響波形を見ていると正確な方形波であり間違えようがないと思うのだが、これがミスするのである。サンプリング周期を1msから0.25msに早くしたり、平均をとる回数を3回から10回、20回と増やしてもパルスの立ち上がりで短いパルスと長いパルスの2つにとってしまう。紙にパルスの状況とサンプリングのタイミング図を散々書いて調べた結果、やっとその原因がわかった。要するに、急速にパルスの立ち上がる区間にたまたまサンプリングの周期が入ると、その前後の値はちょうどピークの1/2づつの差が出来て、閾値の設定が非常に微妙になり、閾値が大きいと2つとも逃すし、小さいと2つとも拾ってしまう。どのタイミングにサンプル期間が来るかはわからない。これは、この方式では構造的な問題で、閾値をどれだけ追い込んでも、サンプリングの巾を変えても解決できない。点で評価すれば解決しそうだが、それほど複雑なロジックが必要なものとも思えない。簡単なロジックがあるはずだ。機械式がまだ正確なのは、パルスが立ち上がった後すぐ大きく変化し、電子式のように前後がちょうど1/2になるタイミングになることが少ないからだと思われる。リズムキャプチャーと命名(10/4/08)パルス判定ロジックは暗礁に乗り上げたが、まあ、これはソフトウエアで解決する話だ。測定データは完全に数値化ができているし、こればかりに時間もとっていられない。先に進むため、そろそろ実装に向けて作業を開始することにした。これまでリズムメーターと呼んできたが、どうも実態をあらわしていない。そこで、音響パルスのリズム間隔をキャプチャーする(つかまえる)「リズムキャプチャー」という名前にすることにする。これならば、このあいだのコメントにあったように、電子メトロノームと誤解される心配もない。アナログ関係はあとはゲインの調整用の可変抵抗器をどこかにつける必要があるだけでもう余り心配はない。懸念されたLEDのノイズはブレッドボードと電源スイッチの間の接触不良が大きな原因であることがわかった。差し込むとノイズは殆ど無視できるほど下がった。電源のレギュレーションをここで悪くさせていたのか、高周波でも出ていたのかもしれない。パスコンを色々な所に挟んでノイズ対策をしていたが改善せず、放置してあったのだけれど助かった。プログラムはこれまでスイッチでタイミングを測っていたコードを流用していたが、あとからコードを追加したため構造が複雑になってしまった。最初から作り直すことにする。今度は、持ち運べるようにLCDに表示するコードも必要だ。フラッシュが8kもありプログラムはいくらでも増やせるが、入出力ポートは意外に少なく、LCD表示をしようとするとピンが足らない。ISPの3つのピンは使えないわけではないが、デバッグ用のUARTに残しておきたいし、LEDも今の3つはともかく、2つくらいは欲しいし、スイッチは測定開始終了の指示のため必須なのでこのピンもいる。結局、LEDの数を2つに絞ってピンアサインは何とか納まった。手持ちのケースやLCD、電池ケースなどを並べてレイアウトを考える。アナログ増幅のため、電源は最低でも5V近くは欲しい。するとバッテリーはやはり3つは必要で、バッテリーだけでケースの半分を占めてしまうが仕方がない。ゲイン調整のVRを何処に置くか、LCDの配置をどうするか。保守性を良くするためLCDは基板につけて、上蓋に固定するのは避けたいが、位置あわせや、見栄え良く仕上げることが難しいし、耐久性が心配だ。いやいや悩むことが沢山ある。これも電子工作の醍醐味のひとつである。埋もれていたバグを見つける(10/5/08)リズムキャプチャーのソフトを作り直す話である。このプログラムはイベントドリブンで、一番主要なイベントは0.25ms毎のタイマー割込みである。このときにADCを動かし音響入力を測定する。回数を数えておいて一定の間隔でADCからの出力を平均化し、前回の数値と比較して閾値を越えればフラグを立てる。別のところでも数をかぞえていてこれはLEDを点滅させるのに使う。次の割込みでさっきのフラグを見て別のタイマーを止め、これまでの時間を測る。これがリズム間隔となる。このタイマーはただちにスタートし次の間隔を測り始める。このイベント以外に不定期に発生するイベントが2つある。ひとつは測定開始・終了を制御するスイッチ割込みと、リズム間隔を測るタイマーがオーバーフローすると(4秒余り)、タイムアウトして計測を中止し初期状態に戻すタイマー割込みである。この2つはさっきの0.25msの割り込みとは全く独立していつ起きるかわからないイベントである。難しい構造ではないが、プログラムの中のフラグやスイッチはなるべく少なくしたい。良い加減に作っていくとスパゲッティになる。久しぶりに擬似コーディングを紙の上でやった。擬似コーディングという言葉に聞きなれない人も多いだろうが、要はいきなりソースコードを書いて行くのではなく、普通の言葉でプログラムの動作をステートメント風に箇条書きに書いて矛盾がないか確かめる方法である。if文やwhile文の条件文も日本語で書く。するとロジックが理解しやすい。ひとつ肝腎なことは、自分が使う立場になってソフトウエアの仕様を完全に決めてから開発に入ることだ。操作面(業務要件)から入るのは、大規模ソフトウエアのときと変わらない。中途半端に仕様を決め開発に入ってしまうとあとで痛い目に会う。何か処理をするときのことは一生懸命考えるが、それが終わったあとどうするかまではなかなか考えておかない。これをつめておかないと丈夫なソフトウエアにはならない。今度のリズムキャプチャーの操作仕様をまとめてみた。電源を入れるとウエルカムメッセージが出て、電源が入ったことが確認できる。スイッチを一度押すと、測定が始まる。リズム音を検知するとLEDが点灯し測定に入ったことがわかる。最初は測定値だけだが、何回か測定が進むと平均値のメトロノーム数(一分間の拍数)が出る。測定中にスイッチを押すと無条件に測定を中止し、もう一度押すと測定を再開する。拍の間隔が5秒以上になるとタイムアウトとして初期の状態に戻り、測定中を示すLEDが消える。以上のことをなるべく構造を簡単にしてプログラムしていくわけである。これ以外に気を遣う事は山ほどある。割込みルーチンの中にはなるべく複雑な処理をいれない。これはレジスター退避などを少なくしてフラッシュメモリを節約するためもあるが、処理をなるべくメインルーチンでひとまとめにしてあるほうが、デバッグの時に余計な心配をしないで済む。それに余り長い間割込みルーチンに入っていると、別の割込みが入ってフラグが変わってしまい、わけのわからないバグに悩まされる。このあいだのI2Cドライバーのときも非同期にプログラムが2つ動いていてこれにやられた。今度のソフトは最初、3つのフラグを使っていたが、擬似コーディングを重ねて、ひとつ減らすことが出来た。フラグを減らすことばかり気を取られていると、構造がかえって複雑になり、デバッグに苦労することになる。何事もバランスが大切だ。能書きを垂れつつ、やっとソフトが完成した。これまではスイッチをメトロノームの音響パルスに見立てたテストプログラムだが、今度は実装を前提にした本格版である。公開にそなえてコメントもなるべく入れる。これが動かないのである。自信を持って組み上げたはずなのだが、開始のスイッチを入れてもうんともすんとも言わない。やれやれ、テストステートメントを挿入し動きを追跡する。スイッチで開始フラグが立つのだがスイッチを押してもフラグが立っていない。テストステートメントをスイッチ割込みのところまで増やしてテストする。なに、割り込みが2回も起きている。スイッチはトグル(0なら1、1なら0)なのでこれでは永遠にスタートにならない。