NI GPIB-USB-HS on Ubuntu 24.04, 26.04
1st version 10/07/2026
General
This guide describes how to install and use an National Instruments GPIB-USB-HS (USB, IEEE-488 GPIB Instrument Control Device) on Ubuntu 24.04 and Ubuntu 26.04 using Linux-GPIB 4.3.7.
The particular adapter used in this project requires a modification to the ni_usb_gpib.c file because its identification sequence during startup differs from what the original Linux-GPIB driver expects. I prepared the required modifications as a patch file so that they can be applied easily. The patch code is provided at the end of this page and on GitHub.
I was unable to get the official NI-488.2 package to work properly with this adapter, so I decided to use Linux-GPIB instead.
The setup procedure is similar to that for the Agilent 82357B when using Linux-GPIB. However, the NI GPIB-USB-HS requires a few additional steps, including configuration of gpib.conf and, for the particular adapter tested here, application of a patch.
If the driver and firmware files for both adapters are installed, the Agilent 82357B and NI GPIB-USB-HS can be used on the same Ubuntu installation by connecting the desired adapter.
✎ Note
Linux-GPIB 4.3.7 states that Linux kernels 6.13 and later contain GPIB drivers in the standard kernel source tree. This guide intentionally builds the kernel drivers supplied with Linux-GPIB 4.3.7 because the ni_usb_gpib driver is modified for the particular adapter tested here.
Linux-GPIB 4.3.7 was officially announced as supporting kernels through 6.17. The procedures in this guide were also tested successfully in my Ubuntu environments using kernel 7.0.0-31-generic; this is a test result from these systems, not a statement of official upstream support for kernel 7.0.
Test Configurations
Intel NUC13ANK
- Intel Core i5-1340P – 16 GB RAM – Intel Iris Xe Graphics (onboard)
- Ubuntu 24.04.4 LTS, clean installation
- Ubuntu 26.04.1 LTS, clean installation
HP ENVY 17t-s100
- Intel Core i7-6700HQ – 16 GB RAM – Intel HD Graphics 530
- Ubuntu 24.04.4 LTS
USB-GPIB adapter: NI GPIB-USB-HS
This adapter was purchased as a new item from an eBay seller named “NI Grocery Store” for $50 in May 2026.




Test Equipment


(The powered USB hub did not eliminate the USB hot-plug problem described later in this guide.)
Linux-GPIB Drivers and Utilities Installation
1. Install the Build Tools and Required Development Packages
sudo apt install python3-setuptools
sudo apt update
sudo apt upgrade
sudo apt install build-essential
sudo apt install python3-setuptools
sudo apt install python3-dev
sudo apt install libboost-python-dev
Reboot Ubuntu before continuing:
sudo reboot
The kernels used for the tests described here were:
Ubuntu 24.04.4: 7.0.0-31-generic
Ubuntu 24.04.4: 7.0.0-34-generic
Ubuntu 26.04.1: 7.0.0-31-generic
Disconnect the GPIB adapter’s USB cable from the PC before starting the installation.
2. Download the Linux-GPIB Driver Package from SourceForge
Linux-GPIB download page:
https://sourceforge.net/projects/linux-gpib/files/linux-gpib%20for%203.x.x%20and%202.6.x%20kernels/

Download Linux-GPIB 4.3.7.
cd ~/Downloads
ls -al linux-gpib-4.3.7.tar.gz
Example:
-rw-rw-r-- 1 mm mm 1309937 Sep 6 15:11 linux-gpib-4.3.7.tar.gz
3. Copy the Package to /opt and Extract It
sudo cp linux-gpib-4.3.7.tar.gz /opt/
cd /opt/
sudo tar -xzf linux-gpib-4.3.7.tar.gz
cd linux-gpib-4.3.7/
ls -al
The package contains separate kernel and user-space archives:
-rw-r--r-- 1 mm users 213606 Oct 5 2025 linux-gpib-kernel-4.3.7.tar.gz
-rw-r--r-- 1 mm users 1095172 Oct 5 2025 linux-gpib-user-4.3.7.tar.gz
-rw-r--r-- 1 mm users 4175 Oct 5 2025 README.txt
Extract both archives:
sudo tar -xzf linux-gpib-kernel-4.3.7.tar.gz
sudo tar -xzf linux-gpib-user-4.3.7.tar.gz
✎ Note After a Linux kernel update
The Linux-GPIB kernel drivers may need to be rebuilt after a kernel update. A driver built for the previous kernel is not automatically available for a newly installed kernel.
If GPIB suddenly stops working after a kernel update, first check the currently running kernel:
uname -r
Then check whether the NI USB GPIB driver has been installed for that kernel:
find /lib/modules/$(uname -r) -name "ni_usb_gpib.ko*"
Linux kernel modules are installed separately for each kernel version under /lib/modules/.
If ni_usb_gpib.ko is not found for the currently running kernel, repeat the installation procedure from Section 4. Install the Linux Kernel Headers onward.
4. Install the Linux Kernel Headers
sudo apt install linux-headers-$(uname -r)
5. Apply the Special Patch for the NI GPIB-USB-HS
❗ Important
This patch modifies ni_usb_gpib.c for the particular NI GPIB-USB-HS adapter tested in this project.
The patch is required for my adapter, but it may not be required for other hardware revisions or for genuine NI units that follow the response sequence expected by the original Linux-GPIB driver.
For the initial installation, I recommend skipping this section and first completing the installation with the original driver. Apply this patch only if the adapter cannot be initialized correctly.
5-1. Prepare the patch file
The patch code is also included at the end of this page. Alternatively,
the patch file can be downloaded from GitHub:
https://github.com/moriyasum/GPIB/blob/main/ni_usb_gpib_709b_linux-gpib-4.3.7.patch
Place the following file in ~/Downloads:
ni_usb_gpib_709b_linux-gpib-4.3.7.patch
Confirm that it is present:
ls -al ~/Downloads/*.patch
Example:
-rw-rw-r-- 1 mm mm 2224 Sep 8 16:06 /home/mm/Downloads/ni_usb_gpib_709b_linux-gpib-4.3.7.patch
Move to the Linux-GPIB kernel source directory:
cd /opt/linux-gpib-4.3.7/linux-gpib-kernel-4.3.7
5-2. Test the Patch First
Use --dry-run to check whether the patch can be applied without actually modifying the source:
patch --dry-run -p1 < ~/Downloads/ni_usb_gpib_709b_linux-gpib-4.3.7.patch
If the dry run is successful, a message similar to the following is displayed:
checking file drivers/gpib/ni_usb/ni_usb_gpib.c
5-3. Apply the Patch
patch -p1 < ~/Downloads/ni_usb_gpib_709b_linux-gpib-4.3.7.patch
If the patch is applied successfully, a message similar to the following is displayed:
checking file drivers/gpib/ni_usb/ni_usb_gpib.c
6. Build and Install the Kernel Drivers
Move to the kernel source directory:
cd /opt/linux-gpib-4.3.7/linux-gpib-kernel-4.3.7/
Build and install the drivers:
make clean
make
sudo make install
During installation, drivers for multiple supported GPIB interfaces are installed. Among them, you should see entries such as:
INSTALL /lib/modules/7.0.0-31-generic/gpib/agilent_82357a/agilent_82357a.ko
INSTALL /lib/modules/7.0.0-31-generic/gpib/ni_usb/ni_usb_gpib.ko
The exact kernel version in the path will depend on the output of
uname -r
7. Install the User-Space Libraries and Utilities
Move to the user-space source directory:
cd /opt/linux-gpib-4.3.7/linux-gpib-user-4.3.7/
Configure, build, and install:
./configure --sysconfdir=/etc
make
sudo make install
This installs the Linux-GPIB user-space library and utilities, including programs such as gpib_config, ibtest, and ibterm.
8. Install the Python Binding
8-1. Make libgpib.so.0 Available to the PyVISA Backend
In my environment, the following symbolic link was required so that the PyVISA @py backend could locate libgpib.so.0:
sudo ln -s /usr/local/lib/libgpib.so.0 /lib/libgpib.so.0
✎ Note
This symbolic link was required in the systems tested for this guide. Depending on your library configuration, it may not be necessary on every Ubuntu installation.
8-2. Install the Linux-GPIB Python Binding
Move to the Python directory in the Linux-GPIB source tree:
cd /opt/linux-gpib-4.3.7/linux-gpib-user-4.3.7/language/python
ls -al
Confirm that setup.py is present, and install the binding:
sudo python3 setup.py install
9. Install PyVISA for Python Instrument Control
sudo apt update
sudo apt install python3-pyvisa
Check the PyVISA installation:
pyvisa-info
If the Linux-GPIB backend has been installed correctly, the final part of the output should include lines similar to:
GPIB INSTR: Available via Linux GPIB (b'4.3.7')
GPIB INTFC: Available via Linux GPIB (b'4.3.7')
Reboot Ubuntu before continuing:
sudo reboot
10. Configure gpib.conf
✎ Note
This gpib.conf configuration is required for the NI GPIB-USB-HS setup described here. The Agilent 82357B setup uses a different procedure.
10-1. Edit gpib.conf
Open the configuration file:
sudo gedit /etc/gpib.conf
Replace its contents with:
interface {
minor = 0
board_type = "ni_usb_b"
name = "gpib0"
pad = 0
sad = 0
timeout = T3s
master = yes
}
Save the file.
Power on the GPIB instrument. In this example, the instrument is an HP 34401A DMM at GPIB address 13.
Then connect the USB cable from the NI GPIB-USB-HS to the computer.
10-2. Apply the Settings in gpib.conf
Run:
sudo gpib_config
If the command completes without displaying an error, this is normal.
For example:
mm@NUC13:~$ sudo gpib_config
mm@NUC13:~$
Check whether the USB adapter is detected:
lsusb | grep GPIB
Example:
Bus 003 Device 005: ID 3923:709b National Instruments Corp. GPIB-USB-HS
11. Install fxload
Install fxload before setting up the firmware:
sudo apt install fxload
12. Install the Firmware
12-1. Download and Extract the Firmware Package
Move to /opt and download the firmware package:
cd /opt
sudo wget --content-disposition --no-check-certificate http://linux-gpib.sourceforge.net/firmware/gpib_firmware-2008-08-10.tar.gz
Extract the archive:
sudo tar -xvf gpib_firmware-2008-08-10.tar.gz
12-2. Copy the Firmware Files
For the NI GPIB-USB-HS:
cd /opt/gpib_firmware-2008-08-10/ni_gpib_usb_b
sudo cp -r * /usr/local/share/usb/ni_usb_gpib
If you also want to use an Agilent 82357B, its firmware can be installed at the same time. Note that the firmware directory for the 82357B is named agilent_82357a:
cd /opt/gpib_firmware-2008-08-10/agilent_82357a/
sudo cp -r * /usr/local/share/usb/agilent_82357a/
If the driver and firmware files for both adapters are installed, you can use either adapter on the same Ubuntu installation by connecting the adapter you want to use.
After installing the firmware files,
Disconnect the GPIB adapter’s USB cable from the PC and reconnect it.
13. Configure GPIB Device Permissions
By default, /dev/gpib0 may be accessible only by root. Configure a udev rule so that Linux-GPIB applications, including ibtest and Python programs, can access the device without sudo.
13-1. Check Membership in the plugdev Group
Run:
groups
In my environment, plugdev was already listed:
mm adm cdrom sudo dip plugdev users lpadmin
If plugdev is already listed, skip the next usermod command.
If plugdev is not listed, add the current user to the group.
sudo usermod -aG plugdev $USER
Log out and log back in after running this command.
13-2. Create a udev Rule
Open a new rule file:
sudo gedit /etc/udev/rules.d/99-gpib.rules
Add the following line:
KERNEL=="gpib[0-9]*", GROUP="plugdev", MODE="0660"
Save the file, and reload the udev rules:
sudo udevadm control --reload-rules
sudo udevadm trigger
Disconnect the GPIB adapter’s USB cable from the PC and reconnect it.
Check the permissions:
ls -l /dev/gpib0
In my environment, the result was:
crw-rw---- 1 root plugdev 160, 0 Sep 7 12:07 /dev/gpib0
If plugdev is shown as the group and your user belongs to plugdev, the device can be accessed without sudo.
14. Final Check
14-1. Check USB Detection
lsusb | grep HS
Example:
Bus 003 Device 061: ID 3923:709b National Instruments Corp. GPIB-USB-HS
14-2. Check the LEDs on the GPIB-USB-HS
On the adapter tested here, both LEDs are relatively dim.
- Ready (orange): stays on continuously.
- Active (green): flashes during GPIB communication and is
normally off when idle.

The Linux-GPIB driver, user-space utilities, firmware, and device permissions are now configured, and the NI GPIB-USB-HS is ready for an actual communication test.
The next section uses the Linux-GPIB utilities ibtest and ibterm to communicate with an HP 34401A.
✎ Note
If you later add an Agilent 82357B, the same Ubuntu installation can also be prepared for that adapter by installing its required driver/firmware files.
You can then switch between the NI and Agilent USB-GPIB adapters as needed.
Utility Applications
The Linux-GPIB installation includes several command-line utilities. Before testing with Python, it is useful to confirm basic GPIB communication with ibtest and ibterm.
The examples below use an HP 34401A at GPIB address 13.
✎ Change the GPIB address to match your instrument.
1. Test Communication with ibtest
1-1, Operation
ibtest, included with Linux-GPIB, provides a simple way to verify communication with a GPIB instrument without writing a program.
Start ibtest:
ibtest
For the example used in this guide, enter the following selections:
d— open a device, not a GPIB interface board13— GPIB address of the HP 34401Aw— write a command to the instrument*IDN?— query the instrument identificationr— read the response100— maximum number of bytes to read
A typical session is shown below:
Do you wish to open a (d)evice or an interface (b)oard?
(you probably want to open a device): d
enter primary gpib address for device you wish to open [0-30]: 13
trying to open pad = 13 on /dev/gpib0 ...
After the device has been opened, select w:
: w
enter a string to send to your device: `*IDN?`
Then select r and specify the maximum number of bytes to read:
: r
enter maximum number of bytes to read [1024]: 100
trying to read 100 bytes from device...
received string: 'HEWLETT-PACKARD,34401A,0,7-5-2
'
Number of bytes read: 31
This confirms that the adapter can send a GPIB command to the instrument and receive its response.
Enter q to exit ibtest.
1-2. Useful HP 34401A Commands for ibtest
| Command | Description | Read required? |
|---|---|---|
*IDN? | Queries the instrument identification information HEWLETT-PACKARD,34401A,0,7-5-2 | Yes |
MEAS:VOLT:DC? | Measures DC voltage and returns the measured value received string: ‘+5.25970000E-05’ | Yes |
MEAS:VOLT:AC? | Measures AC voltage and returns the measured value received string: ‘+1.80423900E-03’ | Yes |
MEAS:RES? | Measures resistance and returns the measured value received string: ‘+1.00052360E+06’ | Yes |
CONF:VOLT:DC | Configures the DMM for DC voltage measurement | No |
CONF:VOLT:AC | Configures the DMM for AC voltage measurement | No |
CONF:RES | Configures the DMM for resistance measurement | No |
READ? | Performs a measurement using the current configuration | Yes |
*RST | Resets the instrument to its default settings | No |
*CLS | Clears the instrument status registers | No |
For example, a DC-voltage measurement can be performed as follows:
w, MEAS:VOLT:AC?, r, 100 ---> -4.83986000E-04
w, MEAS:RES?, r, 100 ---> +1.00052360E+06
w, CONF:VOLT:DC, w, READ?, r, 100 ---> -7.02526000E-04
w, READ?, r, 100 ---> -5.60173000E-04
w, READ?, r, 100 ---> -5.28759000E-04
w, READ?, r, 100 ---> -4.95879000E-04
2. Test Communication with ibterm
ibterm is another Linux-GPIB utility for communicating interactively with a GPIB instrument. It is more convenient than ibtest when you simply want to type instrument commands and view the responses.
Start ibterm with the GPIB address of the instrument:
ibterm -d 13
where 13 is the GPIB address of the HP 34401A.
A typical startup message is:
Attempting to open /dev/gpib0
pad = 13, sad = 0, timeout = 10, send_eoi = 1, eos_mode = 0x0000
Commands can then be entered directly:
ibterm> *IDN?
HEWLETT-PACKARD,34401A,0,7-5-2
ibterm> MEAS:VOLT:DC?
+4.68678000E-04
ibterm> MEAS:VOLT:AC?
+1.88880200E-03
ibterm> MEAS:RES?
+5.25072420E+05
✎ Note from my tests with ibterm:
With the NI GPIB-USB-HS, simple query commands such as *IDN? and MEAS:VOLT:DC? worked correctly. However, I observed problems with some CONF / READ? command sequences when using ibterm.
At this point, basic GPIB communication has been verified using the Linux-GPIB utilities. The next section tests GPIB communication using Python and PyVISA.
Test with Python and PyVISA
1. Test GPIB Interactively with Python
Before creating a Python script, communication can be checked directly from the Python interactive prompt.
Start Python:
python3
At the >>> prompt, enter or paste:
import pyvisa
rm = pyvisa.ResourceManager()
inst = rm.open_resource("GPIB0::13::INSTR")
print(inst.query("*IDN?"))
inst.close()
rm.close()
For the HP 34401A used in this example, the response is:
HEWLETT-PACKARD,34401A,0,7-5-2
This confirms that PyVISA can communicate with the instrument through Linux-GPIB.
To leave the Python interactive mode:
quit()
✎ Note
GPIB0 is the VISA interface name, while 13 is the GPIB address of the instrument. Change the address to match your instrument.
2. Python CLI Application for One HP 34401A
This first program reads the instrument ID and then measures DC voltage five times.
2-1. File
File name: dmm1-cli.py
The example programs are available from:
https://github.com/moriyasum/GPIB
✎ Change the GPIB address to match your instrument.
2-2. Run the Program
python3 ./dmm1-cli.py
2-3. Example Output
Interface: GPIB0 , GPIB address: 13
Instrument ID: HEWLETT-PACKARD,34401A,0,7-5-2
0 DC Voltage = +3.65830000E-05 V
1 DC Voltage = +5.06870000E-05 V
2 DC Voltage = +4.25880000E-05 V
3 DC Voltage = +5.31860000E-05 V
4 DC Voltage = +4.21300000E-05 V
2-4. Python Source Code
import pyvisa
import time
# GPIB address and interface number
adr = "13"
interface = "GPIB0"
# Open VISA
rm = pyvisa.ResourceManager()
dmm = rm.open_resource(f"{interface}::{adr}::INSTR")
dmm.timeout = 5000
# Read instrument ID
print("Interface: ", interface, ", GPIB address: ", adr)
print("Instrument ID: ", dmm.query("*IDN?").strip())
for i in range(5):
# Configure the DMM for DC voltage measurement
dmm.write("CONF:VOLT:DC")
# Take a measurement
value = dmm.query("READ?")
print(i, "DC Voltage =", value.strip(), "V")
time.sleep(2)
# Close the instrument and Resource Manager
dmm.close()
rm.close()
The VISA resource string is constructed with an f-string:
f"{interface}::{adr}::INSTR"
With interface = "GPIB0" and adr = "13", this becomes:
GPIB0::13::INSTR
3. Simple Python GUI Application for One HP 34401A
The next example adds a small Tkinter GUI. It displays the instrument ID, GPIB interface and address, measured DC voltage, and START / STOP / EXIT buttons.
3-1. File
File name: dmm1-gui.py
Download location:
https://github.com/moriyasum/GPIB
✎ Change the GPIB address to match your instrument.
3-2. Run the Program
Install Tkinter for the GUI:
sudo apt install python3-tk
Run program:
python3 ./dmm1-gui.py
3-3. Example GUI

3-4. Python Source Code
import tkinter as tk
import pyvisa
# GPIB address and interface number
adr = "13"
interface = "GPIB0"
# Open VISA
rm = pyvisa.ResourceManager()
dmm = rm.open_resource(f"{interface}::{adr}::INSTR")
dmm.timeout = 5000
# Read instrument ID
idn = dmm.query("*IDN?").strip()
# Configure DC voltage measurement mode
dmm.write("CONF:VOLT:DC")
# GUI
root = tk.Tk()
root.title("HP 34401A DC Voltage Monitor")
root.geometry("500x250")
running = False
voltage_text = tk.StringVar(value="-------- V")
status_text = tk.StringVar(value="STOPPED")
def measure():
if not running:
return
try:
voltage = float(dmm.query("READ?"))
voltage_text.set(f"{voltage:.8f} V")
status_text.set("RUNNING")
except Exception as e:
status_text.set("ERROR: " + str(e))
if running:
root.after(500, measure)
def start():
global running
if not running:
running = True
measure()
def stop():
global running
running = False
status_text.set("STOPPED")
def close():
dmm.close()
rm.close()
root.destroy()
tk.Label(
root,
text=idn,
font=("Arial", 11)
).pack(pady=15)
tk.Label(
root,
text=f"Interface:{interface} GPIB Address:{adr}",
font=("Arial", 12)
).pack()
tk.Label(
root,
textvariable=voltage_text,
font=("Courier", 28, "bold")
).pack(pady=15)
tk.Label(
root,
textvariable=status_text
).pack()
button_frame = tk.Frame(root)
button_frame.pack(pady=15)
tk.Button(
button_frame,
text="START",
command=start,
width=10
).pack(side="left", padx=5)
tk.Button(
button_frame,
text="STOP",
command=stop,
width=10
).pack(side="left", padx=5)
tk.Button(
button_frame,
text="EXIT",
command=close,
width=10
).pack(side="left", padx=5)
root.protocol("WM_DELETE_WINDOW", close)
root.mainloop()
4. Python CLI Application for Three HP 34401A Multimeters
The next example controls three HP 34401A multimeters connected to the same GPIB bus.
The GPIB addresses used in this example are:
- DMM 1: address 11
- DMM 2: address 12
- DMM 3: address 13


4-1. File
File name: dmm3-cli.py
Download location:
https://github.com/moriyasum/GPIB
✎ Change the GPIB address to match your instrument.
4-2. Run the Program
python3 ./dmm3-cli.py
4-3. Example Output
Interface:GPIB0
Instrument 1: Addr=11 HEWLETT-PACKARD,34401A,0,4-1-1
Instrument 2: Addr=12 HEWLETT-PACKARD,34401A,0,5-1-1
Instrument 3: Addr=13 HEWLETT-PACKARD,34401A,0,7-5-2
0 DC Volt: 11= +1.87790000E-05 V, 12= +2.36160000E-05 V, 13= +5.30810000E-05 V
1 DC Volt: 11= +2.15320000E-05 V, 12= +2.77230000E-05 V, 13= +5.66400000E-05 V
2 DC Volt: 11= +2.97650000E-05 V, 12= +3.68070000E-05 V, 13= +4.06650000E-05 V
4-4. Python Source Code
import pyvisa
import time
# GPIB addresses and interface number
adr1 = "11"
adr2 = "12"
adr3 = "13"
interface = "GPIB0"
# Open VISA
rm = pyvisa.ResourceManager()
dmm1 = rm.open_resource(f"{interface}::{adr1}::INSTR")
dmm1.timeout = 5000
dmm2 = rm.open_resource(f"{interface}::{adr2}::INSTR")
dmm2.timeout = 5000
dmm3 = rm.open_resource(f"{interface}::{adr3}::INSTR")
dmm3.timeout = 5000
print(f"Interface:{interface}")
# Read instrument IDs
print(f"Instrument 1: Addr={adr1} ", dmm1.query("*IDN?").strip())
print(f"Instrument 2: Addr={adr2} ", dmm2.query("*IDN?").strip())
print(f"Instrument 3: Addr={adr3} ", dmm3.query("*IDN?").strip())
# Configure all three DMMs for DC voltage measurement
dmm1.write("CONF:VOLT:DC")
dmm2.write("CONF:VOLT:DC")
dmm3.write("CONF:VOLT:DC")
for i in range(10):
value = dmm1.query("READ?")
print(i, "DC Volt:", adr1 + "=", value.strip(), "V, ", end="")
value = dmm2.query("READ?")
print(adr2 + "=", value.strip(), "V, ", end="")
value = dmm3.query("READ?")
print(adr3 + "=", value.strip(), "V")
time.sleep(0.5)
# Close the instruments and Resource Manager
dmm1.close()
dmm2.close()
dmm3.close()
rm.close()
5. Python GUI Data Logger for Three HP 34401A Multimeters
The final Python example expands the three-instrument program into a GUI data logger with real-time display, graphing, and recording.
5-1. File
File name: dmm3-gui-graph-record.py
The full source code is available here:
https://github.com/moriyasum/GPIB/blob/main/dmm3-gui-graph-record.py
✎ Change the GPIB address to match your instrument.
5-2. Run the Program
Install Tkinter for the GUI:
sudo apt install python3-tk
Install Matplotlib for graphing:
sudo apt install python3-matplotlib
Run program:
python3 ./dmm3-gui-graph-record.py
5-3. Example GUI

Example of a recorded data file:

5-4. Python Source Code
Because this program is considerably longer than the previous examples, the complete source code is maintained on GitHub rather than duplicated here:
https://github.com/moriyasum/GPIB/blob/main/dmm3-gui-graph-record.py
The progression of the examples is therefore:
interactive Python → one-DMM CLI → one-DMM GUI →
three-DMM CLI → three-DMM GUI/data logger
This makes it possible to verify each layer of the system before moving to the next one.
USB Connection and Detection Test with Three HP 34401A Multimeters
After confirming operation with the three-DMM Python program, I also tested the NI GPIB-USB-HS with different USB ports on the Intel NUC13ANK.
| USB port | Hot plug (Note) | Hot plug through a powered USB hub | Connected before power-on |
|---|---|---|---|
| USB 3.2 | GOOD | GOOD | GOOD |
| USB 2.0 | GOOD | GOOD | GOOD |
| Thunderbolt 4 | GOOD | GOOD | GOOD |
In these tests, the adapter was detected and communication with the three HP 34401A multimeters worked in all of the connection methods shown above.
✎ Observation during USB hot-plugging
During testing, the HDMI monitor frequently went black for a few seconds at the moment a USB plug was connected directly to the NUC.
On one occasion, Ubuntu also rebooted unexpectedly.
I initially tried a powered USB hub, but a similar event could occur when the powered hub itself was connected to the NUC.
In this test setup, the powered hub did not eliminate the problem.
Ground-Potential Difference Observed in My Test Setup
Further investigation showed a substantial AC potential difference between the NUC chassis/USB ground and the measurement-equipment chassis in my particular setup.
This malfunction caused by the electrical transient during connection occurred only on the NUC in this experiment and did not occur on the Envy or EliteDesk systems.
A powered USB hub did not eliminate the issue in this setup.


In my test setup, after confirming that the chassis/ground points could be safely connected, equalizing their potentials eliminated the USB-connection problem.
Ground/chassis connection used in this test setup:

⚠️ Warning: Do not treat the chassis connection shown above as a general solution.
The connection was made only after checking the particular equipment used in this test. Do not connect the chassis or ground terminals of two devices together unless you have first confirmed that the connection is electrically safe.
In particular, do not make such a connection between equipment connected directly to the AC mains, power equipment, or equipment with an unknown grounding or isolation configuration. A large potential difference or fault current could flow through the added wire, the GPIB cable, or the computer, creating a risk of equipment damage or electric shock.
The important point from this test is that the USB/GPIB software itself was not the only possible cause of connection instability. In this particular setup, an electrical potential difference between the connected equipment was associated with the USB hot-plug symptoms.
NI GPIB-USB-HS Driver Patch Details
This section provides the patch used with the particular NI GPIB-USB-HS adapter tested in this guide.
The installation procedure for applying this patch is described earlier in Section 5, Apply the Special Patch for the NI GPIB-USB-HS.
Driver source file:
ni_usb_gpib.c
Driver source directory:
/opt/linux-gpib-4.3.7/linux-gpib-kernel-4.3.7/drivers/gpib/ni_usb
Patch file:
ni_usb_gpib_709b_linux-gpib-4.3.7.patch
Patch file location used in this guide:
~/Downloads/ni_usb_gpib_709b_linux-gpib-4.3.7.patch
The same patch file is also available from GitHub:
https://github.com/moriyasum/GPIB/blob/main/ni_usb_gpib_709b_linux-gpib-4.3.7.patch
❗ Important
This patch was developed for the particular adapter used in this project, identified as USB ID 3923:709b.
It should not be assumed that every NI GPIB-USB-HS requires this modification. As described in Section 5, first try the original Linux-GPIB 4.3.7 driver. Apply this patch only if the adapter cannot be initialized or used correctly with the original driver.
Patch File
The following is the complete patch used in this guide:
--- a/drivers/gpib/ni_usb/ni_usb_gpib.c
+++ b/drivers/gpib/ni_usb/ni_usb_gpib.c
@@ -479,6 +479,18 @@
i - 1, (int)raw_data[i - 1]);
unexpected = 1;
}
+
+ /*
+ * NI GPIB-USB-HS (3923:709b) may omit the register-write status
+ * block here and proceed directly to the termination block.
+ */
+ if (raw_data[i] == NIUSB_TERM_ID) {
+ i += ni_usb_parse_termination_block(&raw_data[i]);
+ if (unexpected)
+ ni_usb_dump_raw_block(raw_data, i);
+ return i;
+ }
+
i += ni_usb_parse_status_block(&raw_data[i], ®ister_write_status);
if (register_write_status.id != NIUSB_REG_WRITE_ID) {
pr_err("unexpected data: register write status id=0x%x, expected 0x%x\n",
@@ -1015,6 +1027,14 @@
int i = 0;
struct ni_usb_status_block status;
+ /*
+ * On 3923:709b, sending NIUSB_IBGTS (0x06) after GPIB addressing
+ * causes the following data write to fail with NIUSB_ADDRESSING_ERROR.
+ * Keeping the adapter in its current state allows the write to succeed.
+ */
+ if (ni_priv->product_id == USB_DEVICE_ID_NI_USB_HS)
+ return 0;
+
if (!ni_priv->bus_interface)
return -ENODEV;
usb_dev = interface_to_usbdev(ni_priv->bus_interface);
@@ -1853,11 +1873,21 @@
{
int retval;
struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
+ struct usb_device *usb_dev;
static const int buffer_length = 8;
u8 *buffer;
struct ni_usb_status_block status;
unsigned long flags;
+
+ /*
+ * NI GPIB-USB-HS (3923:709b) does not tolerate the interrupt-monitor
+ * control request used by this driver during initialization.
+ * Normal GPIB transfers work through the bulk endpoints without it.
+ */
+ if (ni_priv->product_id == USB_DEVICE_ID_NI_USB_HS)
+ return 0;
+
+ usb_dev = interface_to_usbdev(ni_priv->bus_interface);
buffer = kmalloc(buffer_length, GFP_KERNEL);
if (!buffer)
@@ -1886,6 +1916,13 @@
struct usb_device *usb_dev;
int int_pipe;
int retval;
+
+ /*
+ * The 3923:709b compatibility path uses synchronous bulk transfers
+ * only; do not start the interrupt endpoint.
+ */
+ if (ni_priv->product_id == USB_DEVICE_ID_NI_USB_HS)
+ return 0;
if (ni_priv->interrupt_in_endpoint < 0)
return 0;
❗ Important
Keep the patch file exactly as shown.
Do not modify its whitespace or context lines.
Conclusion
The NI GPIB-USB-HS used in this project was successfully operated on Ubuntu with Linux-GPIB 4.3.7 after applying the adapter-specific patch described in this guide.
Communication was verified with Linux-GPIB utilities, PyVISA, and Python programs using one and three HP 34401A multimeters. The three-instrument GUI/data-logger example also demonstrated continuous measurements through the same GPIB interface.
Because the patch and some of the observed USB behavior are specific to the hardware and test environment used here, they should be treated as test results from this setup rather than as requirements for every NI GPIB-USB-HS.