Instrument Control (GPIB, Serial, VISA, IVI)

cancel
Showing results for 
Search instead for 
Did you mean: 

How are ivi-com drivers interchangeable? Confused!

I am developing a c++ measurement studio application to use IVI scope and Fgen drivers defined at runtime using MAX, so that instruments are truly interchangeable, and new instruments can be added without code changes. This works fine with IVI-c drivers.

However, I'm struggling to get one function in the ivi-c driver for agilent 33220a to work correctly, so I (naively) downloaded the IVI-com driver provided by agilent. After also installing visa-com as a secondary visa driver, I patched this ivi driver in MAX (it does see this ivi-com driver). Using the logical name tied to this driver in my application, unfortunately, it doesn't work - I get a 'File not found' from the IVI engine.

I am aware there are big differences in architecture between ivi-c and ivi-com. Looking at the documentation and examples which came with the ivi-com driver, the driver is imported specifically into the code using a #import specificivicom.dll directive. The examples then show control of the device using a smart pointer to the specific com object (understandable being a com object).

What I don't understand is how this is interchangeable in any way if it has to be hard coded in?

Do the c++ wrapper classes (eg CNiIviScope and CNiIviFgen) only work with ivi-c drivers? Is there an equivalent for ivi-com?

Can you actually talk to instruments via IVI com drivers setup in MAX?

How can I use an IVI-com driver interchangeably? As an end user I'm not really interested in driver architecture - I just want to get on and use them!

(I asked this question briefly part way through another post-no reply yet. Apologies for cross-posting, but I figured this is worth a post of it's own).
Many thanks
0 Kudos
Message 1 of 10
(6,618 Views)
I think I may be getting somewhere... this from the IVI-COM driver reference:

For now, assume the Configuration Store contains an IVI Session whose name is DMM and which points to an Agilent34401 SoftwareModule. You can create a driver with this code:

IAgilent34401Ptr spDmm;
IIviSessionFactoryPtr spFactory(__uuidof(IviSessionFactory));
spDmm = spFactory->CreateDriver("DMM");

The first statement declares a smart pointer without actually creating an object because the constructor is not passed any parameters; its value is NULL. You must create an actual instance of the IVI Session Factory as is done with the second statement. A smart pointer is used for the factory. The assignment statement invokes the IVI Session Factory's CreateDriver method, which looks up the string, DMM, in the Configuration Store to find a Driver Session or Logical Name. The IVI Session Factory creates an instance of the object, queries the object to make sure it is the same type as spDmm, and finally sets spDmm's value so it points to the newly created object. This spDmm object is identical to the one created using the constructor technique.

If the application accesses only the IVI class-compliant capabilities of the driver, the first statement can be changed to:

IIviDmmPtr spDmm; // *** IS THIS THE KEY?***

This smart pointer, spDmm, has access to only the class compliant interfaces exposed by the driver.

Looks hopeful, BUT WHERE IS IIVIDMMPTR DEFINED. What DO i need to import to use this. Is this the same for all IVI-com drivers, or is it agilent sprcific?
I ONLY NEED THE CLASS COMPLIANT INTERFACE

ALSO, HOW DO QUERY THE CONFIG STORE TO FIND OUT WHETHER I HAVE AN IVI_C OR IVI COM driver?
0 Kudos
Message 2 of 10
(6,607 Views)
Hi Dr Jonno,
Unfortunately, IVI-C and IVI-COM drivers do not work well together in an interchangeable manner and this is not something that is easy to do.  Since an IVI-C driver is available, my first recommendation is to use it.  If there is a problem with a class defined function in the 33120 IVI-C driver, please report this and we will do our best to get it fixed quickly.
 
The C++ wrappers for the IVI-C classes only work with IVI-C drivers.  NI has prototyped COM adapters for some classes that will allow the C++ wrapper to call an IVI-COM driver through the the IVI-C class and COM adapter.  Again, the most ideal approach is to use the existing IVI-C driver as the adapter approach adds a potential layer of complexity.
 
If you are still interested in getting C and COM drivers working together interchangeably, I can provide you with the appropriate COM adapter.  You should understand that support for this approach will be limited as it is something that has had limited usage and may not be ideal in practice.
 
Jason Hobbs
Instrument Drivers
0 Kudos
Message 3 of 10
(6,601 Views)
The type library information for IIviDmm interface is embedded in IviDmmTypeLib.DLL
located at /Program Files/IVI/BIN directory.  You can just #import the DLL.
 
Other cases are also true - IviScopeTypeLib.DLL, IviSpecAnTypeLib.DLL,etc...
The IVI-COM common interfaces can be imported from IviDriverTypeLib.DLL.
 
All the above DLLs are installed as parts of IVI Shared Components, which
are also bundlled in NI IVI Compliance Package 2.x, or Agilent IO Libraries
Suite 14.x.
 
makoto
0 Kudos
Message 4 of 10
(6,592 Views)
Thanks to you both for your help.
PLEASE COULD YOU LET ME KNOW HOW TO GET THESE COM ADAPTERS.

I eventually discovered that there is a class-compliant set of function calls for ivi-com, as well as the instrument specific. ANd indeed I was able to use these by:

#import "C:\Program Files\IVI\Bin\IviDriverTypeLib.dll" no_namespace
#import "C:\Program Files\IVI\Bin\IviFgenTypeLib.dll" no_namespace
#import "C:\Program Files\IVI\Bin\IviSessionFactory.dll" no_namespace

NOTE that there is also an IviDriverTypeLib.dll in the national instruments\ivi directory. BUT the NI implementation does NOT seem to have the following pointer objects, which allow you to do the class-compliant stuff:

IIviFgenPtr spFgen;
IIviSessionFactoryPtr spFactory(__uuidof(IviSessionFactory));
spFgen = spFactory->CreateDriver("logical_name_from_MAX");
spFgen->Initialize("logical_name_from_MAX",VARIANT_TRUE,VARIANT_TRUE,"");

With the above, you can then work with spFgen (smart pointer to Fgen), just as you would a CNiIviFgen object. There are, of course, annoying syntactic differences and omissions between the ivi-c and ivi-com classes. For example, there is no Arbitrary->waveform->sethandle function in ivi-com, you have to use configure instead. You also seem to have to mess around with horrible SAFEARRAYs in ivi-com 😞

However, the ClearMemory function in ivi-com DOES work for my application. WHERE DO I REPORT ERRORS/OMISSIONS for IVI-C drivers?

SO one plan would be to find a way to query the config store to check the driver is IVI-C (probably worth doing anyway, even if not implementing ivi-com) and go to ivi-c or ivi-com handling code - relatively easy for my application, but yuk. It seems like the ivi c++ classes fell at the last hurdle. Surely the logical thing would for NI to have CNiIviFgen class as an abstract base class, and have CNiIviCFgen and CNiIviCOMFgen derived classes and build the correct derived class at runtime.
I am hoping that's what the COM adapter will do which Jason kindly said he could send me. It seems crazy that this has not been implemented fully for the class-complient level functionality. Surely that would avoid this big ivi-c vs ivi-com split?

THanks again
0 Kudos
Message 5 of 10
(6,571 Views)

You can report issues with instrument drivers developed by National Instruments by sending an email to:

instrument.drivers@ni.com

 

Please also send an email to this address to request the IVI-COM class driver adapters.

0 Kudos
Message 6 of 10
(6,554 Views)

If your program wants to distinguish IVI-COM and IVI-C drivers you are using, you can access the IVI Config Store contents through the IviConfigServer DLL.  Here is a VC++ example that identifies the IVI driver type (COM or C) from a given Logical Name - "MyInstr" in this case.

// Add this line in the stdafx.h
#import "C:\Program Files\IVI\Bin\IviConfigServer.dll" no_namespace named_guids

...

 IIviConfigStorePtr spCs;
 hr = ::CoCreateInstance(
  CLSID_IviConfigStore,
  NULL,
  CLSCTX_ALL,
  IID_IIviConfigStore,
  (void**)&spCs);


 try {
  // Load the master config XML
  spCs->Deserialize( spCs->MasterLocation);

  // Get interface for the logical name "MyInstr"
  IIviLogicalNamePtr spLn = spCs->LogicalNames->Item[L"MyInstr"];

  // Get interface for the driver session
  IIviDriverSessionPtr spDs = spLn->Session;

  // Get interface for the software module
  IIviSoftwareModulePtr spSm = spDs->SoftwareModule;

  // Acquire the prefix, module-path, progID strings
  _bstr_t strPrefix = spSm->Prefix;
  _bstr_t strModulePath = spSm->ModulePath;
  _bstr_t strProgID = spSm->ProgID;

 }
 catch( _com_error e) {
 }

When IVI-C, you can get a valid ModulePath string such as "<prefix>_32.DLL" and an empty ProgID.  When IVI-COM, you can get a valid ProgID string such as "Agilent.<componentidentifier>" and an empty ModulePath.  Through the IIviSoftwareModule interface, you can acquire more useful information about the software module associated with the given Logical Name.

 

このメッセージは 10-07-2005 10:28 AMに Makoto が編集しています。

このメッセージは 10-07-2005 10:28 AMに Makoto が編集しています。

0 Kudos
Message 7 of 10
(6,543 Views)
Hi Can i know how to configure the Logic name using the IVI API with out using MAX tool
0 Kudos
Message 8 of 10
(5,676 Views)

parthipan,

 

Go to www.ivifoundation.org and download the IVIConfigurationServer spec (IVI 3.5). Towards the end is a VB6 example of doing what you want.

0 Kudos
Message 9 of 10
(5,645 Views)

Hi,

 

  I need it in c#

 

Regards

Parthipan

0 Kudos
Message 10 of 10
(5,642 Views)