概要
私が勤めている職場には小型の卓上旋盤やフライス盤が設置されているのですが、いずれもボリュームで回転数が変更できるものの肝心の回転数表示がありません。
これらの装置は加工する材料の材質や直径などにより適切な回転数を決めないとうまく加工できません。
品質維持のためにもぜひ回転計が欲しいという事で、余っている部品をかき集めて即席タコメータを作りました。
回路構成
回転検出に使用したセンサはUS1881というホールセンサです。
回転検知にはフォトセンサなども候補に挙がると思いますが、油や切りクズなどで汚れて検知不良が出ると使い物になりませんし、メンテナンスも大変です。
ホールセンサにはアナログ出力とデジタル出力の2種類があり、US1881はデジタル出力でマイコンに直結出来て使いやすいタイプです。また、デジタル出力でも磁気が入った時にONするタイプや、N極・S極に応じて出力の+-が切り替わるものがあります。
安くで手に入ったUS1881は後者のタイプなので、パルス極性を交互させるために磁石が2個必要になります。
CPUには引き出しの肥やしになっていたPIC16F873を使っています。ロットを見るとなんと2000年製造になっていました。 センサ出力はオープンドレンなので5.1kΩでプルアップしてあります。オープンドレン出力ができるセンサなら他の物も使えるので、フォトカプラやらなんやらに付け替えて応用できるようになっています。 7セグLEDは回路図を見ての通りダイナミック駆動です。
CPUには引き出しの肥やしになっていたPIC16F873を使っています。ロットを見るとなんと2000年製造になっていました。 センサ出力はオープンドレンなので5.1kΩでプルアップしてあります。オープンドレン出力ができるセンサなら他の物も使えるので、フォトカプラやらなんやらに付け替えて応用できるようになっています。 7セグLEDは回路図を見ての通りダイナミック駆動です。
プログラム構成
ソースリスト Ver.0.04
ソフトの要求仕様として、表示可能な回転数は0~9,999回転、7セグLEDはちらつかない程度のダイナミック点灯、極力割り込みを使用するという方針で開発をスタートしました。 パルス幅をカウントする過去の例として赤外線リモコン受信ユニットを作った事があるので、これを参考に開発を進めました。
センサから出力したパルスはCCP割り込み経由で入力し、立下りの間隔をカウントして以下の数式に当てはめて1分間の回転数を求めます。
CCPの計測値は16ビットですが、実際はクロック周波数の影響を受けて最大18ビットの値で取得されます。 このクラスのPICでは多バイト長の乗除算処理は苦手なので、式を変形して最低限の計算時間で回転数が求められるようにしました。 余談ですが、プログラム開発時にこれまで使っていた24ビット除算ルーチン(気圧高度計を作った時にAVR版から移植したもの)に移植バグがあることが判明しました。 今回は即席で作りたかったのでネットで別の除算ルーチンを探してきて対応しました。
割り込みの利用については、CCP用のTimer1オーバーフロー割り込みで16ビット以上の追加カウント、CCP割り込みでキャプチャデータの退避とフラグ立て、Timer2でLEDのダイナミック点灯といった3種類の割り込みを使っています。 優先度が低いメインルーチンではキャプチャ完了フラグをチェックして割り込みで退避したキャプチャデータから回転数を求める割り算、回転数から7セグLEDの点灯パターンへ変換して表示バッファを更新する処理を行っています。
ソフトの要求仕様として、表示可能な回転数は0~9,999回転、7セグLEDはちらつかない程度のダイナミック点灯、極力割り込みを使用するという方針で開発をスタートしました。 パルス幅をカウントする過去の例として赤外線リモコン受信ユニットを作った事があるので、これを参考に開発を進めました。
センサから出力したパルスはCCP割り込み経由で入力し、立下りの間隔をカウントして以下の数式に当てはめて1分間の回転数を求めます。
RPM = 1 / 測定したCCPパルス間隔 * 60
これを変形して
RPM = 60 RPMの基準パルス間隔定数 / 測定したCCPパルス間隔 とします。
これを変形して
RPM = 60 RPMの基準パルス間隔定数 / 測定したCCPパルス間隔 とします。
CCPの計測値は16ビットですが、実際はクロック周波数の影響を受けて最大18ビットの値で取得されます。 このクラスのPICでは多バイト長の乗除算処理は苦手なので、式を変形して最低限の計算時間で回転数が求められるようにしました。 余談ですが、プログラム開発時にこれまで使っていた24ビット除算ルーチン(気圧高度計を作った時にAVR版から移植したもの)に移植バグがあることが判明しました。 今回は即席で作りたかったのでネットで別の除算ルーチンを探してきて対応しました。
割り込みの利用については、CCP用のTimer1オーバーフロー割り込みで16ビット以上の追加カウント、CCP割り込みでキャプチャデータの退避とフラグ立て、Timer2でLEDのダイナミック点灯といった3種類の割り込みを使っています。 優先度が低いメインルーチンではキャプチャ完了フラグをチェックして割り込みで退避したキャプチャデータから回転数を求める割り算、回転数から7セグLEDの点灯パターンへ変換して表示バッファを更新する処理を行っています。
見やすくするための工夫
パルス幅を計測して表示するという仕組み上、低回転では表示の更新間隔が長く、高回転では表示の更新間隔が短くなる特性があります。
私の体感では表示が秒速6回程度を超えると目で数値を追うのが難しく、秒速10回を超えると表示が変わりやすい1の位の桁はほとんど読めませんでした。
秒速6回は回転数に換算すると360RPMですので、中速域で使わない限りほとんど読めない事になってしまいます。
ということで、LEDのリフレッシュタイミングと同期させて毎秒6回以上は表示を更新しないようにしました。もちろん60RPMのような低回転では低速で表示が更新されます。
使ってみて分かったこと・製作過程で苦労した点
- 表示更新のリミットを付けたことで視認性が上がった。これが有るのと無いのとでは大違いである。
- 見やすい更新間隔を決めるために何通りものパターンを作って試行錯誤したところが苦労した。
- CCP計測の精度を上げるつもりでクロックを10MHzに上げたところ、低回転の計測ができなくなったこと。 これは計算基準にしている60秒のパルス間隔が24ビットの数値に収まらなくなったのが原因だった。むやみに周波数を上げるのも良くないと痛感した。現在の4MHzで下限回転数は43RPMである。
- 高回転時に1の位の桁の精度は問われにくくなるため、8,192RPM以上では10で割って表示するようにした。これにより99,990RPMまで表示可能になった。
- 電源の電解コンデンサを実装する場所が狭すぎた。
参考サイト
- 24bitの除算ルーチンが掲載されていたサイト。他にも価値のあるプログラム例が沢山あってとても役に立ちます。