cwindowsansi-cgpib

How to interface a GPIB device on a windows machine using only ansi-c


How do i open and close a connection to a GPIB device using only ANSI-C and possibly windows headers.

Is there a default way of doing this or does gpib inherently involve third party drivers?


Solution

  • Using only windows headers and ANSI C... not likely. As Adriano points out.

    The easiest way will be to use the VISA libraries. They're a standardized interface to GPIB between different manufacturers (almost)... using this library your code and resulting executable won't care whose VISA implementation your using (example caveats linked to below)...

    You will need to link against visa32.lib. This can be found in the directory $(VXIPNPPATH)/WinNT/lib/msc. The variable VXIPNPPATH, I think is setup by default to point you at C:\Program Files (x86)\IVI Foundation\VISA\ or the equivalent on a 32-bit machine.

    Header files for the C VISA library can then be found at $(VXIPNPPATH)/WinNT/include

    Note, depending on who's VISA library you have installed cross-manufacturer use of GPIBs you might need to do some config. For example, when using NI's library to successfully connect to Agilent devices you have to enable the option described in this article.

    I know NI have some example programs you can look at. A general example to open and close a device might look something like...

    ViStatus status;
    ViChar buffer[80];
    unsigned int board = 0, device = 10;
    
    /* Open the default resource manage */
    status = viOpenDefaultRM(&mVisaDefaultRM);
    if (status < VI_SUCCESS)
        exit(-1);
    
    /* Construct a string describing the GPIB device to open and open it! */
    sprintf(buffer, "GPIB%u::%u::INSTR", board, device);    
    status = viOpen(mVisaDefaultRM, buffer, VI_NULL, VI_NULL, &mVisaInst);
    if (status < VI_SUCCESS)
    {
        viClose(mVisaDefaultRM);
        exit(-1);
    }
    
    /* Close it */
    viClose(mVisaInst);
    viClose(mVisaDefaultRM);
    

    You can then do all sorts with the rest of the API... for example, to reset the device you might write something like...

    /* Reset the device */
    status = viEnableEvent(mVisaInst, VI_EVENT_SERVICE_REQ, VI_QUEUE, VI_NULL);
    if( status >= VI_SUCCESS )
    {
        /* Send SDC (Selected Device Clear) to reset the information interchange 
         * between controller and instrument. 
         * Cleans input and output buffer, aborts operations that prevent 
         * processing of new commands etc. */   
        status = viClear(mVisaInst); 
        if (status >= VI_SUCCESS)
        {
            /* If the SDC successed progress onto reset the device and set it 
             * up for detecting SRQ events... */
            Write("*CLS;");     /* Clear status command. Clears the whole status structure */
            Write("*RST;");     /* Reset command. Abort all activities and initialise the device (instrument specific) */
            Write("*SRE 255;"); /* Service request enable. Disable all service requests except ESB: 0010_0000 */
            Write("*ESE 255;"); /* Standard event status enable. Disable all statuses except the errors and op complete: 0011_1101 */                   
        }
    }
    
    if (status < VI_SUCCESS)
    {
        /* Do something */
    }
    

    An example of the National Instruments VISA API doc can be found here. I'm sure Agilent and other folks must have their versions too. They key thing is that you code and resulting EXE should not care who's implementation is being used...

    A final little link... I found this GPIB programming tutorial to be really useful...