01-09-2013 02:30 AM
こんにちは。
表題の件について、どなたかお教えください。
信頼性試験においてサーボモータでターゲット系に働きかけターゲット系の出力信号を、cDAQ-9174 + NI9239 +VB.NET 2005 で繰り返し取得したいと考えています。
サーボモータの動作開始はコントロールできるため NI9239の信号取得開始はコントロールできます。しかし、ターゲット系の動作終了は毎回決まっていないため
ターゲット系の動作終了を検出後(このタイミングはサーボモータとシリアル通信にて取得できています。)NI9239の動作をストップ・データ取得をする方法はないでしょうか?
あるいはサンプルコードなどはないでしょうか?
(NI9239でデータ取得開始) → (サーボモータ動作開始) → (ターゲット系信号出力) → (サーボモータにより動作完了検出)
→ (NI9239データ取得ストップ) → (NI9239取得データの保存) → (先頭へもどり繰り返す)
Task.Timing.ConfigureSampleClock("", SampleRate, SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples, intDataNum)
Reader = New AnalogMultiChannelReader(Task.Stream)
Reader.BeginReadMultiSample( intDataNum, New AsyncCallback(AddressOf ReadCallback), Nothing)
Task.Control(TaskAction.Verify)
大雑把ではありますが、上記のコードではintDataNum 個を事前に設定しなければならず、途中でストップできません。
以上よろしくお願いします。
解決済! 解決策の投稿を見る。
01-09-2013 11:58 PM
平素よりNI製品をご利用頂きまして誠に有難うございます。
日本ナショナルインスツルメンツ技術部のソンと申します。
少座間様が使用しているコードの「ConfigureSampleClock」の「SampleQuantityMode.FiniteSamples」は有限サンプルです。
今回必要なのは連続サンプルですので、「SampleQuantityMode.ContinuousSamples」を使用します。
DAQmxのドライバをインストールした際にテキスト言語サポート、dotNetサポート、をインストールして頂けてのでしたら、
ヘルプファイルと連続サンプルのサンプルコードは下記の場所にあります:
「スタートメニュー」→「National Instruments」→「NI-DAQ」→「Text-Based Code Support」
連続サンプルのサンプルは、ご使用しているdotNET Framework のバージョンのフォルダから:
Analog In\Measure Voltage\ContAcqVoltageSamples_IntClk\VB
を御覧下さい。
宜しくお願い申し上げます。
01-10-2013 01:33 AM
ソン様
御返事ありがとうございます。少座間です。
>Analog In\Measure Voltage\ContAcqVoltageSamples_IntClk\VB
の存在は、知っておりました。ですが、これでは私の希望とする動作ではないようです。
私の最初の投稿が良くなかったので、補足させていただきます。
【補足】 ”任意ストップした時点で Task を終了し、そこまでのデータを取得・保存し、すぐに次の動作に移りたい。”です。
私も、もしやと思い SampleQuantityMode.ContinuousSamples を試したのですが、
Reader.BeginReadMultiSample( intDataNum, New AsyncCallback(AddressOf ReadCallback), Nothing)
このBeginReadMultiSampleで指定した intDataNum の取得が終わらない限り 次の動作に移れない状況です。
ご教授頂いたサンプルプログラムも Stop ボタンは押せるものの、Samples/Channel のNumericUpDown コントロール内に指定した
データ数の取得が終わらない限り反応が返ってきません。
たとえばHIOKI社製メモリハイコーダ8855では、データ取得途中でもストップボタンを2回押せば、そこまでのデータを取得でき動作を終了し
次の動作に移ることができます。この様な使い方はできないものでしょうか?
以上よろしくお願いします。
01-10-2013 01:51 AM
ソン様
お世話になります。少座間です。
さらなる補足です。
>ご教授頂いたサンプルプログラムも Stop ボタンは押せるものの、Samples/Channel のNumericUpDown コントロール内に指定した
>データ数の取得が終わらない限り反応が返ってきません。
NumericUpDown コントロール内に指定するデータ数を小さくしてやれば見かけ上、Stopボタンを押した場合の反応は早いです。(もちろん Rate(Hz) の設定にもよりますが。)
この場合に、例えば1000データを指定したとします。とすると、プログラムの流れは、
(①1000個データ取得) → (画面に表示) → (②1000個データ取得) → (画面に表示)・・・・ と繰り返しますよね。
こうした場合、①の1000データと②の1000データを合わせた2000データは連続なのでしょうか?
言い換えれば2000データを指定した場合と同じ結果となっているのでしょうか?素朴に考えると画面に表示している間のデータが
抜け落ちているのではないかと思っているものですから。
もしも、連続データというのならば、私の投稿は解決なのですが。
以上よろしくお願いします。
01-14-2013 06:51 PM
少座間様のご質問にお答えするにはまず弊社のDAQとPCの通信構造をご説明したほうが良いと思います。
計測を行う際のサンプル数、レート、またメモリはDAQとPCでそれぞれ別に定義されております。
例として連続サンプルでサンプルレート1000Hz、サンプル数/チャンネル1000の測定だとします。
この場合DAQはタスクが開始されてから1000Hzで集録を続けます。このタイミングはDAQの内部クロックを参照しているので正確です。
PCはDAQ読み取り関数でDAQ内のバッファに1000サンプルのデータが溜まるまでポーリングで待機して、最終的にデータをDAQのバッファからPCのメモリに転送します。
理想的にはPCへの読み込みは1秒間に一回行われますが、このタイミングはWindowsのクロックに依存しますし、データ転送により多少の遅延も生じます。
DAQ読み取りはポーリングしますので、この場合画面上の更新と操作は一秒間に一回になります。(LabVIEWであれば簡単に並列スレッドにプログラムが作成出来ますが)
DAQ読み取りは不具合が生じてDAQからデータが来ない場合は指定されたタイムアウト時間後にエラーを返します。
サンプル数/チャンネルを小さい数値にすれば画面の更新速度が早くなりますが、データの転送が間に合わなくてDAQのメモリがいっぱいになることもあります。
逆にサンプル数/チャンネルが大きすぎてもDAQのメモリがいっぱいになってしまいます。
ご質問な対する回答:
> ”任意ストップした時点で Task を終了し、そこまでのデータを取得・保存し、すぐに次の動作に移りたい。
DAQ読み取りは指定されたサンプル数づつデータを転送しますので、直ぐにタスクを終了する事は出来ません。
少座間様の仰る通りサンプル数/チャンネルをある程度小さくすれば(レートの1\10)ほぼ気にならない程度の遅延(100ms)にすることはできます。
本当の意味での「直ぐに停止」は1サンプル毎にデータをDAQからPCに転送になりますが、これでは転送時間が間に合わないのでこのような仕様になっております。
> (①1000個データ取得) → (画面に表示) → (②1000個データ取得) → (画面に表示)・・・・ にデータの抜け落ちはあるか
DAQからPCに転送するのは毎1000サンプルですが、DAQ自体はノンストップで1000Hzの集録を行なっております。
仮にDAQの集録がデータ転送より早かったとしても、データはDAQのバッファ内に保存されて順番にPCの転送されますので、データ抜け落ちは無いです。
しかし、DAQの集録がデータ転送より常に速いとDAQ内のメモリにデータがどんどん溜まっていきますので、いずれはバッファがいっぱいでエラーになります。
以上、不明な点などがございましたらご質問下さい。
宜しくお願い申し上げます。
01-14-2013 11:03 PM
ソン様
お世話になります。少座間です。
ご丁寧な解説ありがとうございました。
おかげさまで抱えていた問題が解決しました。
改めてありがとうございます。
この投稿をご覧になる方々への情報としまして気づいた点を以下に記させて頂きます。
>DAQ読み取りはポーリングしますので、この場合画面上の更新と操作は一秒間に一回になります。(LabVIEWであれば簡単に並列スレッドにプログラムが作成出来ますが)
VB.NETにおいても特に苦もなくできました。上記の並列スレッドとは意味あいが違うかもしれないですが。
Analog In\Measure Voltage\ContAcqVoltageSamples_IntClk\VB のサンプルコードで大雑把に言えば、
startButton_Clickプロシージャ内のコードを 例えば private sub xxxを作成してその中に移動し、
startButton_Click 内に以下のコードでスレッドを作成すれば(相当に簡略化していますのでこのままでは動きませんが・・・)
私の環境では問題なく動作しました。もちろん、xxxから呼び出されるプロシージャに適宜変更は必要となります。
Thread01 = New System.Threading.Thread(AddressOf xxx)
Thread01.Start()
>Reader.BeginReadMultiSample( intDataNum, New AsyncCallback(AddressOf ReadCallback), Nothing)
都合上、サンプルコード Analog In\Measure Voltage\ContAcqVoltageSamples_IntClk\VB のBeginReadWaveformをBeginReadMultiSample関数に
変更したため、AsyncCallback(AddressOf ZZZ)のZZZプロシージャ内の EndReadWaveform関数をEndReadMultiSample関数に変更することとなりました。
ここまでは良かったのですが、2度目以降のポーリングに関しては、BeginMemoryOptimizedReadWaveformをBeginMemoryOptimizedReadMultiSample関数に
変更することになりますので、サンプルコードではEndReadWaveformがそのまま使えることに対して、EndReadMultiSample関数が使えず、
EndMemoryOptimizedReadMultiSampleを使って対応しました。
以上よろしくお願いします。