Instrument Control (GPIB, Serial, VISA, IVI)

cancel
Showing results for 
Search instead for 
Did you mean: 

Measuring Agilent Power Meter using VC++

See the following C++ code:
 
 
int main(int argc, char* argv[])
{

 HRESULT hr = CoInitialize(NULL);
 if(SUCCEEDED(hr)) {
  // Create an instance of the driver
  IAgilentRFPowerMeterPtr spDrvr(__uuidof(AgilentRFPowerMeter));

  try
    {
   // Edit resouce descriptor and options for your system
   _bstr_t resourceDescriptor = "ASRL1::INSTR";
   _bstr_t driverSetupOptions = "QueryInstrStatus=true";//Simulate=true,
   // Initialize the driver, this requires the instr settings at 9600/N/8/1
   // because VisaCom Open() just passes NO_LOCK option without LOAD_CONFIG option.
   spDrvr->Initialize(resourceDescriptor, VARIANT_FALSE, VARIANT_FALSE, driverSetupOptions);
   //
   IFormattedIO488Ptr spFmtIO = spDrvr->System->IO;
   IVisaSessionPtr spVisaSession = spFmtIO->IO;
   
   IMessagePtr spMsg = spVisaSession;
   // you can optionally send BAUD 19200 command with 9600bps trafic now
   //spMsg->WriteString( "SYST:COMM:SER:BAUD 19200\n");
   //Sleep( 1000);
   ISerialPtr spSerial = spVisaSession;
   spSerial->BaudRate = 19200;

  }
  catch( _com_error e) {
   //
  }
    
 }
 if(SUCCEEDED(hr)) {
  CoUninitialize();
 }
 return 0;
}
 
This is my example that initially open the instrument with the ***DEFAULT*** serial port settings, then send SCPI's BAUD command, then change the VISA baudrate to 19200.  Sorry but I do not have a real instrument, therefore my example passes FALSE and FALSE params to the driver's Initialize() method.  But simulation is not specified. This example does not generate an COM exception.
 
But there is an important issue for using this IVI-COM driver with serial port.  As I see the SPY log, the instrument driver invokes GlobMgr's Open() method to open ASRL1::INSTR port but the driver simply passes NO_LOCK option without passing LOAD_CONFIG option.  This means the default serial port conditions are always 9600/N/8/1 even though you configure them in NI-MAX in advance.  Therefore, if you pass a VARIANT_TRUE to either bQuery or bReset parameter when Initialize() call, the driver will invoke WriteString() call with the default 9600bps for sending *IDN?, *RST, or anything else.  The only fortunate thing is, passing FALSE and FALSE to Initialize() call never invokes VISA COM WriteString() function, allowing your instrument is able to boot up with 19200bps configuration.
 
Therefore I think there are a couple ways to communicate with your instrument:
(1) Use 9600bps anytime, if you set either bQuery or bReset parameter TRUE, or
(2) Use any faster baudrate you want passing bQuery and bReset FALSE, then change the VISA baudrate after Initialize() has returned, or
(3) Use 9600bps when startup, then send SYST:COMM:SER:BAUD 19200 command on the default 9600bps trafic, then change the VISA to 19200bps in order to rendezvouz at the faster baudrate one second later.
 
However I think the 3rd approach is very risky because changing baudrate with keeping the communication established (without VISA close and re-open) may often generate a framing error, especially immediately after the baud change.
 
 
 
 
0 Kudos
Message 11 of 14
(1,999 Views)

hi..

thank u very much for ur reply... i tried what u have suggested... i am passing FALSE for bQuery n bReset.. still i am getting framing error...  

even the baud rate is not getting set to 19200 when i use ISerialPtr interface.....but there is no exception... in the next statement , i am getting the framing error in the instrument...

but the baudrate is getting set when i send the command thru IMessagePtr interface.... but here also it will throw the exception in the next statement....the same framing error in the instrument.... but in the instrument i can see the baud rate set at 19.2k.....

why is this framing error coming?... why cant we initialize the driver even after clearing this framing error(i need to power off n on to proceed, if after i changed the baud rate to 9.6k)... even the Agilent IO connectivity tool is not connecting without powering off...

we can use the message string interface instead of all other interface to send the command right?

plz see my code below

_bstr_t resourceDescriptor = "ASRL2::INSTR";
   _bstr_t driverSetupOptions = "QueryInstrStatus=true, DriverSetup= Trace=false, TraceName=TraceOut";

   // Initialize the driver
   printf("Initializing the driver\n");
   spDrvr->Initialize(resourceDescriptor, VARIANT_FALSE, VARIANT_FALSE, driverSetupOptions);

   spDrvr->System->TimeoutMilliseconds = 20000;

   // Preset the instrument
   spDrvr->System->Preset();

   //  Wait for preset to complete
   spDrvr->System->WaitForOperationComplete(20000);

      IMessagePtr spMsg = spVisaSession;
     spMsg->WriteString( "SYST:COMM:SER:BAUD 19200\n");
     Sleep( 1000);
   /*   IFormattedIO488Ptr spFmtIO = spDrvr->System->IO;
   IVisaSessionPtr spVisaSession = spFmtIO->IO;

ISerialPtr spSerial = spVisaSession;
     spSerial->BaudRate = 19200;*/

   // Select Channel A and set INIT:CONT OFF
   spDrvr->Channels->Item["A"]->Trigger->ContinuousEnabled = false;

0 Kudos
Message 12 of 14
(1,976 Views)
Changing serial baudrate at runtime without rebooting instrument and/or reopening VISA is one of risky operations. 
 
As for checking if VISA is successfully set to 19200, try to read the BaudRate property after changing it.
 
ISerialPtr spSerial = spVisaSession;
spSerial->BaudRate = 19200;
long lBaudRateToConfirm  = spSerial->BaudRate;
if the reception variable is set to 19200 after VISA call, the baudrate is successfully changed.  However, this operation often makes the bus unstable.  How about try to send a Send-Break? This must be implemented in recent VISA as the equivalent of IEEE488 device clear.  If the instrument accepts the device clear, it may cause clean up the serial FIFO including framing/parity error status.
 
ISerialPtr spSerial = spVisaSession;
IMessagePtr spMsg = spVisaSession;
spSerial->BaudRate = 19200;
long lBaudRateToConfirm  = spSerial->BaudRate;
spMsg->Clear(); // this generates a Send-Break signal
 
Anyway, assuming the approach goes well, changing the baudrate after IVI-COM's Initialize() call at 9600bps band always requires the instrument is at 9600bps whenever you call Initialize().  The IVI-COM driver's Initialize() method always assumes that the instrument is waiting for an incoming command at 9600bps band.  Therefore once the instrument is changed to 19200bps, the next Initialize() call of the instrument driver will fail because the instrument is already at 19200bps.
 
The shortcuts for solution in order to operate the driver are:
(1) Give up the faster baudrate and continue to use 9600, or
(2) Modify the driver DLL specially for CAgilentRFPowerMeter::Initialize() method, if source codes are available, or
(3) Ask Agilent for correcting the driver DLL so that it can supports faster baudrate.
 
 
 
0 Kudos
Message 13 of 14
(1,964 Views)
I have found that Agilent IO Libs Suite 14.x implicitly loads the default configurations for serial (baud/data/stop/parity/flow) even if invoking rm.Open("ASRL1::INSTR", NO_LOCK, ...).  Therefore the IVI-COM AgilentRFPowerMeter driver which internally invokes VISA Open at NO_LOCK option will start 19200bps as default if you have configured so.  No runtime modification is needed.  The configuration can be set on Agilent Connection Expert by clicking "Change Properties" button. 
 
However, this approach does not work with NI-VISA, because NI-VISA requires the VISA Open() function explicitly takes LOAD_CONFIG option if you want to apply the default settings that are configured at NI-MAX.  I believe Agilent implementation, which always attempts to load default configs without LOAD_CONFIG given may violate the VISA spec, and its behaviour is not compatible with non-Agilent VISA versions.
 
 
0 Kudos
Message 14 of 14
(1,925 Views)