Skip to content

IVI.NET Driver Walkthrough

In this walkthrough, you will create a simple IVI.NET driver along with a help file and installer.

This walkthrough will consist of the following nine main steps:

  1. Creating the IVI.NET driver project
  2. Defining an enumerated type
  3. Adding a method
  4. Implementing a method using the Instrument Command Editor
  5. Adding a property that uses an enumerated type
  6. Building the driver
  7. Testing the driver
  8. Creating the help file
  9. Creating the driver installer

Creating the IVI.NET Driver Project

We’ll create a new driver project called Acme4321. Nimbus is completely integrated with Microsoft Visual Studio, so the process of creating an IVI.NET driver project begins with the same steps required to create any Visual Studio project.

  1. Open Visual Studio.

  2. From the File menu, choose New Project.

  3. Select IVI.NET Projects from the list of installed project templates shown on the left.

  4. Select IVI.NET Driver from the list of project types shown on the right.

  5. In the Name box, enter Acme4321.

  6. Click Next.

    The IVI.NET Driver Wizard appears.

  7. On the General Page, specify the following:

    • For Instrument manufacturer, enter Acme Corporation.
    • For Driver vendor, enter Pacific MindWorks.
    • For .NET assembly name prefix, enter Acme.
    • For Instrument model, enter Acme4321.
  8. Press Next.

  9. On the IVI Instrument Classes Page, leave all instrument classes unchecked.

  10. Press Next.

  11. On the LXI Compliance Page, select the None radio button.

  12. Press Next.

  13. On the Projects Page, check each of the available project types except Create IVI.NET Visual Basic console application.

  14. Click Finish to create the project.

    The Visual Studio Solution Explorer will automatically open, showing each of the following projects:

    • Acme4321

      This is the Nimbus Project, which manages each of the other related projects in the solution for this driver.

    • Acme4321CsConsoleApplication

      A sample C# console application that can be used to exercise the driver, or be released as sample code.

    • Acme4321Driver

      The standard C# class library assembly project that will contain all of the code for this driver.

    • Acme4321Help

      The driver help project that will build the help file(s) for this driver.

    • Acme4321Setup

      The driver setup project that you’ll use to customize and build the installer for the driver.

    • Acme4321UnitTest

      The standard Visual Studio unit test project that will be used to test the driver.

  15. In the Solution Explorer, double click the Driver Designer node that’s displayed under the Acme4321 Nimbus Project.

    The Nimbus driver designer appears.

Defining an Enumerated Type

Enumerated types are commonly used as property types and parameter types. Nimbus provides special support for defining enums and using them in method and property instrument commands.

  1. Expand the Acme.Acme4321 assembly node in the driver designer. This will reveal the following child nodes:

    • Hierarchy

      This is the main designer node under which most of the driver modifications described below will be performed.

    • Interfaces

      This node lists the interfaces defined in the driver assembly.

    • Classes

      This node lists the classes defined in the driver assembly.

    • Structs

      This node lists the structures defined in the driver assembly.

    • Delegates

      This node lists the delegates defined in the driver assembly.

    • Enums

      This node lists the enumeration types defined in the driver assembly. You’ll be using this momentarily to define a custom enum.

    • Exceptions

      This node lists the exception classes defined in the driver assembly.

  2. Right-click on the Enums node and choose Add Enum.

    A new enum node is added with a default name and the node enters edit mode.

  3. For the name, simply enter TriggerSource and hit Enter.

  4. We need to add three enum members to the TriggerSource. Right-click on the TriggerSource and choose Add Enum Member.

    A new enum member is added to the enum with a default name and the enum member enters edit mode.

  5. Enter Internal for the member name and hit Enter. This will complete the addition of the new enum member, and display the Enum Member Editor.

  6. Enter INT for the Command value shown in the Enum Member Editor. This value will be used by Nimbus whenever automatic instrument command formatting is leveraged by the driver developer.

  7. Right-click again on the TriggerSource and add an enum member named External. Set its instrument Command value to EXT.

  8. Finally, add an enum member named Software. Set its instrument Command value to SW.

Adding a Method

When you add new functionality to a driver, you organize the methods and properties in a hierarchy, which corresponds to interfaces that Nimbus will create and manage.

To add a Configure method with parameters:

Section titled “To add a Configure method with parameters:”
  1. Expand the Hierarchy node in the driver designer to reveal the methods and properties already added to your driver by Nimbus when the driver solution was created.

    Methods and properties shown greyed out indicate that they cannot be modified. This is because those methods and properties are inherited from the IVI-defined IIviDriver interface.

  2. Right-click on the Hierarchy node and choose Add Method.

    A new method node is added to the hierarchy with a default name, and the node enters edit mode.

  3. Enter the following as the name and signature of the new method and then press the Enter key:

    Configure(int numRecords, bool enabled)

  4. Expand the newly created Configure node and notice that Nimbus automatically created both the numRecords and enabled parameters requested above.

  5. Right-click on the Configure method node and select Add Parameter.

    A new parameter node is added to the Configure method with a default name, and the node enters edit mode.

  6. Enter the following as the name and signature of the new parameter and then press the Enter key:

    source : TriggerSource

    If you are prompted to resolve the ambiguity between two different TriggerSource types, pick the instrument-specific one — the one defined in the Acme4321 assembly.

Implementing a Method Using the Instrument Command Editor

Although Nimbus supports developing drivers for any type of instrument — register-based, message-based, or custom I/O devices, special features are provided that make message-based IVI.NET driver development particularly efficient. Every method or property can be implemented by associating an instrument command with the method or property. Nimbus can be instructed to automatically format the runtime value of method parameters into the instrument command string. This section of the walkthrough will present some of the automatic instrument command formatting features provided by Nimbus.

To implement a method using an instrument command:

Section titled “To implement a method using an instrument command:”
  1. Select the Configure method node in the IVI.NET Driver Designer.

  2. From the Item Editor, change the Implementation style to be Instrument Command. This enables the Command text box.

  3. In the Command text box, enter the following command (although you could copy/paste this command, don’t do so at this time so that a feature of this editor can be demonstrated):

    ACQ:CONFIG {numRecords},{enabled}; TRIG:SOUR {source}

    The above command uses parameter tags enclosed in curly braces ({ }) to insert the runtime value of parameters into the command. Notice that when you type a left curly brace ({), Nimbus presents an IntelliSense context menu from which you can select the desired parameter to use in the instrument command.

  4. Right-click on the Configure method node and select Go to Implementation.

    Nimbus will open the source file containing the method’s implementation (Acme4321.cs), and then navigate to the location within that source file where that method resides. It should look as shown below:

    [DriverMethod]
    public void Configure(int numRecords, bool enabled, TriggerSource source)
    {
    if (this.Session.InitOptions.SimulationEnabled)
    {
    throw new NotImplementedException(); // TODO
    }
    this.IO.FormattedIO.PrintfAndFlush("ACQ:CONFIG %d,%s; TRIG:SOUR %s", numRecords, enabled, source);
    }
  5. The implementation of the Configure method needs to be modified so that it works in simulation mode — that is, when no device is physically available. (This is important for steps later in this walkthrough.) The driver designer has already generated the code necessary to test the SimulationEnabled property, which will return true if the driver is being used in simulation mode. But the designer has left the remainder of the simulation-mode implementation for the developer to complete. Since the designer doesn’t know what’s appropriate, it always generates code to raise a NotImplementedException exception. All we need to do is replace the boilerplate code with something more appropriate.

    Delete the TODO comment and replace the throw new NotImplementedException(); statement with a simple return; statement. These changes allow the Configure method to operate when the driver is used in simulation mode.

    The Configure method should now look as follows:

    [DriverMethod]
    public void Configure(int numRecords, bool enabled, TriggerSource source)
    {
    if (this.Session.InitOptions.SimulationEnabled)
    {
    return;
    }
    this.IO.FormattedIO.PrintfAndFlush("ACQ:CONFIG %d,%s; TRIG:SOUR %s", numRecords, enabled, source);
    }
  6. Each parameter used in the instrument command is formatted according to its data type and Nimbus configuration options. Note that the numRecords parameter will be formatted using the %d format specifier, while both the enabled and source parameters will be formatted using the %s format specifier.

  7. Because the source parameter is an enumerated type (TriggerSource), the Command values previously configured for each of its three enum members will be sent to the instrument based on the value of the source parameter. For example, if the source parameter value is TriggerSource.External, the instrument command value will be TRIG:SOUR EXT.

    The formatting used for numeric and boolean values is configured at the Nimbus project level.

    Right click on the Acme4321 project in the Solution Explorer and select Driver Settings Editor. This will display the IVI.NET Driver Settings.

  8. Click on the I/O tab. This will display the instrument command formatting editor.

  9. Note that format specifiers for integer and floating point data types have been provided (%d and %0.15g, respectively). Also note that the default values to use for booleans have been provided (1 and 0 for true and false, respectively).

    Change the Boolean True field from 1 to ON.

    Change the Boolean False field from 0 to OFF.

Adding a Property That Uses an Enumerated Type

Enumerated types are commonly used as property types as well as for parameter types.

  1. We’ve already defined the TriggerSource enum type, so to define a property that uses that type, simply right-click on the Hierarchy node in the driver designer, and select Add Property.

    Enter the following and then press the Enter key:

    SweepSource : TriggerSource

    The General tab of the property item editor will appear to the right.

  2. With the SweepSource property selected in the tree view, change the Implementation style in the Item Editor to Instrument Command.

  3. For the Setter command, enter the following command that will be sent to the device when the property value is written:

    TRIG:SOUR {value}

    For the Getter command, enter the following query that will be sent to the device when the property value is read:

    TRIG:SOUR?

    The setter command instructs Nimbus to take the value of the property and place it in the command in place of the {value} parameter tag. For reads from the instrument, first the Getter command is sent, and then Nimbus reads from the device and parses the response according to the Getter response specified. For the SweepSource property, leave the Getter response set to {value}, which simply means that the device responds by sending a value that Nimbus will parse into one of the allowed TriggerSource values.

  4. Right click on the newly created SweepSource property node in the driver designer and select Go to Implementation. Nimbus should navigate you to the implementation of the new SweepSource property, which should look as follows:

    [DriverProperty]
    [Simulation(SimulationMode.LastValue, Default = "Internal")]
    public TriggerSource SweepSource
    {
    get
    {
    this.IO.FormattedIO.PrintfAndFlush("TRIG:SOUR?");
    Acme.Acme4321.TriggerSource value;
    this.IO.FormattedIO.Scanf("%s", out value);
    return value;
    }
    set
    {
    this.IO.FormattedIO.PrintfAndFlush("TRIG:SOUR %s", value);
    }
    }

    Note that, unlike it did for the Configure method, the Nimbus driver designer did not generate any boilerplate code that needs to be replaced before using this property. The implementation of both the property getter and setter is completely filled in and requires no further updates.

    Furthermore, simulation support has been enabled by default via the use of the SimulationAttribute attribute. This is accomplished automatically by the Nimbus code weaver.

Building the Driver

  1. The first step in compiling a Nimbus driver is properly setting the build configuration. This only has to be done once the first time a new driver project is created, and is described in more detail here.

  2. From Solution Explorer, right click on the solution and choose Configuration Manager. The Configuration Manager Dialog Box appears.

  3. From the Active solution platform combo box, choose <Edit…>. The Edit Solution Platforms dialog box appears.

  4. The following shows the list of platforms will be listed:

    • Any CPU
    • Mixed Platforms
    • x64
    • x86
  5. Remove all platforms except for Mixed Platforms.

  6. Close the Edit Solution Platforms dialog.

  7. Back in the Configuration Manager dialog, make sure that the Platform column setting and Build column setting for each project is set according to the table below.

    ProjectPlatformBuild
    Acme4321CsConsoleApplicationx86Checked
    Acme4321DriverAny CPUChecked
    Acme4321HelpAny CPUUnchecked
    Acme4321Setupx86Unchecked
    Acme4321UnitTestAny CPUChecked
  8. After making the above changes to both the Debug and Release configurations, close the Configuration Manager dialog.

  9. Make sure Mixed Platforms is selected in the Solution Platforms combo box.

    Also make sure Debug is selected in the Solution Configurations combo box.

  10. From the Build menu, select Build Solution. You can also initiate the build by right-clicking on the Solution node in the Solution Explorer and choosing Build Solution.

  11. The driver is now ready to use in an application. The build process automatically registers the driver with the IVI Configuration Store. You can use a 3rd-party IVI browser, such as Measurement Automation Explorer® (MAX) from National Instruments® to view the IVI Configuration Store.

Testing the Driver

Nimbus-generated driver unit test projects integrate directly into Visual Studio’s unit testing environment. As you use the Nimbus driver designer, Nimbus creates, deletes and updates unit test methods for each driver method, property and event, which can then be executed using Visual Studio’s unit testing framework.

  1. From the Visual Studio Test menu, choose Windows and then select Test View.

  2. The Test View window appears docked within Solution Explorer, and will display all of the unit test methods Nimbus has already created for the driver.

    Pull down the Group By combo box within the Test View and select Class Name. This will organize the unit test methods according to the unit test classes in which those test methods are defined. Nimbus creates one unit test class per interface defined within the driver project. The following unit test classes should be visible:

    • IAcme4321Test
    • IIviDriverIdentityTest
    • IIviDriverOperationTest
    • IIviDriverTest
    • IIviDriverUtilityTest
  3. Expand the test class node for the IAcme4321Test class, right-click on the SweepSource property and choose Open Test.

  4. Nimbus navigates to the C# unit test method for the SweepSource property. The test code for this method sets the value of the property, reads back the value in the instrument, and then compares the value set to the value read to ensure that the property worked. It repeats this sequence for each of the three members of the TriggerSource.

    Also note that the unit test method has a [TestMethod] attribute applied. This is a standard Visual Studio attribute that Nimbus uses to mark this method as a unit test method for the Visual Studio unit testing engine.

  5. Go to the top of the IAcme4321Test test class source file.

    Notice that the following two methods are defined: _Init, and _Close. The _Init method has a [TestInitialize] attribute applied, and the _Close method has a [TestCleanup] attribute applied. Those attributes are standard Visual Studio attributes that instruct the Visual Studio unit test engine to invoke those methods before and after each unit test method is executed.

    The _Init and _Close methods do most of their work by delegating to the implementation of implementation inherited from their base class, BaseTest.

  6. Right-click on the BaseTest base class and click Go To Definition. This will take you to the core implementation of the _Init and _Close methods.

  7. Typically, within the _Init, the logicalName variable is set to a valid I/O resource descriptor or to a valid logical name configured in the IVI Configuration Store. For purposes of this walkthrough, we can leave the value of the logicalName as it was set when Nimbus created the unit test project (Acme4321UnitTest), as we will be operating the driver in simulation mode.

    Modify the initOptions variable to run the driver in simulation mode by changing the value of the Simulate operation to True, as shown below:

    var initOptions = "QueryInstrStatus=True, Simulate=True, DriverSetup= ";
  8. From the Build menu, choose Build Acme4321UnitTest.

  9. From the Test View, right-click the IAcme4321UnitTest node and choose Run Selection.

    The Test Results View opens in the lower portion of the Visual Studio IDE, and shows the status of the unit test methods as they execute. Verify that the SweepSource and Configure_Int32_Boolean_TriggerSource unit tests passed.

  10. Return to the Test View and select all 5 unit test classes. Right-click on any one of them and choose Run Selection. This will execute the entire suite of unit test methods that Nimbus has generated for the driver, which includes working code for all of the IVI inherent capabilities.

    You should expect the Test Results window to list the following 3 unit test methods as having failed. The Error Message column next to each should indicate that each test failed because the test is not implemented.

    • Warning
    • InterchangeCheckWarning
    • Coercion
  11. Right-click on the Warning test in the Test Results view and select Open Test. This will take you to the location of the Nimbus-generated unit test method for the Warning event defined on the IVI.NET-defined IIviDriverOperation interface.

    Because Nimbus doesn’t know how to appropriately implement a unit test for the Warning event, it generates the following boilerplate implementation:

    [TestMethod]
    public void Warning()
    {
    Assert.Fail("Test not implemented.");
    }

    Note that the Coercion and InterchangeCheckWarning unit test methods are similarly implemented.

  12. For the purposes of this walkthrough, simply delete the call to Assert.Fail from the Warning, Coercion and InterchangeCheckWarning unit test methods. Each of those unit test methods should now be empty.

  13. In the Test Results view, click the Run button. Because you’ve made a change to the unit test source code, Visual Studio will automatically rebuild the unit test project, and then execute just the 3 unit test methods that failed. They should now pass.

Creating the Help File

Nimbus provides powerful and flexible features for creating driver help files. Help file templates allow complete control over help file styling and content so that custom branding and other styling requirements can easily be incorporated.

One of the most compelling aspects of the Nimbus help editing features is that they provide a single place to enter help content that is used in many places. This greatly simplifies driver documentation management. For instance, the Summary field in the Help Editor is used in all of the following places:

  • Automatically generated XML documentation files for IntelliSense support in .NET languages, such as C# and Visual Basic.
  • Microsoft Help Viewer help content (for use with the Visual Studio).
  • The Help 1.0 (.chm) help file (for standalone viewing and viewing in non-Microsoft IDEs).
  1. From the IVI.NET Driver Designer, select the Configure method.

  2. Click on the Help tab at the bottom of the Item Editor to bring up the Help Editor.

    The Summary tab (listed at the top of the Item Editor) should be the active tab.

  3. Enter the following in the Summary field:

    Configures the device acquisition.

  4. Click on the Remarks tab. This will activate the standard Visual Studio HTML editor. The HTML editor allows use of any arbitrary HTML formatting tags.

    In the HTML editor for the Remarks field, enter the following within the \<body\> tag that’s already been provided:

    <p>
    This method configures the device acquisition.
    </p>
    <p>
    Call the <b>Configure</b> method before invoking the acquisition with the <b>Initiate</b> method.
    </p>
  5. Click on the Preview tab in the Help Editor to instantly view the newly entered help content. The formatted HTML text entered for the Remarks field is rendered just as it will appear in the compiled driver help file.

    Note that Nimbus automatically includes an Instrument Command section on the help page for the method. This feature of driver help files is very useful for end users accustomed to direct SCPI (or other messaging protocol) programming.

  6. The layout and styling of the driver help file is completely customizable via Nimbus Help Templates. Nimbus ships with one pre-built help template that mimic the standard help format of Visual Studio.

    From Solution Explorer, right-click on the Acme4321Help project and choose Properties. The Template page shows a preview of each type of help page for the currently active help template. You can easily choose another help template from the Available templates combo box.

    See the topic Working with Help Templates for a complete discussion of driver help file customization using templates.

  7. Finish documenting the Configure method by providing help documentation for its three parameters:

    1. Click on the numRecords parameter node below the Configure method node in the driver designer.

    2. Click on the Help tab in the Item Editor.

    3. Enter the following into the Summary tab:

      The number of sweeps to perform.

    4. Repeat the above steps to enter documentation for the enabled and source parameters to the Configure method. Enter arbitrary Summary information for each.

  8. From Solution Explorer, right-click on the Acme4321Help project and choose Properties.

    For the purpose of this walkthrough, check the Help 1.x (.chm) help format, but leave the other options cleared. The options on this page are described in detailed here.

  9. From Solution Explorer, right-click on the Acme4321Help project and choose Build. While the build is in progress, the Visual Studio Output window will display the progress of the help project build.

  10. Once the build completes, right-click on the Acme4321Help project in the Solution Explorer and select View Help 1.x (.chm). This will open the newly built driver help file in the Help 1.x viewer.

  11. In the help viewer, click on the Contents tab and then expand the Getting Started node. Note that several boilerplate help pages have been included in the driver’s help file, which are described in more detail here.

  12. Expand the Acme4321 IVI.NET Driver node in the help viewer, then Reference, Driver Hierarchy, and finally IAcme4321. This is where all the dynamically generated help for the main driver interface’s methods, properties and events will appear.

  13. Click on the Configure node in the help viewer table of content. Note that the help documentation entered for the Configure method and its parameters using the driver designer appears in the generated help file.

Creating the Driver Installer

The final task in developing a Nimbus IVI.NET driver is creating the driver installer. The IVI.NET specifications impose a number of detailed requirements for IVI driver installers. Nimbus uses Windows Installer XML (WiX) as the underlying technology for building driver installers. The WiX toolset is in widespread use, especially within Microsoft where it is used to produce the installers for such large-scale projects as Microsoft Office, Visual Studio, and SQL Server.

WiX installers consist of a series of XML files that get compiled in the Acme4321Setup project. Nimbus manages the XML files for you as you add functionality to your IVI.NET driver. For instance, when you use the help project properties to enable or disable different help formats, the Nimbus-generated driver setup project will automatically update the WiX source XML files to reflect set of help files and shortcuts that should be installed on end-user systems by the driver installer.

Nimbus also provides a powerful and easy-to-use graphical designer for customizing a driver installer, such as for installing example programs or other dependent files outside the control of Nimbus.

  1. From Solution Explorer, expand the Acme4321Setup project node. Note that several files have already been added to this project:

    • Images*.*

      This folder contains icon and graphic files that are used by the driver installer.

    • Internal*.wx?

      This folder contains WiX source files that define the required folder structure required for IVI.NET driver installers by the IVI.NET standards, as well as localizable string resources used on driver installer screens.

    • DriverEULA.rtf

      The contents of this license agreement file will be displayed on the driver installer screen when the driver installer is run on end-user machines. You must not remove this file, as the installer source code directly references it. It is essentially empty, providing a place for you to enter the specifics of your driver’s end-user license agreement.

    • Readme.txt

      A starter template for a standard IVI.NET driver readme file.

    • Setup.wxs

      This WiX source file defines the overall layout of the driver installer, and is the file that’s modified by the integrated driver setup designer.

  2. Double click on Setup.wxs in the Solution Explorer to launch the driver setup designer.

  3. The Setup Designer shows the standard IVI.NET folders present on any system with the IVI Shared Components. IVI.NET standard folders that cannot be modified by the driver installer are shown in gray. The Setup Designer also shows the Acme4321 driver folders under which the driver files will be deployed on the target machine.

  4. From the Setup Designer tree view, right-click the Examples folder and choose Add and then select Add Folder…

    The standard Windows Add Folder Dialog appears.

  5. Navigate to a folder on disk with some files and subfolders and click OK. A dialog box titled Select Files to Add will be displayed. Check and uncheck files to be included in the driver installer as desired. Press OK when you’re done.

    Note that the selected folder, its files, and any subfolders and files chosen are now displayed in the Setup Designer tree view. This folder structure will be created on the end-user system by the driver installer.

  6. Right-click on the Acme4321Setup project and choose Build.

  7. When the build has completed, navigate to the \<solutionFolder\>\build\Debug\x86 directory below the driver solution folder and note that an .msi installer package named Acme4321Setup.msi has been created.

This walkthrough has illustrated how to create a simple IVI.NET driver, implement, test and document methods and properties. We have also shown how to create and customize an IVI.NET-compliant driver installer. You might want to explore the following topics: