0

私は現在、Simulink でのデータ取得とリアルタイム処理を含むプロジェクトに取り組んでいます。このプロジェクト専用に購入した DAQ ハードウェア、つまり National Instruments DAQ デバイス (USB) があります。

セッションベースのインターフェースを使用する必要があります。レベル 2 の MS 関数を作成しようとしましたが、問題は、daq.createSession 関数を使用してセッションを作成する場所と、アナログ出力を作成できる場所がわからないことです。誰かにコード例やアドバイスがありますか?

それとも、C ライブラリを書くのは簡単でしょうか? この C ライブラリに使用できる Simulink ブロックはどれですか? マトラブ関数?そして、DAQmxErrChk (DAQmxCreateAOVoltageChan(taskHandle,"Dev1/ao0","",-10.0,10.0,DAQmx_Val_Volts,NULL)); を使用できますか? Simulink での DAQmx サンプルの機能に問題はありませんか?

4

1 に答える 1

0

これには多くのコード行があり、SO 規則に少し反するため、これに対する回避策全体を投稿することはできません。ただし、同様のことができるように、それがどのように機能するかを説明するために最善を尽くします. クラス内にレベル 2 の MS 関数を記述できるようにする一連のクラスがあるという事実によって、これをコーディングしている間は確かに楽になりましたが、それがなくても確実に実行できます。

基本的に最善の策は、ブロックのマスクを作成することです。マスク パラメーターを変更するたびに、Simulink はコールバックを呼び出します。onSetupここで、通常はチャネルを設定したり、他の MS 関数コールバックを登録したりします。この関数で DAQ セッションを作成します。まだ作成されていない場合は、チャネル数、サンプル レート、およびチャネル モード (およびその他のセッション情報) を更新します。次にUserData、ブロックのプロパティを DAQ セッション インターフェイス、または DAQ セッションへの参照を持つハンドル クラスの構造体またはインスタンスのいずれかに設定できます。

また、着信データをキューに入れる方法も必要です。FileExchange からキュー クラスを取得できます (いくつかあると思います) が、これらの速度についてはわかりません。ここでは、リンク リストを完全に実装する必要はおそらくないので、循環バッファーをデータ ストレージとして使用するキュー クラスを作成しました。新しいサンプルが入ってくるとき)。空のキューをポップしようとするとクラス エラーが発生し、満杯のキューにプッシュすると「キュー オーバーラン」タイプのエラーで警告されます。onPostPropagationSetupキューは、それぞれおよびで割り当て/割り当て解除されますonTerminate

DAQ セッションからデータを受信すると、次の関数が呼び出されます。

function onDaqDataAvailable(self, data)
    self.sampleQueue.push(data.Data);
    self.updateOutputStatus();
end

function updateOutputStatus(self)
    if self.sampleQueue.filledLocs >= 0.5 * self.sampleQueue.queueLength
        self.bOutput = true;
    else
        self.bOutput = false;
    end

    drawnow update;
end

そこのしきい値が実際に必要かどうかはわかりません。実際には少し高すぎるかもしれませんが、自分でいじることができます。次に、onOutputsコールバックで、

    function onOutputs(self, block)
        if ~self.daqSess.IsRunning
            self.daqSess.startBackground();
        end

        while ~self.bOutput
            pause(0.1 * self.frameLength / self.sampleRate);
            // Displaying number of samples in queue is useful for debugging here...
            // But we should really use a scope instead
            disp(self.sampleQueue.filledLocs)
            self.updateOutputStatus();
        end

        // Displaying number of samples in queue is useful for debugging here...
        // But we should really use a scope instead
        //disp(self.sampleQueue.filledLocs)
        samples = self.sampleQueue.pop(self.frameLength);
        for nChan = 1:self.nChannels
            block.OutputPort(nChan).Data = samples(:, nChan);
        end

        self.updateOutputStatus();
    end

これは、ブロックが実際にどのように機能するかの基礎です。DAQ セッションのNotifyWhenDataAvailableExceedsプロパティを適切なものに設定して、1 秒あたり最大 20 回の呼び出しを取得する必要があることに注意してくださいonDaqDataAvailable。ただし、サンプル キューがあれば、これはかなり簡単です。モデルの準備が完全に整うまで、DAQセッションは実際には開始されないことにも注意してください。事前に開始すると、スコープなどが UI を開いたときに、多くのキュー オーバーランが発生します。

これで、同等の回避策を作成するのに十分な説明が得られたことを願っています。

于 2013-04-06T12:11:36.627 に答える