NI VISA C 函式 viParseRsrc() 或 viParseRsrcEx() 無法辨識有效的 VISA Resource 字串

更新 Jan 19, 2024

環境

驅動程式

  • NI-VISA

程式語言

  • C++
  • C

我用C/C++ 編寫一支有呼叫到 NI-VISA 的程式,在程式中,我想使用viParseRsrc()viParseRsrcEx() ,但是這兩個函式似乎都不起作用或者它們回傳的狀態都 < 0。

首先請確認您給的  VISA resource string 是否正確。您可以透過多種方式進行檢查,可嘗試以下方法之一: 如果嘗試過這兩點之一是正常的,那麼表示它是一串正確的 resource string。這種情況下,很可能需要對參數進行不同的設置。

檢查viParseRsrc()viParseRsrcEx()的其他參數。確保ViPUInt16 intfTypeViPUInt16 intfNum  是 passed by reference (使用 the & operator) ,而不是透過值傳遞的。

對函式的呼叫應該是:

viParseRsrc(defaultRM, cInstrString, &intfType, &intfNum)
viParseRsrcEx(defaultRM, cInstrString, &intfType, &intfNum, &rsrcClass, &expandedUnaliasedName, &aliasIfExists)

使用 viParseRsrcEx 時,您還需要為ViChar緩衝區提供適當的大小:

ViChar rsrcClass[20] = "0"; ViChar expandedUnaliasedName[20] = "0"; ViChar aliasIfExists[20] = "0";
ViChar rsrcClass[20] = "0"; ViChar expandedUnaliasedName[20] = "0"; ViChar aliasIfExists[20] = "0";
 

Example Code

以下範例程式碼是在 Microsoft Visual Studio 2022 中建立的,是跑在安裝 NI-VISA 的 Windows 系統上,它使用 GPIB-USB-HB+ 和 NI Instrument Simulator。

只需對程式碼稍作修改,就可以在 Linux 和其他 VISA 資源上執行。
/********************************************************************/
/*             Simple Parse Resource Example                        */
/*                                                                  */
/* This example demonstrates how you might test your system for     */
/* the existence of a particular instrument.                        */
/*                                                                  */
/* The general flow of the code is                                  */
/*      Open Resource Manager                                       */
/*      Use viParseRsrcEx() to test for the existence of a specific */
/*          instrument                                              */
/*      Use viParseRsrc() to test for the existence of a specific   */
/*          instrument                                              */
/*      Open a session to this device                               */
/*      Close the VISA Session                                      */
/*                                                                  */
/* This example works well with a NI Instrument Simulator on        */
/* GPIB0::1::INSTR                                                  */
/********************************************************************/

#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
/* Functions like strcpy are technically not secure because they do */
/* not contain a 'length'. But we disable this warning for the VISA */
/* examples since we never copy more than the actual buffer size.   */
#define _CRT_SECURE_NO_DEPRECATE
#endif

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "visa.h"

static ViSession defaultRM;
static ViSession instr;
static ViStatus status;
static ViUInt32 retCount;
static ViUInt32 writeCount;
static char stringinput[512];

/*
* In every source code or header file that you use it is necessary to prototype
* your VISA variables at the beginning of the file. You need to declare the VISA
* session, VISA integers, VISA strings, VISA pointers, and VISA floating variables.
* Remember that if you are prototyping variables that are to be used as part of the
* VISA session that need this prototyping. As an example, above retCount has been
* prototyped as a static variable to this particular module.   It is an integer of
* bit length 32. If you are uncertain how to declare your VISA prototypes refer
* to the VISA help under the Section titled Type Assignments Table. The VISA
* help is located in your NI-VISA directory or folder.
*/

int main(void)
{
    /*
     * First we must call viOpenDefaultRM to get the resource manager
     * handle.  We will store this handle in defaultRM.
     */
    status = viOpenDefaultRM(&defaultRM);
    if (status < VI_SUCCESS)
    {
        printf("viOpenDefaultRM: Could not open a session to the VISA Resource Manager!\n");
        exit(EXIT_FAILURE);
    }
    else
    {
        printf("viOpenDefaultRM: Opened Session to the VISA Resource Manager.\n");
    }

    /*
     * Now we will open a VISA session to a device at Primary Address 1.
     * You can use any address for your instrument. In this example we are
     * using GPIB Primary Address 1.
     *
     * We must use the handle from viOpenDefaultRM and we must
     * also use a string that indicates which instrument to open.  This
     * is called the instrument descriptor.  The format for this string
     * can be found in the NI-VISA User Manual.
     * After opening a session to the device, we will get a handle to
     * the instrument which we will use in later VISA functions.
     * The two parameters in this function which are left blank are
     * reserved for future functionality.  These two parameters are
     * given the value VI_NULL.
     *
     * This example will also work for serial or VXI instruments by changing
     * the instrument descriptor from GPIB0::2::INSTR to ASRL1::INSTR or
     * VXI0::2::INSTR depending on the necessary descriptor for your
     * instrument.
     */

    ViRsrc cInstrString = "GPIB0::1::INSTR";
    char cStatusChar[100] = "none";

    ViPUInt16 intfType = 0; /* Interface type of the given resource string. */
    ViPUInt16 intfNum = 0; /* Board number of the interface of the given resource string. */
    ViChar rsrcClass[20] = "0";
    ViChar expandedUnaliasedName[20] = "0";
    ViChar aliasIfExists[20] = "0";

    status = viParseRsrcEx(defaultRM, cInstrString, &intfType, &intfNum, rsrcClass, expandedUnaliasedName, aliasIfExists);
    if (status < VI_SUCCESS)
    {
        printf("viParseRsrcEx of cInstrString[100] = \"GPIB0::1::INSTR\" before viOpen: Ressource not ready / existing.\n");
        printf("--Error Code: %d \n", status);
        viStatusDesc(&defaultRM, status, cStatusChar);
        printf("--Error Code: %s \n", cStatusChar);
    }
    else
    {
        printf("viParseRsrcEx of cInstrString[100] = \"GPIB0::1::INSTR\" before viOpen: Ressource ready.\n");
    }

    status = viParseRsrc(defaultRM, cInstrString, &intfType, &intfNum);
    if (status < VI_SUCCESS)
    {
        printf("viParseRsrc of cInstrString[100] = \"GPIB0::1::INSTR\" before viOpen: Ressource not ready / existing.\n");
        printf("--Error Code: %d \n", status);
        viStatusDesc(&defaultRM, status, cStatusChar);
        printf("--Error Code: %s \n", cStatusChar);
    }
    else
    {
        printf("viParseRsrc of cInstrString[100] = \"GPIB0::1::INSTR\" before viOpen: Ressource ready.\n");
    }
    
    status = viOpen(defaultRM, cInstrString, VI_NULL, VI_NULL, &instr);
    if (status < VI_SUCCESS)
    {
        printf("viOpen of cInstrString[100] = \"GPIB0::1::INSTR\": Cannot open a session to the device.\n");
        printf("--Error Code: %d \n", status);
        viStatusDesc(&defaultRM, status, cStatusChar);
        printf("--Error Code: %s \n", cStatusChar);
        goto Close;
    }
    else
    {
        printf("viOpen of cInstrString[100] = \"GPIB0::1::INSTR\": Opened session to the device.\n");
    }

    /*
     * Now we will close the session to the instrument using
     * viClose. This operation frees all system resources.
     */
Close:
    printf("Closing Sessions\nHit enter to continue.");
    fflush(stdin);
    getchar();
    status = viClose(instr);
    status = viClose(defaultRM);

    return 0;
}