この記事で扱っていること
- トリガできないハードウェアでしきい値を超えたら値を取得する方法
を紹介しています。
注意:すべてのエラーを確認しているわけではないので、記事の内容を実装する際には自己責任でお願いします。また、エラー配線は適当な部分があるので適宜修正してください。
LabVIEWは計測プログラムに特化したプログラミング言語なのでハードウェアを使用する場面は多いと思います。
National Instruments社が出しているハードウェアのみならず、他のベンダーが提供している計測器もLabVIEWで操作することができます。
そしてそれぞれのハードウェアごとに様々な仕様があるわけですが、そのうちの一つにトリガによる集録開始機能があります。
これは、あるチャンネルでトリガ信号を受けてその結果によってデータの集録を開始する機能です。トリガ信号はデジタル信号(パルス)であることが多いかもしれないですが、アナログ信号を対象として、「あるしきい値を超えたら集録を開始する」という場合もあると思います。
ハードウェアがそういった機能に対応していればいいのですが、中にはそんな機能を持っていないものも当然あると思います。
そこで、ソフトウェア的に疑似的に開始トリガ機能を設ける仕組みを考えてみました。
集録はトリガ等関係なく常に行わせており、トリガ信号自体も測定します。そしてトリガ信号があるしきい値を超えたらデータを別のループに渡し、そのループでデータを表示させたり保存したりすることができるといった仕組みとしました。
どんな結果になるか
プログラムのフロントパネルはこのような形です。
トリガの基準となる信号は何ch目なのかおよびしきい値となる値を指定するトリガパラメーター以外は停止ボタンとデータ表示のためのグラフしか設けていません。
実行すると、トリガ信号を受けるチャンネル(例えばチャンネル0)の信号がしきい値の値を超えるまでグラフには何も表示されません。しきい値を超えてからグラフに値が表示され出します。
プログラムの構造
今回のプログラムはあくまで「一度トリガされて開始したら停止ボタンが押されるまでずっとデータの集録を続ける」という前提としています。そのために必要な構造としては、
- しきい値を超えたかどうかの判定
- 超えた値からのデータを集める
という仕組みを設ける必要があります。これらは機能ごとにサブVIとしました。
メインVIの全体像を以下のようにしています。いわゆる生産者・消費者デザインパターンで実装しています。
このプログラムでは、テスト用の信号として適当な正弦波にノイズを足した波形を2つ(2チャンネル分)使用しており、そのうちの片方をトリガ信号としています。
このテスト用の信号はtest_data_generator.viで作成していますが、ここは適宜実際に使用する測定データを取得する関数で置き換えます。
集録されたデータからトリガ信号がしきい値を超えたかどうかを判定するのがtrigger_detector.viになります。
trigger_detector.viでは、まず以前に一回でもトリガ信号がしきい値を超えたかどうかをブールで判定しています。TRUE、つまりトリガ信号がしきい値を超えたことがあれば、トリガ検出はTRUEとし、また後のサブVIに「このデータは全てトリガ検知後のデータですよ」ということをしきい値超えデータ指標値を0として伝えます。(なお、この例ではしきい値を超えた場合を開始トリガとしていますが、しきい値を下回った場合を開始トリガにする場合には不等号の大なり小なりの判定を反転させるだけです)
一方、まだトリガ信号がしきい値を超えたことがないときには、トリガ対象とするチャンネルのデータを一つずつみていきしきい値を超えたかどうかを判定します。波形データのYの値をForループに配線し、しきい値を超えたらForループが止まるように条件端子を設けています。
しきい値を超えたらそのことをブールで表現し、またしきい値を超えたデータが何番目であったかを後の関数に伝えるためにForループの反復端子の最後の値を出力させています。
その後のdata_extractor.viは、trigger_detector.viでトリガ検知されることでメインVIのケースストラクチャがTRUEとなって実行されます。波形データから「トリガ信号がしきい値を超えた初めてのデータ」以降のデータを抽出します。
この「トリガ信号がしきい値を超えた初めてのデータ」は、trigger_detector.viのForループの条件端子の最後の値に一致しています。
実装の仕方が複数あり、単純にLabVIEW標準関数の部分波形を取得関数で抜き出す波形要素を指定するやり方がシンプルです。
この操作をあえて波形要素で自力で行うとすると、「無視した要素の数だけt0をずらす」必要がありますが、ずらすべき時間量は無視した要素の数にdtをかけた量であることに注意します。
どちらの実装でもいいと思います。
メインVIの方では、ケースストラクチャがTRUE、つまりトリガ信号がしきい値を超えて以降はずっとこのケースストラクチャがTRUEになるようにシフトレジスタを組んでいます。このケースストラクチャのセレクタ端子は、一度TRUEとなったらずっとTRUEのデータが渡され続ける、とも言えます。
ケースストラクチャがTRUEになったら、エンキューの関数でデータを消費者ループに渡しています。つまり、トリガ信号がしきい値を超えて以降のデータしか消費者ループには渡されません。
そのため、消費者ループ内で行いたい処理(表示、解析、保存など)を行わせれば、集録自体はトリガ信号の状態に関係なく行われていたとしても、疑似的に「トリガ信号がしきい値を超えた時点で集録を開始した」状態を再現することになります。
動作の確認
動作を確認するために、波形グラフをもう一つ用意して、これを生産者ループに配線してやります。
生産者ループの方では、トリガ関係なくすべてのデータを扱っているので、そのデータを見つつ、トリガ信号がしきい値を超えたら消費者ループの方のグラフにも表示され始める様子を見ることで、意図したとおりの動作になっているかを確認することができます。
例えば以下の図は、トリガのしきい値を4としたときのトリガ前後の結果です。
このプログラムでは、指定したチャンネルの値がとにかくしきい値を超えたかどうかだけで判断しているので、ノイズでたまたましきい値を超えてしまった場合でもトリガとして検出してしまいます。
そのためノイズの影響も考慮するとなると例えばヒステリシスを指定するといった書き方になると思います。そちらの実装はもう少し複雑になります。
開始トリガをかけられないハードウェアを使用する際にどうしても開始トリガを実装したいときにこの記事が役に立てば嬉しいです。
ここまで読んでいただきありがとうございました。
コメント