Upload a Segment Table using C++


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

#include "stdafx.h"

#include <stdio.h>

#include "atlbase.h"

#include "objbase.h"

 

// import the VNA type library

//----------------------------------------------------------------------------------

#import "C:\Program Files(x86)\Common Files\Keysight\PNA\835x.tlb"  no_namespace, named_guids

 

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

{

 

  // interface pointers to retrieve COM interfaces

  HRESULT hr;

  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;

  SAFEARRAY* pSA;

  VARIANT vSeg;

  VARIANT v;

 

  int NUM_SEGS = 10;

  int SEG_SIZE = 7;

 

  //Create SafeArray to hold the segment data

  SAFEARRAYBOUND aDim[2]; //This must be 2 the VNA 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 VNA expects a 2D array

 

  //Init Variant to set values in Safearray

  VariantInit(&vSeg);

 

  Fstart=10e6;

  Fstop=3e9;

  SegWidth=(Fstop-Fstart)/NUM_SEGS;

 

  //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

  VariantClear(&vSeg);

 

  //Declare Variant to use with Segment data

  VariantInit(&v);

  v.vt = VT_ARRAY|VT_VARIANT;

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

 

  // Initialize the COM subsystem

  CoInitialize(NULL);

  CoInitializeSecurity(NULL,        //security descriptor

    -1,           // authn svc entries

    NULL,         // authn svcs

    NULL,         // reserved

    RPC_C_AUTHN_LEVEL_NONE,

    RPC_C_IMP_LEVEL_IMPERSONATE,

    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

      pNA->Reset();

       

      // Create S11 measurement

      pNA->CreateSParameter(1,1,1,1);

 

      // Set pChan variable to point to the active channel

      pNA->get_ActiveChannel(&pChan);

 

        //Show Segment table

        pNA->NAWindows->Item(1)->ShowTable((NATableType)2);

 

        //Get handle to ISegments Interface

        pChan->get_Segments(&pSeg);

 

        //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 VNA

        pSeg2->SetAllSegments(v);

 

        //Set Sweep Type to Segment Sweep

        pChan->SweepType = naSegmentSweep;

 

        if (pChan)

      {

        // Set pMeas variable to point to the active measurement

            pNA->get_ActiveMeasurement(&pMeas);

 

            if(pMeas)

            {

                  // Setup the channel for a single trigger

                  pChan->Hold(true);

                  pNA->TriggerSignal = naTriggerManual;

                  pChan->TriggerMode = naTriggerModeMeasurement;

 

                // Make the VNA application visible

                  pNA->put_Visible(true);

 

                // Send a manual trigger to initiate a single sweep

                  pChan->Single(true);

 

                  // 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

                        vXVals=pMeas5->GetXAxisValues();

 

                        //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]);

                        }

                  }

            }

      }

 

    }

    else

    {

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

    }

  }

  CoUninitialize();

 

  system("PAUSE");

  return 0;

}