How to connect a multimeter to a computer
Background
Periodically, there is a task to take readings from a multimeter at certain intervals and record them in a file. For example, a voltage graph when discharging or charging a battery. Generally, there are multimeters with a data recording function for this, but none of those I have have such functionality.
In the budget multimeters ZT102 and ZT301, which are built on the DTM0660 chip, it is possible to implement a connection to a computer, but for this you will have to edit the EEPROM and make changes to the printed circuit board. This is not difficult and Kerry Wong described how to do this using the ennoLogic eM860T multimeter as an example.
At the same time, my Agilent U3402A benchtop multimeter already has an RS232 port on the back panel, but it says “used only for calibration”. A similar warning is in the user manual in Russian and English.
There was a mention on the Keysight forum that Agilent supported connecting the U3402A multimeter to a computer via a serial port, but only for customers from China and Korea. I also remember how one of Keysight's videos talked about a fully automatic procedure for checking and calibrating multimeters. To do this, during the verification/calibration process, at least the measurement modes must be switched and the readings must be read. So most likely, control via RS232 works not only for Chinese and Korean customers.
Found on one of the Chinese websites user manual in chinese and it has a section describing work via the RS232 port. I translated this section into Russian and uploaded it to GitHub.
RS232 adapter
The laptop to which the multimeter will be connected has only USB ports. There are USB-RS232 adapters on sale, but I still have a homemade adapter assembled on a breadboard in the process home server repair.
It uses a ready-made USB-UART module based on the FT232RL and a MAX232 chip to convert signal levels for RS232.
Control via RS232
According to the documentation, there are three categories of commands:
KEY commands (emulates pressing the physical buttons of the multimeter)
SET commands (switching measurement modes, ranges, mathematical operations, etc.)
QUERY commands (getting the current status of the multimeter, the values of the main and additional indicators, the firmware version and software reset)
The laptop has Debian Linux installed and all further examples will be oriented towards Linux. I try to perform a software reset of the multimeter with the command “RST” and then get information about the firmware of the multimeter:
$ screen /dev/ttyUSB0 9600
RST
=>
*>
RV
v1.39,6
Super! The multimeter responds to commands and “Remote” lights up on the indicator. Then I connected a signal generator to the input and supplied a 1 kHz, 1 Vrms sinusoidal signal. Now I need to switch the multimeter to ACV measurement mode and display the signal frequency on the second indicator
S112S
=>
S271S
=>
R1
+0.98788E+0
=>
R2
+1000.00E+0
=>
The commands from the documentation worked without problems. This means that at least in my sample there are no “technical” limitations. I think there are none in all the others either.
Support at Sigrok
Now it was possible to write a simple script that would read data from the multimeter and write it to a file. Or write a sketch for Arduino that would write it to an SD card.
While thinking about which way to go next, I remembered about Sigrok. Sigrok provides the libraries libsigrok (responsible for hardware support and input/output formats) and libsigrokdecode (responsible for protocol decoding), as well as various frontends (PulseView, SmuView, sigrok-meter and sigrok-cli).
If you add U3402A support to libsigrok, all the goodies that its frontends provide will become available.
Important remark! I am not familiar with the libsigrok code base and am not sure that everything I have done is correct. But nevertheless I decided to describe my path, because I stepped on several rakes and it may save someone a couple of hours of time.
Started by reading the file HACKING. From it I learned the recommended way to add a new driver:
$ git clone git://sigrok.org/sigrok-util
$ cd sigrok-util/source
$ ./new-driver "Agilent U3402A"
This will create a file called 0001-agilent-u3402a-Initial-driver-skeleton.patch that needs to be imported into the libsigrok repository.
$ cd ../libsigrok/
$ git am ../sigrok-util/source/0001-agilent-u3402a-Initial-driver-skeleton.patch
This patch affects the following files:
src/hardware/agilent-u3402a/api.c
src/hardware/agilent-u3402a/protocol.c
src/hardware/agilent-u3402a/protocol.h
The last three files already declare the minimum set of functions and register the new driver.
Compiling the project is not difficult.
$ ./autogen.sh
$ ./configure
$ make
I did not install all the libraries listed in the configure script output, but limited myself to those needed to build my driver:
libglib2.0-dev
libserialport-dev
libzip-dev
zlib1g-dev
If the compilation is successful, the new library will be located in .libs/libsigrok.so.4.0.0. In order for Sigrok frontends to load this particular version of the library, you need to configure the LD_LIBRARY_PATH or LD_PRELOAD variable. I did it via LD_LIBRARY_PATH:
$ sigrok-cli -L | grep agilent
agilent-dmm Agilent U12xx series DMMs
$ export LD_LIBRARY_PATH=$PWD/.libs
$ sigrok-cli -L | grep agilent
agilent-dmm Agilent U12xx series DMMs
agilent-u3402a Agilent U3402A
Before exporting the LD_LIBRARY_PATH variable, the libsigrok library was used, which was installed according to sigrok-cli dependencies, and after that, it was compiled locally, which adds support for the agilent-u3402a driver.
Now we need to teach the new driver to find a supported multimeter. The code is added to the scan() function, which is located in the src/hardware/agilent-u3402a/api.c file. I looked at the code of other drivers to understand how to initialize the serial port, write a command to it, and, having read the response, decide whether the desired device is connected.
To do this, use the command “RV\r\n” (without quotes), which requests information about the firmware version and the model of the multimeter. The response should be in the format “vX.XX,M” (without quotes).
At first I couldn't understand why the scan() function wasn't running if I specified which port the driver should use. It turned out that I needed to add a list of parameters supported by the driver to the config_list() function. After that, the driver was able to correctly identify the device:
$ sigrok-cli -d agilent-u3402a:conn=/dev/ttyUSB0 --scan
The following devices were found:
agilent-u3402a - Agilent U3402A v1.39 with 1 channel: P1
The device identification line shows the firmware version and the number of channels.
The next step is to get the value measured by the multimeter. For this I will use the command “R1\r\n”, which returns the last reading from the main indicator. An example of the command response is “+0.98788E+0” (without quotes).
To do this, you need to write an implementation of several functions:
I replaced the dev_open(), dev_close() and dev_acquisition_stop() functions with std_serial_dev_open(), std_serial_dev_close() and std_serial_dev_acquisition_stop() from the standard implementation.
I copied the dev_acquisition_start() function from src/hardware/appa-55ii/api.c. But I had to tinker a bit with the agilent_u3402a_receive_data() function. First, I added a skip of the lines that the multimeter returns after entering commands (I didn't find their description in the documentation, so their meaning is my guess):
“=>” (success)
“!>” (error)
“*>” (waiting)
The implementation of reading the readings is very naive so far and does not check which measurement mode is selected. DC voltage is used in registering values. Getting one value from the multimeter looks like this:
$ sigrok-cli -d agilent-u3402a:conn=/dev/ttyUSB0 -C P1 --samples 1
P1: 3.3007 V
The multimeter on the main indicator shows “3.3007 V DC”.
A positive result has been obtained, but there are too many props in the code. At a minimum, it is necessary to write a definition of the current measurement mode (command “R0\r\n”) and the indicator capacity. Then, if interest persists, you can attach switching of measurement modes and readings of the second indicator.
Conclusions
Multimeter manufacturers may be silent about existing functionality and provide it only to certain regions.
Modern multimeter chips support connection to a computer, but this requires intervention in the EEPROM and modification of the circuit.
Sigrok is easier to learn from the existing code base