Controlling GPIB Instruments from Ubuntu Linux
Some instruments that could usefully be computer controlled ...
Thanks to E-Bay, it is possible to acquire a lot of very high quality test gear for
remarkably little money -- instruments that cost 10's of thousands of pounds when
new can be found for tens of pounds (at most a few hundred). In some cases, these
will be in need of a bit of TLC, but with a bit of luck, most will end up working
pretty much perfectly. Your mileage may vary ... :-)
Most high end instruments from the mid-1970's onwards could be controlled by computer.
In fact, computer control started in the early 1960's, but the introduction of HPIB
by Hewlett-Packard around 1973 established a standard interface and protocol for
controlling a wide variety of instruments. HPIB (Hewlett-Packard Interface Bus) was
later standardized (pretty much unchanged) as GPIB (General Purpose Interface Bus).
This was pretty much the universal means of computer control of test and measurement
gear until the mid 1990's.
Many of the instruments from the late 1970's onwards, often to be found on E-Bay,
can be computer
controlled via GPIB ... if your computer can speak GPIB. It is worth trying to get
it to do so, because a lot of tedious things can then be automated. For example,
if you have a signal generator and a multimeter, you can write a program to measure
the frequency respons of some device sitting between them.
There are two main ways of getting a GPIB interface for a modern PC: a PCI interface
card, or a USB to GPIB converter. There are also ISA GPIB cards to be found, but unless
you want to keep an ancient PC going specifically for instrument control, these are no
longer useful. I would not recommend that approach myself.
Unfortunately, GPIB cards tend to be quite expensive. The choice of card used also
determines (or is determined by) the software you can use on the computer. A very
common approach is to use National Instruments LabVIEW software. This is a very
comprehensive system which is no doubt ideal for use in major engineering companies.
It can do vastly more than control a bunch of old instruments! But if what you want
to do is control a bunch of old instruments ... the huge price tag might well rule
it out! I would think certainly for use by hobbyists, anyway. NI extols the many
virtues of LabVIEW here.
Although it was pricey, I chose to go the USB to GPIB converter route myself. Agilent
make a suitable device - the 82357A USB/GPIB interface. I believe this is now itself
obsolete, although the 82357B might still be current. Much cheaper clones of the 82357B
can also be obtained, although I don't know how well they work (I suspect rather well,
though). All the material here is specific to the 82357A/B adapters (and, probably,
the clones of these). One great advantage of a USB/GPIB adapter is that it can be plugged
in to a laptop machine.
Agilent 82357A USB/GPIB Interface
As you might expect, the 82357A came with a comprehensive set of software for Windows
(Windows 2000 at the time). There was no support for Linux. I used it with the Agilent
supplied libraries on Windows for several years, but, for a variety of reasons, I wanted
to move all my personal computing to Ubuntu Linux by 2012.
Installing GPIB Support for Ubuntu Linux
Fortunately, these days, Linux has good support for GPIB, including the 82357A. At least,
it does if you obtain the GPIB software for Ubuntu from Vsevolod Kukol at
this site. I found other sources
had problems (i.e. the GPIB software didn't work properly). You should get the following
packages installed: gpib-firmware, gpib-modules-dkms, gpib-modules-source, libgpib0,
libgpib0-dev and libgpib-bin.
After installation, the file /etc/gpib.conf needs to
be edited to define the controller
(most things in here are not important when using the software described below). For
the 82357A, the following is sufficient:
minor = 0 /* board index, minor = 0 uses /dev/gpib0, minor = 1 uses /dev/gpib1, etc. */
board_type = "agilent_82357a" /* type of interface board being used */
name = "agilent" /* optional name, allows you to get a board descriptor using ibfind() */
pad = 0 /* primary address of interface */
sad = 0 /* secondary address of interface */
master = yes /* interface board is system controller */
timeout = TNONE /* timeout for commands */
minor = 0
name = "ATTN"
pad = 0
sad = 0
You also need to tell Ubuntu what to do when the Agilent 82357A is plugged in to the machine.
This requires two files be installed in /etc/hotplug/usb. These are needed to get
the firmware loaded in to the interface device (the correct firmware is shipped in the
Linux GPIB packages). The first file is agilent_82357a:
# pre-renumeration device IDs
case $PRODUCT in
# 82357a with firmware already loaded
# 82357a without firmware
# 82357b with firmware already loaded
# 82357b without firmware
# quit unless we were called to download some firmware
if [ "$FIRMWARE" = "" ]; then
# OR: restructure to do other things for
# specific post-renumeration devices
# missing firmware?
if [ ! -r $FIRMWARE ]; then
if [ -x /usr/bin/logger ]; then
/usr/bin/logger -t $0 "missing $FIRMWARE for $PRODUCT ??"
# missing fxload?
if ! which $FXLOAD; then
if [ -x /usr/bin/logger ]; then
/usr/bin/logger -t $0 "missing $FXLOAD ??"
if [ -x /usr/bin/logger ]; then
/usr/bin/logger -t $0 "load $FIRMWARE for $PRODUCT to $DEVICE"
$FXLOAD $FXLOAD_OPTIONS -I $FIRMWARE
The second is agilent_82357a.usermap. This defines the signature for
the interface device so that Ubuntu can recognize it and do the right thing.
# usb module match_flags idVendor idProduct bcdDevice_lo bcdDevice_hi bDeviceClass bDeviceSubClass bDeviceProtocol bInterfaceClass bInterfaceSubClass bInterface Protocol driver_info
agilent_82357a 0x0003 0x0957 0x0007 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000
agilent_82357a 0x0003 0x0957 0x0518 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000
You may be thinking: "This is all a bit complicated.". And it is, but once set up it does
seem to just work (reliably). When the 82357A is plugged in, devices
gpib0 to gpib15 will be found in /dev.
The GPIBlib and GPIBWrap Software
The code I wrote for controlling GPIB instruments has two parts (each of which also has
The specific instruments supported by GPIBlib/GPIBWrap are simply those I happen to own. These
- A C++ library: GPIBlib. There are two bits to this: a base GpibInstrument class in
GPIBlib.cpp (and .h) and a set of instrument specific classes. Together, these let C++
programmers write programs that control and get data from a set of supported instruments.
The GpibInstrument code should make it fairly easy to add additional specific instruments.
GPIBlib is compiled to a shared library (.so) with which other C++ program may
link. The instrument specific functions are quite high level, and form a sort of "language"
for accessing a particular instrument.
- A Python interface to GPIBlib: GPIBWrap.py. Python is a wonderful language IMHO, and
being able to access GPIB instruments from it makes things much easier than using C++. At this
stage of life, I am of the opinion that whenever performance requirements allow it,
interpreted languages are much to be preferred over compiled ones. Python allows performance
sensitive code to be written in C or C++ and used from an interpreted language. This is often
the best of both worlds. In our case, the C-types mechanism is used to do this.
Clearly, this code is more immediately useful if you happen to have one of these
instruments too. However, it isn't too hard to add support for additional instruments.
This requires two sets of code be written:
- HP-3325A Synthesiser/Function Generator.
- HP-3457A Multimeter
- HP-3582A Spectrum Analyzer
- HP-8903E Distortion Analyzer
- Sony/Tektronix RTD-710A Digitizer
Hopefully, examining the source code for GPIBlib will make it clear what to do. In
addition to the C++ class for an instrument, C wrappers for this class need to be
defined so that the Python code in GPIBWrap.py can access its functionality. The
C++ code files for each instrument have the C wrappers and looking at those should
make it clear what to do.
- Support for the instrument as a C++ class derived from GpibInstrument. This
would be in its own source .cpp file and corresponding include .h
- Python wrappers for this new C++ code added to GPIBWrap.py.
The source code for GPIBlib and GPIBWrap can be found here.
It can be built by running buildlib.sh.
Documentation for the Python side can be found here.
This was generated automatically
by Epydoc from the docstrings in the source code. It may be helpful. A pretty crude PDF
version can be found here.
GPIBWrap uses Matplotlib to draw graphs. A sample test program (to be found at the
bottom of GPIBWrap.py) that includes this capability is:
# Generate a 1kHz, 1V square wave.
f = HP_3325A( address['HP_3325A'], 0 )
f.set_function( 'square' )
f.set_frequency( 1, 'kHz' )
f.set_amplitude( 1, 'v_rms' )
# Get the signal's spectrum
s = HP_3582A( address['HP_3582A'], 0 )
s.set_input_mode( 'cha' )
s.set_sensitivity( 'cha', 3 )
s.start_measurement( 'rms', 5, 1 )
(frq,cha,chb,samps,aok,bok) = s.get_spectrum()
# Plot it.
ann = s.read_annotation()
ch1ann = s.parse_channel_annotation(ann,'cha')
ch2ann = s.parse_channel_annotation(ann,'chb')
avann = s.parse_average_annotation(ann)
bwann = s.parse_bandwidth_annotation(ann)
plt.title( 'HP 3582A Spectrum Analyzer' )
plt.xlabel( 'Frequency (Hz)' )
plt.ylabel( 'Amplitude (dBV)' )
plt.grid( True )
ax = plt.gca()
plt.text( 0.6, 0.90, ch1ann, transform=ax.transAxes )
plt.text( 0.6, 0.85, ch2ann, transform=ax.transAxes )
plt.text( 0.6, 0.80, avann, transform=ax.transAxes )
plt.text( 0.6, 0.75, bwann, transform=ax.transAxes )
This results in the graph shown below. (The test code in GPIBWrap .py can be run
with the command: python GPIBWrap.py, of course.)
Measurements made with GPIBlib/GPIBWrap and plotted with Matplotlib
Upgrading to Ubuntu 14.04 LTS
This upgrade will stop GPIB working.
Vsevelod Kukol no longer maintains a working version of the Ubuntu GPIB code.
He stopped at V13. Fortunately, Phil Pemberton has taken up the gauntlet and
you should be able to upgrade the GPIB kernel modules from his private package
archive. Here are the steps required.
echo "Fetch new gpib-modules-dkms for Ubuntu 14.04 and upgrade."
# Vsevelod Kukol no longer maintains Ubuntu GPIB. He stopped at V13.
# Fortunately, Phil Pemberton has taken up the gauntlet.
# This script gets the updated kernel modules from his PPA
# and installs them
sudo add-apt-repository ppa:philpem/ppa
sudo apt-get update
echo "The next step will take ome time."
echo "It removes all previous GPIB kernel modules from all the Ubuntu"
echo "kernel versions that have ever been installed. Which will be lots."
echo "Please just let it run."
sudo apt-get install gpib-modules-dkms
echo "Done. Try plugging in the Agilent 82357A. It should load firmware"
echo "and work as it did on 12.04 LTS."
After this, everything works again. YMMV!
I hope this software might be of some use to people other than myself.
Feel free to do anything you like with it, although I'd be grateful if
you acknowledged where it came from if you do use it.
Go home ...