パルス頻度をアナログ電圧に変換

以前に似たような名前の記事『サーボ信号をアナログ電圧に変換』という記事を書きましたが、今度は時間あたりに何回かやってくるパルスをアナログ電圧に変換することになりました。というのもラジコンモーター用の回転数を計測(タコメーターの機能)し、それをアナログ電圧として取りこみたいという要望があったためです。

回転数を取りたいというニーズはあるようで、回転する物体に磁石を埋め込んで回転数を検出するラジコン用の部品がありました。例えばEagleTreeという製品の RPM Sensor with 4 magnetsがそれに対応すると思います。原理は単純で、埋め込まれた磁石の磁力をホールICで検出しパルスに変換、あとはそのパルスの頻度を監視すればよい、という訳です。先ほどの製品を分解された方もいるようで、製品で利用しているホールICの仕様を知ることができました。その他にも、光学的な方法(ペラが通ると光がさえぎられる)や電気的な方法(モーターを駆動しているスピコンの出力を監視する)といった方法があるようですが、マグネット方式が一番汎用性が広そうなので、ここではそういったセンサから出力されるパルスの頻度に注目することにしました。

ということで表題のとおり、パルスの頻度をアナログ電圧にマイコンを使って変換することを考えました。ここで2つの方式が思い浮かびました。一つは単位時間あたりのパルスの数を数える方式(波数方式と名づけます)、もう一つがパルス間の時間を計測する方式(同じく波長方式)です。この2つの方式を比較してみました。

結果は波長方式に軍配があがりました。というのも波数方式では回転数の計測精度をあげるためには、監視を行う一定時間、つまりサンプリング間隔を長く取らなければならず、更新頻度と精度が比例の関係にあります。一方の波長方式ではタイマーの解像度があれば、比較的短いサンプリング間隔である程度の精度を維持することができます。
詳しい比較はExcelのファイルに譲りますが、具体的な数値をあげると、8000rpm時に波数方式ではサンプリング間隔=1秒で60rpmの精度に対し、波長方式ではサンプリング間隔=約10msで精度2rpm(PIC16F88に搭載の16bitsタイマーの使用を仮定)と、更新頻度、精度とも波長方式が優れているという結果になりました。
予想はできていたのですが、このようになった理由としては、モーターの回転を検出するパルス頻度はマイコンにとって永遠とも呼べる時間であること(マイコン=数MHz、モーター=数百Hz)、またタイマーの解像度が意外と高い(16bits)こと、があげられると思います。

実装ですが、基板は以前の記事と同じPIC16F88を使った基板に対して、ほぼコードを入れ替えるだけで機能を実現できました(ホールICによってはオープンドレインのものがあるので、センサからの入力をプルアップに修正する必要があります)。コードをこの辺りにおいておきます。

コードで注目すべきは、波長方式においては除算をしなければならない、ということに話はつきます。除算をしなければならないのは (回転数) = 1.0 / (波長) の関係にあるためですが、マイコンにとって割り算は鬼門であり、今回もご多分に漏れずsdcc-2.8.0 (build.5117)においても16bitsどおしの除算を失敗していました。
そのような場合は線形補完(テーラー展開の1次項をとる)+ビットシフト演算で乗り切るのが定石だと思います。簡単な例をあげると、テーラー展開の結果 (差分) (割る 3) がでてきた場合、 (差分) (掛ける 43) (割る 128) つまりは (掛ける 43) (ビットシフト 7)で代用するということです。経験上、掛け算とビットシフト演算はどのマイコンでも問題なく動作するので、安心して使えます。
公開したコードからこのような苦労の片鱗を見ていただけると、少し報われます(笑)。

September 08, 2008 00:58 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク

コメント

コメントする