I've used the NI VISA library for instrument control in a C++ application and found it really easy to use. I'm not doing anything too interesting, just control of a DMM, frequency counter, Power meter and switchable attenuators.
Below is the bit of code that calls the visa functions. Its part of a larger application built with the Wx framework so you'd need to convert obvious stuff like WCHAR to char etc.
/****************************************************************************/
/*** Include files ***/
/****************************************************************************/
#include "GpibDevice.h"
#include <wx/wx.h>
#include <wx/string.h>
#include <wx/log.h>
#include <wchar.h>
#include "visa.h"
/****************************************************************************
*
* NAME: cGpibDevice
*
* DESCRIPTION:
* Constructor for the cGpibDevice class
*
* PARAMETERS: Name RW Usage
* name R description goes here
*
* RETURNS:
* void
*
****************************************************************************/
cGpibDevice::cGpibDevice(void)
{
bDeviceOpen = FALSE;
}
/****************************************************************************
*
* NAME: ~cGpibDevice
*
* DESCRIPTION:
* Deconstructor for the cGpibDevice class
*
* PARAMETERS: Name RW Usage
* name R description goes here
*
* RETURNS:
* void
*
****************************************************************************/
cGpibDevice::~cGpibDevice(void)
{
}
/****************************************************************************
*
* NAME: mGpibOpen
*
* DESCRIPTION:
* Method to open a GPIB connection
*
* PARAMETERS: Name RW Usage
* iAddress R Address of GPIB device
* iTimeout R Timeout time
*
* RETURNS:
* bool: TRUE if the device was opened ok
* FALSE if something went wrong
*
****************************************************************************/
bool cGpibDevice::mGpibOpen(int iAddress, int iTimeout)
{
bool bOk = TRUE;
ViStatus viError;
char acBuff[200];
WCHAR wcBuff[200];
WCHAR wcManufacturer[100];
WCHAR wcModel[100];
/* construct the device id string */
sprintf(acBuff, "GPIB0::%d::INSTR",iAddress);
/* If the device is already opened, close it first */
if(bDeviceOpen){
mClose();
}
/* Open session to GPIB device at the given address */
viError = viOpenDefaultRM(&defaultRM);
if(viError != VI_SUCCESS) bOk &= FALSE;
viError = viOpen(defaultRM, acBuff, VI_EXCLUSIVE_LOCK, iTimeout, &vi);
if(viError != VI_SUCCESS) bOk &= FALSE;
viError = viSetAttribute(vi, VI_ATTR_TMO_VALUE, iTimeout);
if(viError != VI_SUCCESS) bOk &= FALSE;
bDeviceOpen = TRUE;
if(!bOk){
wxLogMessage(_T("GPIB device failed to open on address %i"),iAddress);
return(FALSE);
}
/* Initialise the device */
bOk &= mPrintf((char*)"*RST\n");
/* Send an *IDN? string to the device and read the results */
bOk &= mQueryf((char*)"*IDN?\n", (char*)"%t", acBuff);
if(bOk){
/* convert the results to unicode */
wxMB2WC(wcBuff, acBuff, sizeof(acBuff));
/* Get the manufacturer name */
wcscpy(wcManufacturer, wcstok(wcBuff, _T(",")));
/* Get the model name */
wcscpy(wcModel, wcstok(NULL, _T(",")));
wxLogVerbose(_T("GPIB device %s %s opened on address %i"),wcManufacturer, wcModel, iAddress);
} else {
wxLogVerbose(_T("GPIB device opened on address %i"), iAddress);
}
return(TRUE);
}
/****************************************************************************
*
* NAME: mClose
*
* DESCRIPTION:
* Method to close a GPIB connection
*
* PARAMETERS: Name RW Usage
* iHandle R Handle for the device we want to close
*
* RETURNS:
* void
*
****************************************************************************/
void cGpibDevice::mClose(void)
{
/* Close session */
viClose(vi);
viClose(defaultRM);
bDeviceOpen = FALSE;
}
/****************************************************************************/
/*** Local Functions ***/
/****************************************************************************/
/****************************************************************************
*
* NAME: mPrintf
*
* DESCRIPTION:
* Method to write to a GPIB device
*
* PARAMETERS: Name RW Usage
* acWriteMessage R Message to write to the GPIB device
* ... R variable number of arguments
*
* RETURNS:
* bool: TRUE if the message was written ok
* FALSE if something went wrong
*
****************************************************************************/
bool cGpibDevice::mPrintf(char *acWriteMessage, ...)
{
ViStatus viError;
va_list args;
va_start(args, acWriteMessage);
viError = viVPrintf(vi, acWriteMessage, args);
va_end(args);
if(viError == VI_SUCCESS){
return(TRUE);
} else {
return(FALSE);
}
}
/****************************************************************************
*
* NAME: mScanf
*
* DESCRIPTION:
* Method to read from a GPIB device
*
* PARAMETERS: Name RW Usage
* acReadMessage R format specifier string for data to read
* ... R variable number of arguments
*
* RETURNS:
* bool: TRUE if the data was read ok
* FALSE if something went wrong
*
****************************************************************************/
bool cGpibDevice::mScanf(char *acReadMessage, ...)
{
ViStatus viError;
va_list args;
va_start(args, acReadMessage);
viError = viVScanf(vi, acReadMessage, args);
va_end(args);
if(viError == VI_SUCCESS){
return(TRUE);
} else {
return(FALSE);
}
}
/****************************************************************************
*
* NAME: mQueryf
*
* DESCRIPTION:
* Method to read from a GPIB device
*
* PARAMETERS: Name RW Usage
* acReadMessage R format specifier string for data to read
* ... R variable number of arguments
*
* RETURNS:
* bool: TRUE if the data was read ok
* FALSE if something went wrong
*
****************************************************************************/
bool cGpibDevice::mQueryf(char *acWriteMessage, char *acReadMessage, ...)
{
ViStatus viError;
va_list args;
va_start(args, acReadMessage);
viError = viVQueryf(vi, acWriteMessage, acReadMessage, args);
va_end(args);
if(viError == VI_SUCCESS){
return(TRUE);
} else {
return(FALSE);
}
}
/****************************************************************************/
/*** END OF FILE ***/
/****************************************************************************/