Author Topic: Instrument control with C++  (Read 12558 times)

0 Members and 1 Guest are viewing this topic.

Offline KSPTopic starter

  • Regular Contributor
  • *
  • Posts: 98
  • Country: gb
Instrument control with C++
« on: January 12, 2015, 01:20:38 pm »
Hi all.

I have had an introduction to the C++ language and written a couple of little console apps, but my main need and interest is instrument control. Can anyone recommend any training courses (whether online or through a UK training provider) which tailor to this area? I've looked at NIs LabWindows/CVI training but obviously that  requires their libraries etc.

I just want the ins and outs of sending an receiving information via IEEE488.2, USB, Ethernet, etc. Doesn't have to be a C++ course, I'm open to suggestions, but that's all I know right now.

Any ideas?
 

Offline KSPTopic starter

  • Regular Contributor
  • *
  • Posts: 98
  • Country: gb
Re: Instrument control with C++
« Reply #1 on: January 12, 2015, 04:03:08 pm »
Thats pretty much the path I have taken so far. I have a 34410A (similar to the 01s just with more bells and whistles) and a NI USB-GPIB adaptor. Ive got it to identify itself so far using example code but then my brain melted trying to adapt the code to what I want. I figured my problem was that using someone elses code can be confusing and lead you down false paths, so I wanted an insight in how to start from scratch, but I guess I will just keep tinkering.

Cheers for the response
 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 20639
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Instrument control with C++
« Reply #2 on: January 12, 2015, 04:19:23 pm »
My preference for "experimenting" with finding out what does and doesn't work with a particular instrument is to avoid having to use the edit-compile-run pattern. Experimentation can be much faster in an interpreted environment since you simply type in your "question/experiment" and instantly see what happens. That hasn't changed since the mid/late 70s, when the Commodore PET had an IEEE488 (OK, HPIB) interface and was programmed in BASIC.

Once you have working example code, you can choose whether or not it is worth converting it to a different language, e.g. c++.

The choice of interpreted environment would probably be dictated by having the access mechanism to the bus and/or device.

There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 27943
  • Country: nl
    • NCT Developments
Re: Instrument control with C++
« Reply #3 on: January 12, 2015, 08:32:57 pm »
A much easier way is to use some SCPI console (like the one in NI's VISA full install) to test commands and implement that in your code.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline KSPTopic starter

  • Regular Contributor
  • *
  • Posts: 98
  • Country: gb
Re: Instrument control with C++
« Reply #4 on: January 13, 2015, 09:55:07 am »
I have NI VISA 488.2 installed and I have been using NI-MAX to send individual commands to the dmm, thats easy enough for me. Is that what you meant by SCPI console? Because the commands for the instrument have never been the issue, Ive been using Fluke Met/Cal for a long time and iserting instrument commands in to those programs is a piece of cake, but we are trying to move away from proprietary software. It is the C++ side of things I struggle with. Getting the program to talk to the bus is the main thing I need to understand, then sending command strings to it should be straight forward. Also receiving and interpreting the responses and saving/presenting them is something I need help with but I guess that is a tad more generic, I'm sure I can find info on saving data to files, etc.
 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 20639
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Instrument control with C++
« Reply #5 on: January 13, 2015, 10:17:41 am »
It is the C++ side of things I struggle with.

You might like to look at the C++ FQA (note, not a typo) at http://yosefk.com/c++fqa/
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline VK3DRB

  • Super Contributor
  • ***
  • Posts: 2261
  • Country: au
Re: Instrument control with C++
« Reply #6 on: January 13, 2015, 10:39:45 am »
Ideally LabWindows or Labview are the best for quick development of powerful test equipment applications, but they are hideously expensive. You might want to consider C# if it is for the Windoze platform. Or Python. Both pretty easy to learn and use. Much better than the slightly antiquated C++.

Plenty of people know how to write software, but few know how to write it properly, so check out some sites that offer tips on quality coding. Google "xxxxx coding standards", where xxxxx is the language you are interested in. Worth reading the documents that come up. Writing good quality code pays off in many ways. Bad coding can be soul destroying for anyone who has to take it over.

SCPI ("skippy") commands are worth knowing about. They make life easy for interfacing to HP/Agilent gear. Also a lot of instrument makers provide DLL's that you can call to control and get readings from an instrument. It is worth checking the websites of the instrument maker to see what support software for programming is already available.

Good luck.

 
 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 20639
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Instrument control with C++
« Reply #7 on: January 13, 2015, 01:45:52 pm »
Plenty of people know how to write software, but few know how to write it properly, so check out some sites that offer tips on quality coding. Google "xxxxx coding standards", where xxxxx is the language you are interested in. Worth reading the documents that come up. Writing good quality code pays off in many ways. Bad coding can be soul destroying for anyone who has to take it over.

Good luck.

Note that with C++ many whole books have been written on the subject - with many conflicting sets of recommendations. Think about that, and you'll realise that with C++ you need either luck or experience or both.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline KSPTopic starter

  • Regular Contributor
  • *
  • Posts: 98
  • Country: gb
Re: Instrument control with C++
« Reply #8 on: January 13, 2015, 02:26:27 pm »
Thanks guys.

Ideally LabWindows or Labview are the best for quick development of powerful test equipment applications, but they are hideously expensive. You might want to consider C# if it is for the Windoze platform. Or Python. Both pretty easy to learn and use. Much better than the slightly antiquated C++.

Plenty of people know how to write software, but few know how to write it properly, so check out some sites that offer tips on quality coding. Google "xxxxx coding standards", where xxxxx is the language you are interested in. Worth reading the documents that come up. Writing good quality code pays off in many ways. Bad coding can be soul destroying for anyone who has to take it over.

SCPI ("skippy") commands are worth knowing about. They make life easy for interfacing to HP/Agilent gear. Also a lot of instrument makers provide DLL's that you can call to control and get readings from an instrument. It is worth checking the websites of the instrument maker to see what support software for programming is already available.

Good luck.

 

You mention python... I have no experience with python but you're not the first to recommend it, do you mind elaborating on why it would be better for my needs?

And can I use NI VISA libraries with it?
 

Offline pardo-bsso

  • Regular Contributor
  • *
  • Posts: 220
  • Country: ar
Re: Instrument control with C++
« Reply #9 on: January 13, 2015, 02:58:34 pm »
Hi, I know it is not C++ but take a look at http://lantz.readthedocs.org/en/latest/
 

Offline Codemonkey

  • Regular Contributor
  • *
  • Posts: 235
  • Country: gb
Re: Instrument control with C++
« Reply #10 on: January 13, 2015, 03:10:16 pm »
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.

Code: [Select]
/****************************************************************************/
/***        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                                                   ***/
/****************************************************************************/
 

Offline Codemonkey

  • Regular Contributor
  • *
  • Posts: 235
  • Country: gb
Re: Instrument control with C++
« Reply #11 on: January 13, 2015, 03:15:04 pm »
And this is the bit that accessed the DMM (34401A). I can't post the lot but it should be enough to get you started!

Code: [Select]
/****************************************************************************
 *
 * NAME:       mRead
 *
 * DESCRIPTION:
 * Method to read from a GPIB DMM device
 *
 * PARAMETERS:  Name            RW  Usage
 *              pacMeasurement  R   DMM_MEASURE_V or DMM_MEASURE_I
 *              pacACDC         R   DMM_MEASURE_AC or DMM_MEASURE_DC
 *              pacRange        R   choose from one of the DMM_SCALE options
 *              pacResolution   R   choose form one of the DMM_RESOLUTION
 *                                  options
 *
 * RETURNS:
 * float:       Value read from the DMM
 *
 ****************************************************************************/
bool cDMM::mRead(const char *pacMeasurement, const char *pacACDC, const char *pacScale, const char *pacResolution, float *pfResult)
{
    bool bOk = TRUE;

    float fMeasurement = 0;

    char acCommand[100];

    if(!bDeviceOk){
        wxLogMessage(_T("DMM is inoperative"));
        return(FALSE);
    }

    sprintf(acCommand, "MEASURE:%s:%s? %s,%s\n",pacMeasurement, pacACDC, pacScale, pacResolution);

    bOk &= mQueryf(acCommand, (char*)"%f",&fMeasurement);

    *pfResult = fMeasurement;

    if(strcmp(pacScale, pacPreviousScale) == 0)
    {
        bScaleChanged = FALSE;
    }
    else
    {
        wxLogMessage(_T("DMM scale changed!"));

        bScaleChanged = TRUE;
    }

    pacPreviousScale = pacScale;

    return(bOk);

}
 

Offline KSPTopic starter

  • Regular Contributor
  • *
  • Posts: 98
  • Country: gb
Re: Instrument control with C++
« Reply #12 on: January 13, 2015, 03:30:47 pm »
Thank you very much for the help! Sifting through all of that on my tiny phone screen would probably drive me mad so I will check it out later.

On a side note, I've been checking out python, more specifically the use of it with pyVISA. Looks pretty comprehensive and all little more simple than C/C++ code.

My only question is creating .exe files from the python code. I've seen that there's a thing called py2exe, but in theory could I create an simple C++ program that would call and run the python code, then make a  .exe out of that? That way the guts of it is python?

May seem redundant to some but I'm just curious
 

Offline VK3DRB

  • Super Contributor
  • ***
  • Posts: 2261
  • Country: au
Re: Instrument control with C++
« Reply #13 on: January 14, 2015, 01:11:13 pm »
Thanks guys.

Ideally LabWindows or Labview are the best for quick development of powerful test equipment applications, but they are hideously expensive. You might want to consider C# if it is for the Windoze platform. Or Python. Both pretty easy to learn and use. Much better than the slightly antiquated C++.

Plenty of people know how to write software, but few know how to write it properly, so check out some sites that offer tips on quality coding. Google "xxxxx coding standards", where xxxxx is the language you are interested in. Worth reading the documents that come up. Writing good quality code pays off in many ways. Bad coding can be soul destroying for anyone who has to take it over.

SCPI ("skippy") commands are worth knowing about. They make life easy for interfacing to HP/Agilent gear. Also a lot of instrument makers provide DLL's that you can call to control and get readings from an instrument. It is worth checking the websites of the instrument maker to see what support software for programming is already available.

Good luck.

 

You mention python... I have no experience with python but you're not the first to recommend it, do you mind elaborating on why it would be better for my needs?

And can I use NI VISA libraries with it?

http://www.quora.com/What-are-the-advantages-of-Python-over-C++

He writes, "Language complexity: C++ is a beast of a language. The spec is 775 pages of language legalese, and even the best C++ developers I've known can be caught up short by unintended consequences in complex (or not so complex) code. Python is much simpler, which leads to faster development and less mental overhead."

True, but familiarity is important in quick development. A bad Labview programmer will create a mess. A good Labview programer will get a project of medium complexity up and running in no time that is easily readable. Same with LabWindows, Visual Studio, C or anything.

If you are experienced in OOP concepts and C or C# or C++, two days of learning Python and you will be hooked. Even not knowing these, in a couple of week, you'll be writing programs. There are plenty of tutorials available on the information superhighway. The only bad thing is popular microcontroller and compiler vendors do not support Python. For those I use C almost exclusively, except for the occasional in-line assembly code. Python is basically and interpreted language but you can compile it to an exe on a PC. Interpreted languages have historically been touted as crap. And they were. BASIC is one such example. Ran like a dog on old PC's, but that was years ago. Things have changed.

If running on a Windoze platform, you can easily call DLL's. An example:

Let's assume the DLL downloaded from the equipment vendor is called HP34410A.dll...

Script:

from ctypes import*
# give location of dll
testEquipmentDll = cdll.LoadLibrary("C:\\HP34410A.dll")
testEquipmentDll.SetVoltmeterRange(100)
result = testEquipmentDll.ReadVoltage()
print "Voltage = "+result

Output:
4.985


NI VISA libraries will work, called by C, C#, or C++. The VISA DLL is called visa32.dll, so you can call it with pretty much any language. But if I am not mistaken you will need to load in the big NI runtime engine and the huge device drivers library. NI is annoying in that you have to have a huge driver library with GPIB and the rest just for RS-232 port support!

Also check this out... http://pyvisa.readthedocs.org/en/master/
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf