NAME
GPIB - Perl extension for GPIB devices
SYNOPSIS
use GPIB;
$g = GPIB->new("name");
$g = GPIB->new($interface_module_name, @interface_parameters);
# GPIB Functions
$var = $g->ibcnt # Read GPIB ibcnt variable
$var = $g->iberr # Read GPIB iberr variable
$var = $g->ibsta # Read GPIB ibsta variable
$data = $g->ibrd($maxcnt) # Read from device
$data = $g->ibrda($maxcnt)
$data = $g->ibrdf($maxcnt)
$ibsta = $g->ibwrta($data) # Write data to device
$ibsta = $g->ibwrt($data)
$ibsta = $g->ibwrtf($data)
$ibsta = $g->ibcmd # Write commands to GPIB bus
$ibsta = $g->ibcmda
# GPIB Functions
$value = $g->ibask($option)
$ibsta = $g->ibbna($name)
$ibsta = $g->ibcac($v)
$ibsta = $g->ibclr
$ibsta = $g->ibconfig ($option, $value)
$ibsta = $g->ibdma($v)
$ibsta = $g->ibeos($v)
$ibsta = $g->ibeot($v)
$ibsta = $g->ibgts($v)
$ibsta = $g->ibist($v)
$lines = $g->iblines
$dev = $g->ibln($pad, $sad)
$ibsta = $g->ibloc
$ibsta = $g->ibnotify($v)
$ibsta = $g->ibonl($v)
$ibsta = $g->ibpad($v)
$ibsta = $g->ibpct
$ibsta = $g->ibppc($v)
$pp = $g->ibrpp($v)
$ibsta = $g->ibrsc($v)
$sp = $g->ibrsp($v)
$ibsta = $g->ibrsv($v)
$ibsta = $g->ibsad($v)
$ibsta = $g->ibsic
$ibsta = $g->ibsre($v)
$ibsta = $g->ibstop
$ibsta = $g->ibtmo($v)
$ibsta = $g->ibtrg($v)
$ibsta = $g->ibwait($mask)
# Utility Function
$result = $g->query($command);
print "OK" if $g->devicePresent;
print $g->hexDump($data);
$g->errorCheck;
$g->printStatus;
$g->printConfig;
GPIB::msleep($milliseconds);
# Normally not called by user, GPIB->new() calls these
$ibsta = $g->ibfind()
$ibsta = $g->ibdev()
DESCRIPTION
Gpib.pm provides a convenient and powerful interface to electronic test equipment through GPIB, serial, or other interfaces. The module provides Perl versions of familiar GPIB calls through an object interface.
GPIB.pm works in conjunction with interface modules that perform low level access. GPIB::ni is an XS module that interfaces to National Instruments GPIB cards, GPIB::hpserial is an XS module that interfaces to the serial port of HP equipment, GPIB::rmt is a client to access a GPIB sever running on a remote machine with TCP/IP protocols. GPIB::rmt also provides a standalone Perl server to allow remote access.
Normally, the GPIB module uses /etc/pgpib.conf file to configure the low level interface for particular devices. In general, the applications programmer doesn't need to be aware of the lower level interface and applications work transparent to the lower level interface.
GPIB->new() is used to create a reference for operations on a device. A typical program might use the following to open a device:
use GPIB;
$g = GPIB->new("Generator");
First, Generator is looked up in /etc/pgpib.conf (c:\pgpib.conf on Windows). A typical /etc/pgpib.conf entry is:
# name driver Board PAD SAD TMO EOT EOS
Generator GPIB::ni 0 0x10 0 T1s 1 0
This entry describes a device called "Generator" that uses the National Instruments driver, board 0, primary address 16, and a timeout value of 1 second. See the sample /etc/pgpib.conf.sample file for more information on parameters for other interfaces.
GPIB->new() can be called to open a device bypassing /etc/pgpib.conf. Used in this manner, the first parameter is the name of the low level interface module. Other parameters are those required by the low level module. Here is an example for opening a device using the National Instruments driver with a primary address of 16. In the case of the GPIB::ni module, the parameters to new() are the parameters passed to ibdev() in a GPIB program written in C:
$g = GPIB->new("GPIB::ni", 0, 16, 0, GPIB->T1s, 1, 0);
If GPIB::ni gets 6 parameters it uses ibdev() to open the device. If it gets 1 parameter it calls ibfind() to open the device. To open the bus (as opposed to a specific device), ibfind() is used with the nameof the bus as a parameter. Here is an example for open the GPIB bus on the first board. This can also be done in the /etc/pgpib.conf file.
$g = GPIB->new("GPIB::ni", "gpib0");
The reference return by GPIB->new is used by all other GPIB methods to indentify the device. Most of the methods are object methods of standard GPIB function calls. A simple program for accessing the device is shown below:
use GPIB;
$g = GPIB->new("Generator");
$g->tmo(GPIB->T3s); # Set timeout to 3s
$g->ibwrt('*IDN?'); # Send *IDN? to device
$id = $g->ibrd(1024); # Read result
print "Got $id\n";
See GPIB documentation or example programs for examples using standard GPIB calls.
$t = $g->hexDump($data) produces a human readable dump of scalar containing binary data. This is useful for debugging GPIB programs.
GPIB::msleep($milliseconds) sleeps for specified number of mS. This is often useful in GPIB programming.
$result = $g->query($command) is a convenience function that does an $g->ibwrt($command) followed by an $g->ibrd() if the write succeeds. This simplifies the example shown above for read the ID string as follows:
use GPIB;
$g = GPIB->new("Generator");
print "Got ", $g->query('*IDN?');
$g->printStatus() and $g->printConfig() are utility functions for printing status of the last operation (printStatus) or the configuration of the device (printConfig).
$g->errorCheck() is convenience function that check the ibsta return code from the previous operation. If there was an error then some diagnostic information is printed and the program exits. It's a quick and dirty method for doing error checking:
use GPIB;
$g = GPIB->new("device"); # new() dies on error
$g->ibwrt('*IDN?');
$g->errorCheck("ibwrt error ");
$d = $g->ibrd(1024);
$g->errorCheck("ibrd error ");
$g->ibsta(), $g->ibcnt(), and $g->iberr() are methods for accessing the global ibsta, ibcnt, and iberr variables normally associated with GPIB programming. These are usually global variables in GPIB C programs. In Perl these are instance variables. GPIB constants are accessed in the GPIB namespace. A typical piece of code for checking errors is:
$g->ibwrt("Hello, world.");
print "There was an error\n" if $g->ibsta & GPIB->ERR;
print "Timeout\n" if $g->ibsta & GPIB->TIMO;
Look in GPIB.pm for a list of exportable constants.
INHERITANCE
The GPIB module is written with the intention of it being inherited by other modules. Driver modules that provide functionality for specific devices inherit GPIB. See documentation for specific modules, a short example is shown below. The GPIB::hp33120a driver module provides methods for conveniently setting parameters on this device while still providing all of the functionality of the GPIB module. An example is shown below:
use GPIB::hp33120a;
$g = GPIB::hp33120a->new("name");
$g->freq(20000.0); # Set frequency to 20kHz
$g->shape(SIN); # Sine wave
$g->amplitude(4) # 4v peak-to-peak
$g->offset(2) # Dc offset of 2v
The GPIB::hp33120a module is a very simple module written in completely in Perl. It inherits GPIB and implements methods that generate SCPI commands for the HP33120A functionality. It's very easy to write these modules and create resuable code useful for other projects.
POLYMORPHISM
A big word for a small piece of advice. If device driver modules that provide similar functionality for different devices adopt consistent naming for their methods, application programmers can write programs that might work across a number of devices. For example, if someone writes a new module for a function generator and she uses the same naming convention as GPIB::hp33120a, life is more convenient for everyone:
use GPIB::hp33120a;
use GPIB::xyzgen;
$g[0] = GPIB::hp33120a->new("device1");
$g[1] = GPIB::xyzgen->new("device2");
for (@g) {
$_->freq(1000000.0);
$_->shape(SIN);
}
In the example above, an array contains references to function generators. The loop sets all function generators to 1MHz sine waves without knowledge of the details of each device. This is a really great concept, but it only works if a consistent naming convention is used for similar modules. Please keep this in mind when you write new instrument drivers.
CONFIGURATION
/etc/pgpib.conf (C:\PGPIB.CONF on NT) contains local configuration information. It associates a name with the proper low level driver and parameters for that driver. In most cases, local configurations issues can be resolved with this file.
The file has one device per line. Blank lines or lines beginning with a '#' are ignored. The file is read once the first time GPIB->new() is called. From that point the configuration information is held in memory in a hash called %gpib::config. %gpib::config is a hash keyed off the name of the entry. Each element is a reference to an array of parameters on the configuration line. test.pl in the gpib traverses this data structure.
Each parameter in the file can be either a string, a decimal number, a hex number if it begins with '0x', or one of the National Instruments timeout constants TNONE, T10us, T30uS, etc.
It's not essential to have a /etc/pgpib.conf file, but it makes life much easier to confine all local configuration issues to this one file. If the address of a device is changed or if a device is moved from GPIB to a serial port, the only change required is in this file. When using Perl-GPIB the first time it's probably best to enter a device or two into this file and do some simple tests from the Perl debugger until you get confortable that things are working. Here's a sample test on my setup:
% perl -MGPIB::hp33120a -de1
Loading DB routines from perl5db.pl version 1.0401
Emacs support available.
DB<1> $g = GPIB::hp33120a->new("HP33120A")
DB<2> x $g->get
0 'SIN'
1 '1.000000000000E+06'
2 '+1.000000E+00'
3 '+0.000000E+00'
DB<3> p $g->query('*IDN?')
HEWLETT-PACKARD,33120A,0,7.0-4.0-1.0
Entries for the GPIB::ni (National Instruments GPIB) interface look like this. The parameters after GPIB::ni correspond to the 6 parameters to ibdev():
# NI GPIB card
# name Board PAD SAD TMO EOT EOS
#
K2002 GPIB::ni 0 0x10 0 T1s 1 0
Entries for the GPIB::rmt remote access interface look like this:
# Remote connections
# name driver machine user password device
#
HP33120A GPIB::rmt sparky.mock.com jeff fiddle HP33120A
Entries for the GPIB::hpserial serial port interface look like this:
# Serial port
# name driver port speed TMO EOS FLAG
#
HP33120AS GPIB::hpserial /dev/cua1 9600 T3s 0x0a 0x0001
CREDIT
These modules were insprired by a GPIB module written by Steve Tell at the MSL at UNC (tell@cs.unc.edu). Steve's module showed me how great Perl is as a language for GPIB programming. So much of GPIB programming is munging text strings and Perl just can't be beat for this.
AUTHOR
Jeff Mock, jeff@mock.com
SEE ALSO
perl(1), GPIB::hpserial(3), GPIB::ni(3), GPIB::hp33120a(3), pgpib.conf(4).