The HP34401A Digital Multimeter (DMM) is a commonly used benchtop meter. They are available on the used market for reasonable (for what you are getting) prices. It is new enough that it supports the SCPI style command set which makes writing drivers simpler than the old R2D2 style command set.
This tool supports measurements using automatic configuration or manual configuration. It can make use of the triggering system in the '34401A to accurately control when multiple measurements are made. Measurement data can be saved to .csv files. Commands can be supplied to the tool on the shell command line, from a script file, or from an internal shell-like mode. Arbitrary delays between commands can be set. Multiple measurements with delays between them can be made with the measurements saved to a .csv file for later use.
This tool shares the architecture of the project #HP E3634A Power Supply Control Software . Both tools share a lot of their source code. GPIB interface tasks are handled by the linux_gpib library that is available via Source Forge and other places. Linux_gpib supports many different interface boards and dongles. Development was done under Fedora 32 and tested on several other Fedora versions. You must install the linux_gpib package before building this tool.
Both the linux_gpib library and the National Instruments NI488-2 libraries are compatible with each other with minor exceptions. It is possible to build this package to run under Windows using the NI488-2 library. Instructions to do so can be found in my #HP545xx Data Acquisition Software project.
In order to build this project on a Linux machine, you must already have the linux_gpib package installed. There is a .h file needed at compile time and a library that is needed at link time for this package to compile successfully. Create a working directory to build the tool in and copy the .tgz file into it. Un-tar the file and type make:
> mkdir HP34401A_ctl
> cd HP34401A_ctl
> cp wherever/HP34401A_ctl_xx_xx_xxxx.tgz .
> tar -xvf HP34401A_ctl_xx_xx_xxxx.tgz
> make
and the software should build with no errors or warning messages. Finally, copy the executable program to a convenient directory in your executable path like ~/bin. There should be no need to do any of these tasks as root unless you want to put the executable in a directory off the /usr tree.
Typing ./HP34401A_ctl with no parameters will give you a command listing:
Usage: HP34401A_ctl [-d dev_addr] CMD1 [arg1] [CMD2]...
where CMDn [argn] is one of:
HELP cmd_name
READ_CMDFILE cmdfilename
INTERACTIVE [TOLERANT]
SLEEP_MS NmilliSeconds
GET_ID no parameters
GET_ERRORS no parameters
GET_VOLTAGE_DC_AUTO no parameters
GET_CURRENT_DC_AUTO no parameters
GET_VOLTAGE_AC_AUTO no parameters
GET_CURRENT_AC_AUTO no parameters
GET_RESISTANCE_AUTO no parameters
GET_4W_RESISTANCE_AUTO no parameters
GET_FREQUENCY_AUTO no parameters
GET_PERIOD_AUTO no parameters
GET_CONTINUITY_AUTO no parameters
GET_DIODE_AUTO no parameters
GET_VOLTAGE_DC_MAN range/MIN/MAX resolution/MIN/MAX
GET_VOLTAGE_AC_MAN range/MIN/MAX resolution/MIN/MAX
GET_CURRENT_DC_MAN range/MIN/MAX resolution/MIN/MAX
GET_CURRENT_AC_MAN range/MIN/MAX resolution/MIN/MA
GET_RESISTANCE_MAN range/MIN/MAX resolution/MIN/MAX
GET_4W_RESISTANCE_MAN range/MIN/MAX resolution/MIN/MAX
CONFIG_VOLTAGE_DC_MAN range/MIN/MAX resolution/MIN/MAX
CONFIG_VOLTAGE_AC_MAN range/MIN/MAX resolution/MIN/MAX
CONFIG_CURRENT_DC_MAN range/MIN/MAX resolution/MIN/MAX
CONFIG_CURRENT_AC_MAN range/MIN/MAX resolution/MIN/MAX
CONFIG_RESISTANCE_MAN range/MIN/MAX resolution/MIN/MAX
CONFIG_4W_RESISTANCE_MAN range/MIN/MAX resolution/MIN/MAX
SET_AUTOZERO_ENABLE ON/OFF
GET_AUTOZERO_ENABLE No Parameters
GET_MULTIPLE_AUTO_TO_FILE VOLTS_DC/VOLTS_AC/CURRENT_DC/CURRENT_AC/RESISTANCE NUM DWELL_ms FILENAME
GET_MULTIPLE_MAN_TO_FILE VOLTS_DC/VOLTS_AC/CURRENT_DC/CURRENT_AC/RESISTANCE range/MIN/MAX resolution/MIN/MAX NUM DWELL_ms FILENAME
SET_TRIG_SOURCE BUS/IMMEDIATE/EXTERNAL
GET_TRIG_SOURCE No Parameters
SET_TRIG_COUNT Num
GET_TRIG_COUNT No Parameters
SET_TRIG_DELAY Nseconds
GET_TRIG_DELAY No Parameters
TRIG_DELAY_AUTO ON/OFF
GET_TRIG_DELAY_AUTO No Parameter
SET_SAMPLE_COUNT Num
GET_SAMPLE_COUNT No Parameters
SEND_TRIGGER No Parameters
READ No Parameters
SEND_INITIATE No Parameters
FETCH No Parameters
GET_DATA_POINTS No Parameters
DEV_CLR No Parameters
DISPLAY_ENABLE ON/OFF
GET_DISPLAY_ENABLE No Parameters
FETCH_TO_FILE Filename
SHOW_RESPONSE cmdstring
SEND_CMD cmdstring
SCANNER u16 u16 u16 char
Commands may be entered in upper or lower case:
> GET_DC_VOLTAGE_AUTO
and
> get_dc_voltage_auto
issue exactly the same command to the meter.
Instrument commands may be typed on the command line, like:
> HP34401A_ctl GET_DC_VOLTAGE_AUTO sleep_ms 500 GET_DC_VOLTAGE_AUTO
to measure the DC voltage twice, with 500mS between measurements. Multiple commands can appear on a single line, separated by space characters.
Text command files can be used to run the same operations numerous times. After creating a text file hptest.txt containing:
GET_DC_VOLTAGE_AUTO
sleep_ms 500
GET_DC_VOLTAGE_AUTO
you can run that file:
> HP34401A_ctl read_cmdfile hptest.txt
The interactive command reads commands as you type them and executes them after each line feed character. The biggest difference between using the command line method and the interactive method is that the GPIB bus does not disconnect between commands when using the interactive method, while it does disconnect between commands using the command line method. This is important when setting up and using the trigger stuff on the HP34401A meters. Any trigger setup gets cleared when you disconnect from the meter.
Using the command line or the read_cmdfile methods will exit with an error if you fat finger a command or parameter. If the TOLERANT parameter in interactive mode is used, the program will not exit on parsing errors.
Also, when using the interactive mode, you don't have to type HP34401A_ctl before commands.
One of the main uses for the interactive mode is when this program is exec'd from another program. Connecting to the stdin and stdout of this program in interactive mode allows full control from the calling program. The TOLERANT option will greatly simplify development of these applications.
Understanding some of the command set will require studying the HP34401A Programmers Manual, especially the trigger operations.
Commands like: GET_VOLTAGE_DC_AUTO do exactly what they suggest, they just issue the measure command (using auto-ranging) and return the result. Commands like:
GET_VOLTAGE_DC_MAN range/MIN/MAX resolution/MIN/MAX
run manual ranging measurements, so they require a value for range and resolution. Those values can be either numerical or MIN or MAX.
Getting multiple measurements to a .csv file can be done with the looping commands:
GET_MULTIPLE_AUTO_TO_FILE VOLTS_DC/VOLTS_AC/CURRENT_DC/CURRENT_AC/RESISTANCE NUM DWELL_ms FILENAME
or
GET_MULTIPLE_MAN_TO_FILE VOLTS_DC/VOLTS_AC/CURRENT_DC/CURRENT_AC/RESISTANCE range/MIN/MAX resolution/MIN/MAX NUM DWELL_ms FILENAME
Both of these commands require you to specify a measurement type (VOLTS_DC...) the number of measurements to take (NUM), the time between measurements (DWELL_ms) and the data FILENAME. The manual ranging (second example) measurements must supply the range and resolution for the measurements. If you need accurate timing on the measurements for either of these examples, investigate the trigger method of initiating measurements.
Using the trigger operations is complex enough that you need to read the Programmers manual to make sense of it.
A couple of debugging commands, SHOW_RESPONSE and SEND_CMD are included to allow sending a command to the meter and displaying the full response string, or just sending an arbitrary command.
As mentioned above, this program was written to enable calibrating another project. The SCANNER command was the path into that. In operation, SCANNER would fork and exec programs similar to this one to control the system being calibrated and a power supply. What is visible in the included source code is just a stub function.
The software is written in layers. The main function calls the parse_and_exec () function that parses the instrument commands. In the parse_and_exec.c file, the individual instrument commands get their parameters parsed and then call low level commands in HP34401A.c that assemble the outgoing strings, communicate with the GPIB driver and fetch results. The low level file (HP34401A.c and .h) could be used in a GUI driven program with the GUI software calling the low level command handling functions.