0

バニラ関数をテストしていて、無効なコマンド文字列を渡してもエラー コードが返されないviWrite()ことに気付きました。これは少し奇妙だと思います...確かに、実装はこのイベントを検出する必要があります。

これを示すために使用した小さなテストケースを次に示します...(これは単なるテストコードであるため、完璧ではありません:))

#include <visa.h>
#include <cstring>
#include <iostream>

#define VIBUF_LEN 255

static ViChar viBuf[VIBUF_LEN];

void MyWrite(ViSession sess, char const *cmd)
{
    ViStatus status;
    ViUInt32 rcount;

    strncpy_s(viBuf, cmd, VIBUF_LEN);
    status = viWrite(sess, (ViBuf)viBuf, strlen(viBuf), &rcount);
    if (status < VI_SUCCESS)
    {
        std::cout << "Failed to write!\n";
        exit(-1);
    }
}

std::string MyRead(ViSession sess)
{
    ViStatus status;
    ViUInt32 rcount;

    status = viRead(sess, (ViBuf)viBuf, VIBUF_LEN, &rcount);
    if (status < VI_SUCCESS)
    {
        std::cout << "Failed to read 1!\n";
        exit(-1);
    }
    else if (rcount >= VIBUF_LEN)
    {
        std::cout << "Failed to read 2!\n";
        exit(-1);
    }
    else if (!rcount)
    {
        std::cout << "Failed to read 3!\n";
        exit(-1);
    }

    viBuf[rcount] = NULL;
    return std::string(viBuf);
}

int _tmain(int argc, _TCHAR* argv[])
{
    ViStatus status;
    ViSession mVisaDefaultRM;
    ViSession mVisaInst;

    status = viOpenDefaultRM(&mVisaDefaultRM);
    if (status == VI_SUCCESS)
    {
        strncpy_s(viBuf, "GPIB0::1::INSTR", VIBUF_LEN);
        status = viOpen(mVisaDefaultRM, viBuf, VI_NULL, VI_NULL, &mVisaInst);
    }

    if (status < VI_SUCCESS)
    {
        std::cout << "Failed to initialise!\n";
        exit(-1);
    }

    viClear(mVisaInst);
    MyWrite(mVisaInst, "*CLS;");
    MyWrite(mVisaInst, "*RST;");
    MyWrite(mVisaInst, "*SRE 0;");
    MyWrite(mVisaInst, "*ESE 0;");
    MyWrite(mVisaInst, "CRAP;");   /* Wow really!? */
    MyWrite(mVisaInst, "*ESR?;");
    std::string str = MyRead(mVisaInst);
    std::cout << "ESR is " << str.c_str() << "\n";

    std::cout << "END\n";
    getchar();

    return 0;
}

プログラムは次を出力します。

ESR is +32
END

したがって、SCPI コマンド「CRAP;」の書き込みは、デバイスによって間違いなくエラーとしてフラグが立てられています。

これは私に考えさせました、ああ...私はESEビットを有効にして、このビットを有効にしてSTBでフラグを立てていませんでした。だから私はこれを行います:

MyWrite(mVisaInst, "*ESE 255;");
//                       ^^^
//                       A bit of a sledge hammer but should do the job

不正なコマンドはまだ検出されていません。

さて、おそらくSRQを有効にする必要があります...おそらくVISAライブラリはこれを処理するためにこれらの両方を有効にする必要があります...

だから私はこれを行います:

MyWrite(mVisaInst, "*SRE 255;");
//                       ^^^
//                       A bit of a sledge hammer but should do the job

いいえ、違いはありません。それでも、不正なコマンドは検出されません。

これは標準VISAですか?このように機能する必要がありますか?これは、これらのエラーを検出したい場合、常にイベントを有効にする必要がVI_EVENT_SERVICE_REQあるviWaitOnEvent()ということですか? 私はバニラviWrite()が私のためにこれを検出すると思っていたでしょうか??

4

1 に答える 1

2

viWrite書き込みのみを処理します ( Ni Visa Programmers Referenceを参照)。これは、真の通信障害 (タイムアウトや誰かがケーブルを抜いたなど) が発生した場合にのみエラーを返すことを意味します。これは、低レベルの I/O 機能 (ソケット、シリアル ポートなど) の標準です。

つまり、リモート デバイス エラーがあるかどうかを確認するには、何らかの方法でクエリを実行する必要があります。私は VISA に詳しくないので、これを実現する最善の方法が何であるかわかりません。それはあなたが話しているスタイルのもの(イベント)ですか、それともデバイスに直接問い合わせることができますか?(おそらく、「あなたのステータスを教えてください」というコマンドを viWrite してから、応答を viRead できますか?)

于 2013-07-16T11:11:39.467 に答える