Example Code

Advanced Scripting in Perl, Python and Tcl

Code and Documents

Attachment

Download All

Overview

The ability to re-use existing code while migrating to a new test software framework can save developers both time and money.  Both NI TestStand test management software and NI LabVIEW give users the ability to directly call and integrate with code written in a variety of languages such as Perl, Python and Tcl.

 

Description

This article examines some of the more advanced scripting language concepts such as communicating with data acquisition devices and instruments. In particular, we will look at how to use Perl, Python and Tcl to call functions in DLLs, perform Data Acquisition using NI-DAQmx and communicate with instruments using NI-VISA.

 

Steps to Implement or Execute Code

 

1. Calling C-Style DLLs from Scripts

 

The first section will describe how to call a function in a simple C-Style DLL from Perl, Python and Tcl.

 

The C-Style DLL

 

We created a simple DLL using LabWindows/CVI that exports a single function called addNumbers. This function uses the cdecl calling convention and has the following four parameters and return value:

Prototype: int addNumbers (int x, int y, int* sum, char* string);

 

Parameter Type Details
x (in) int (by value) First Addend
y (in) int (by value) Second Addend
sum (out) int * (by reference) Output: Sum of x and y
string (out) char * (by reference) Output: “Hello World”
Return value int 0

 

CVI Code: addNumbers
int addNumbers (int x, int y, int* sum, char *string)
{
       *sum = x+y;
       strcpy (string, "Hello World");
       return 0;
}

 

You can download the precompiled DLL here: simpledll.dll

 

Caveats:

  • Perl – Calling Convention: In order to call a function that uses the cdecl calling convention, you must specify the calling convention when you load the function.
    For more on calling conventions, please refer to KnowledgeBase 2RCKK3TL: Calling Conventions in LabWindows/CVI.
  • Perl – Packing: Since numbers can be represented in multiple ways, in order to pass it to the DLL function, the number has to be stored in the same format as the DLL expects. In order to pass an integer pointer, you have to ‘pack’ it as an Int32 (‘i’) before calling the function. Packing in Perl basically tells the interpreter how to represent the data in memory.
    For a tutorial on Packing in Perl, refer to PerlMonks: Pack/Unpack Tutorial.
  • Python – ctypes: Since numbers can be represented in multiple ways, in order to pass it to the DLL function, the number has to be stored in the same format as the DLL expects. In order to pass an integer pointer, Python has a library called ‘ctypes’ that includes types like c_int to facilitate passing integer pointers.
    For more information on the ctypes library, refer to The Python Standard Library: ctypes – A foreign function library for Python.
  • Tcl – Yet Another DLL Caller: The example scripts below use a utility from the Tcl Wiki called ‘Yet Another DLL Caller’ that facilitates calling DLL functions from Tcl. This package contains a DLL as well as a Tcl file that must be included in your source code before you can use it.
    For more information on this utility, refer to Tcl Wiki: Yet another dll caller.

2. Data Acquisition in Scripts Using NI-DAQmx

 

NI-DAQmx is the high-performance, multithreaded, data acquisition (DAQ) driver software at the heart of NI measurement services software.

 

Installing the NI-DAQmx driver also installs and registers several DLLs. One such DLL is nicaiu.dll which is located at:
< Windows>\System32\nicaiu.dll

 

This particular DLL contains the function calls that are part of the NI-DAQmx C API.  Script developers can use these functions to perform data acquisition using National Instruments DAQ devices.

You can find help on all of the NI-DAQmx C API functions in the NI-DAQmx C Reference Help which installs to:
Start»Programs»National Instruments»NI-DAQ»NI-DAQmx C Reference Help.

 

Getting Started

 

  • Installing the NI-DAQmx Driver: In order to use the NI-DAQmx functions, you must have NI-DAQmx installed. This is a free download from http://ni.com/support.
  • Using an NI-DAQmx Compatible Device: In order to perform data acquisition, you also need a device to read from. If you have a device, the following examples refer to the device as ‘dev1’. If you don’t already have a device, you can create and use a simulated device, and make sure that its alias is set to ‘dev1’. For instructions on creating a simulated device, refer to:
    Developer Zone Tutorial: NI-DAQmx Simulated Devices

The Functions We Will Use

 

The following is a list of NI-DAQmx functions that are used will use in the following example scripts:

  • DAQmxCreateTask
    Prototype:
    int32 DAQmxCreateTask (const char taskName[], TaskHandle *taskHandle);
    Purpose: Creates a task.
  • DAQmxCreateAIVoltageChan
    Prototype:
    int32 DAQmxCreateAIVoltageChan (TaskHandle taskHandle, const char physicalChannel[], const char nameToAssignToChannel[], int32 terminalConfig, float64 minVal, float64 maxVal, int32 units, const char customScaleName[]);
    Purpose: Creates channel(s) to measure voltage and adds the channel(s) to the task you specify with taskHandle.
  • DAQmxReadAnalogScalarF64
    Prototype:
    int32 DAQmxReadAnalogScalarF64 (TaskHandle taskHandle, float64 timeout, float64 *value, bool32 *reserved);
    Purpose: Reads a single floating-point sample from a task that contains a single analog input channel.
  • DAQmxClearTask
    Prototype:
    int32 DAQmxClearTask (TaskHandle taskHandle);
    Purpose: Clears the task. Before clearing, this function stops the task, if necessary, and releases any resources reserved by the task.

Note: All DAQmx functions return 0 on success. This example checks for zero at each step and reports an error for non-zero return values.

 

Detailed help on these functions can be found in the NI-DAQmx C Reference Help.

 

3. Instrument Control in Scripts Using VISA

 

National Instruments Virtual Instrument Software Architecture (VISA) is a standard for configuring, programming, and troubleshooting instrumentation systems comprising GPIB, VXI, PXI, Serial, Ethernet, and/or USB interfaces. VISA provides the programming interface between the hardware and development environments.

 

Installing the NI-DAQmx driver also installs and registers several DLLs. One such DLL is visa32.dll which is located at:
< Windows>\System32\visa32.dll

 

This particular DLL contains the function calls that are part of the VISA C API, and developers can use these functions to perform instrument control.

 

You can find help on all of the VISA C API functions in the NI-VISA Help which installs to:
Start»Programs»National Instruments»VISA»Documentation»NI-VISA Help.

 

Getting Started

 

  • Installing the NI-VISA Driver: In order to use the VISA functions, you must have VISA installed. This is a free download from http://ni.com/support.
  • Using the NI-VISA Device: In order to perform instrument control, you also need a device to communicate with. In the following example, we communicate via a GPIB Board to an Instrument Simulator on address 2. The example can easily be modified for serial communication as well.

The Functions We Will Use

 

The following is a list of NI-VISA functions we will use in our example:

  • viOpenDefaultRM
    Prototype:
    ViStatus viOpenDefaultRM(ViPSession sesn)
    Purpose:
    This function returns a session to the Default Resource Manager resource.
  • viOpen
    Prototype:
    ViStatus viOpen(ViSession sesn, ViRsrc rsrcName, ViAccessMode accessMode, ViUInt32 openTimeout, ViPSession vi)
    Purpose: Opens a session to the specified resource.
  •  viSetAttribute
    Prototype:
    ViStatus viSetAttribute(ViObject vi, ViAttr attribute, ViAttrState attrState)
    Purpose: Sets the state of an attribute.
  • viWrite
    Prototype:
    ViStatus viWrite(ViSession vi, ViBuf buf, ViUInt32 count, ViPUInt32 retCount)
    Purpose:
    Writes data to device or interface synchronously.
  • viRead
    Prototype: ViStatus viRead(ViSession vi, ViPBuf buf, ViUInt32 count, ViPUInt32 retCount)
    Purpose: Reads data from device or interface synchronously.
  • viClose
    Prototype:
    ViStatus viClose(ViObject vi)
    Purpose:
    Closes the specified session, event, or find list.

Note: All VISA functions return 0 on success. This example checks for zero at each step and reports an error for non-zero return values.

 

Detailed help on these functions can be found in the NI-VISA Help.

Additional Information or References

Now that you have learned the basics of data acquisition and instrument control in these three scripting languages, you are ready to create your own test automation software.  To see more resources on National Instruments products and scripting languages click on the links below.

Introduction to Scripting in Perl, Python, and Tcl
Calling Scripting Languages from NI TestStand

Example code from the Example Code Exchange in the NI Community is licensed with the MIT license.

Contributors