Upload a Segment Table using C++

This example program shows the Variant method for uploading a segment sweep to the PNA using the SetAllSegments method

#include "stdafx.h"

#include <stdio.h>

#include "atlbase.h"

#include "objbase.h"


// import the PNA type library


#import "C:/Program Files/Common Files/Keysight/PNA/835x.tlb"  no_namespace, named_guids


int _tmain(int argc, _TCHAR* argv[])



  // interface pointers to retrieve COM interfaces


  IUnknown* pUnk = 0;              

  IApplication* pNA = 0;

  IChannel* pChan = 0;

  IMeasurement* pMeas = 0;

  IMeasurement5* pMeas5 = 0;

  IArrayTransfer* pTrans = 0;

  ISegments* pSeg = 0;

  ISegments2* pSeg2 = 0;


  //Variables for X and Y data read portion

  SAFEARRAY* sArray;

  _variant_t vXVals;

  double HUGEP* xVals;

  float* pScalarData;


  //Variables for Segment portion

  double Fstart, Fstop, SegWidth;

  long i[2];

  int num_points = 11;





  int NUM_SEGS = 10;

  int SEG_SIZE = 7;


  //Create SafeArray to hold the segment data

  SAFEARRAYBOUND aDim[2]; //This must be 2 the PNA expects to see a 2 dimensional array

  aDim[0].lLbound = 0;

  aDim[0].cElements = SEG_SIZE; //This will be set to 7 unless port power is uncoupled

  aDim[1].lLbound = 0;

  aDim[1].cElements = NUM_SEGS;

  pSA= SafeArrayCreate(VT_VARIANT,2,aDim);  //The cDim parameter must be set to 2 as the PNA expects a 2D array


  //Init Variant to set values in Safearray







  //Loop to write segment data

  for(int j=0; j<NUM_SEGS; ++j)


        i[1]=j; //Set Segment #


        //Segment Definition

        i[0] = 0;

        vSeg.vt = VT_BOOL; //First parameter is Boolean

        vSeg.boolVal = VARIANT_TRUE; //Segment State

        SafeArrayPutElement(pSA, i, &vSeg);

        i[0] += 1;

        vSeg.vt = VT_I4; //Second parameter is an integer

        vSeg.intVal = num_points; //Number of Points

        SafeArrayPutElement(pSA, i, &vSeg);

        i[0] += 1;

        vSeg.vt = VT_R8; //Remaining parameters are of type double

        vSeg.dblVal = Fstart+j*SegWidth; //Start Frequency

        SafeArrayPutElement(pSA, i, &vSeg);

        i[0] += 1;

        vSeg.dblVal=vSeg.dblVal+SegWidth; //Stop Frequency

        SafeArrayPutElement(pSA, i, &vSeg);

        i[0] += 1;

        vSeg.dblVal = 1.0e3; //IF Bandwidth

        SafeArrayPutElement(pSA, i, &vSeg);

        i[0] += 1;

        vSeg.dblVal = 0.0; //Dwell time

        SafeArrayPutElement(pSA, i, &vSeg);

        i[0] += 1;

        vSeg.dblVal = -5.0; //Power

        SafeArrayPutElement(pSA, i, &vSeg);



  //vSeg no longer needed, clean up



  //Declare Variant to use with Segment data



  v.parray = pSA; //write safearray to variant


  // Initialize the COM subsystem


  CoInitializeSecurity(NULL,        //security descriptor

    -1,           // authn svc entries

    NULL,         // authn svcs

    NULL,         // reserved



    NULL,         // authn info

    0,            // capabilities

    NULL);        // reserved



  // Create an instance of the network analyzer

  // Request the NA's IUnknown interface

  hr = CoCreateInstance(CLSID_Application,0,CLSCTX_ALL,IID_IUnknown, (void**) &pUnk);

  if (!FAILED(hr))


    // QueryInterface for the INetworkAnalyzer interface of the NetworkAnalyzer object

    hr = pUnk->QueryInterface(IID_IApplication,(void**)&pNA);


    if (!FAILED(hr))


      // Reset the analyzer to instrument preset



      // Create S11 measurement



      // Set pChan variable to point to the active channel



        //Show Segment table



        //Get handle to ISegments Interface



        //Get handle to ISegments2 Interface

        hr = pSeg->QueryInterface(IID_ISegments2, (void**)&pSeg2);


        //Set Segment Sweep Options

        pSeg2->IFBandwidthOption = VARIANT_TRUE;

        pSeg2->SourcePowerOption = VARIANT_TRUE;


        //Push segments to PNA



        //Set Sweep Type to Segment Sweep

        pChan->SweepType = naSegmentSweep;


        if (pChan)


        // Set pMeas variable to point to the active measurement





                  // Setup the channel for a single trigger


                  pNA->TriggerSignal = naTriggerManual;

                  pChan->TriggerMode = naTriggerModeMeasurement;


                // Make the PNA application visible



                // Send a manual trigger to initiate a single sweep



                  // QueryInterface for the IArrayTransfer interface of the NetworkAnalyzer object

                  hr = pMeas->QueryInterface(IID_IArrayTransfer,(void**)&pTrans);


                  // Get handle for IMeasurement5 interface

                  hr = pMeas->QueryInterface(IID_IMeasurement5, (void**)&pMeas5);


                  if (!FAILED(hr))


                        int val = num_points*NUM_SEGS;


                        // Store the data in the "result" variable

                        pScalarData = new float[val];

                        xVals = new double[val*2];


                        //Get X axis values



                        //Convert _variant_t array to a SAFEARRAY

                        sArray = vXVals.parray;


                        //Convert data from SAFEARRAY to double array.  Each SAFEARRAY value

                        //is 16 bytes so it takes up 2 floats so the xVals size is double

                        //the number of points.  This also means that every other data point

                        //in the resulting array can be discarded.

                        hr = SafeArrayAccessData(sArray, (void HUGEP**)&xVals);


                        //Get Measurement Values

                        pTrans->getScalar(naRawData, naDataFormat_LogMag, (long *)&val, pScalarData);


                      // Display the result

                        printf("S11(dB) - Visual C++ COM Example for PNA operating in segment sweep mode/n/n");

                        for (int j = 0; j < val; j++)


                              //Write value...the xVals array is offset by 1 in each data point since

                              //the return data is 16 bytes and each double is 8.

                              printf("%.3lf GHz, %.4f/n",xVals[2*j+1]/1e9, pScalarData[j]);









      printf("Programmed failed to connect to the PNA.");






  return 0;