PyVISA
PyVISADocs

Multimeter Example

How to automate a Keysight 34461A digital multimeter with PyVISA. DC/AC voltage, current, resistance, and fast burst measurements.

Automate a Keysight 34461A (or any SCPI-compatible DMM) with PyVISA. Connect, measure, and configure for speed or accuracy.

Connect and Measure

import pyvisa

rm = pyvisa.ResourceManager()
dmm = rm.open_resource("USB0::0x2A8D::0x0101::MY53220001::INSTR")

try:
    dmm.timeout = 10000
    dmm.write_termination = '\n'
    dmm.read_termination = '\n'

    idn = dmm.query("*IDN?")
    print(f"Connected to: {idn.strip()}")

    dmm.write("*RST")
    dmm.write("*CLS")

    voltage = float(dmm.query("MEAS:VOLT:DC?"))
    print(f"DC Voltage: {voltage:.6f} V")
finally:
    dmm.close()
    rm.close()

Basic Measurements

All standard DMM functions use the same pattern: CONF, then READ?.

import pyvisa
import time

rm = pyvisa.ResourceManager()
dmm = rm.open_resource("USB0::0x2A8D::0x0101::MY53220001::INSTR")
dmm.timeout = 10000

try:
    # DC Voltage
    dmm.write("CONF:VOLT:DC")
    dc_v = float(dmm.query("READ?"))

    # AC Voltage
    dmm.write("CONF:VOLT:AC")
    ac_v = float(dmm.query("READ?"))

    # DC Current
    dmm.write("CONF:CURR:DC")
    dc_i = float(dmm.query("READ?"))

    # 2-wire resistance
    dmm.write("CONF:RES")
    res_2w = float(dmm.query("READ?"))

    # 4-wire resistance (more accurate for low values)
    dmm.write("CONF:FRES")
    res_4w = float(dmm.query("READ?"))

    print(f"DC Voltage:  {dc_v:.6f} V")
    print(f"AC Voltage:  {ac_v:.6f} V")
    print(f"DC Current:  {dc_i:.6f} A")
    print(f"Resistance (2W): {res_2w:.2f} ohm")
    print(f"Resistance (4W): {res_4w:.2f} ohm")
finally:
    dmm.close()
    rm.close()

Log measurements automatically

TofuPilot logs voltage and resistance measurements with limits and pass/fail status across production runs. Free to start.

Advanced Configuration

ParameterSCPI CommandValuesDefault
Integration timeVOLT:DC:NPLC0.02, 0.2, 1, 10, 100 PLC1
RangeVOLT:DC:RANG0.1, 1, 10, 100, 1000 VAUTO
AutozeroVOLT:DC:ZERO:AUTOON, OFFON
ResolutionVOLT:DC:RESMIN, MAX, or numericMedium
Input impedanceVOLT:DC:IMP10e6 (10 MOhm), 10e9 (10 GOhm)10e9

High-Accuracy Setup

For calibration or reference measurements, maximize integration time and fix the range:

# Configure for best accuracy (slowest)
dmm.write("CONF:VOLT:DC")
dmm.write("VOLT:DC:NPLC 100")        # 100 PLC
dmm.write("VOLT:DC:RANG 10")         # Fixed 10 V range
dmm.write("VOLT:DC:ZERO:AUTO ON")    # Drift compensation
dmm.write("VOLT:DC:IMP:AUTO OFF")
dmm.write("VOLT:DC:IMP 10e9")        # 10 GOhm input impedance

voltage = float(dmm.query("READ?"))
print(f"High-accuracy reading: {voltage:.8f} V")

Statistical Sampling

import statistics

dmm.write("CONF:VOLT:DC")
dmm.write("VOLT:DC:NPLC 10")

readings = []
for i in range(20):
    v = float(dmm.query("READ?"))
    readings.append(v)

mean = statistics.mean(readings)
stdev = statistics.stdev(readings)
print(f"Mean: {mean:.8f} V, Stdev: {stdev:.8f} V")
print(f"Range: {min(readings):.8f} to {max(readings):.8f} V")

Fast Burst Measurement

For monitoring or high-throughput testing, minimize integration time and read all samples in one transfer.

import pyvisa
import time

rm = pyvisa.ResourceManager()
dmm = rm.open_resource("USB0::0x2A8D::0x0101::MY53220001::INSTR")
dmm.timeout = 30000

try:
    count = 100
    dmm.write("CONF:VOLT:DC")
    dmm.write("VOLT:DC:NPLC 0.02")       # Minimum integration
    dmm.write("VOLT:DC:ZERO:AUTO OFF")   # Skip autozero
    dmm.write(f"SAMP:COUN {count}")

    start = time.time()
    response = dmm.query("READ?")
    elapsed = time.time() - start

    values = [float(x) for x in response.split(',')]
    rate = len(values) / elapsed

    print(f"{len(values)} readings in {elapsed:.3f} s ({rate:.0f} readings/s)")
finally:
    dmm.close()
    rm.close()

SCPI Commands Used

CommandPurpose
CONF:VOLT:DCConfigure for DC voltage measurement
CONF:VOLT:ACConfigure for AC voltage measurement
CONF:CURR:DCConfigure for DC current measurement
CONF:RESConfigure for 2-wire resistance
CONF:FRESConfigure for 4-wire resistance
READ?Trigger and return measurement
SAMP:COUN <n>Number of samples per trigger
VOLT:DC:NPLC <n>Integration time in power line cycles
VOLT:DC:ZERO:AUTO OFFDisable autozero for speed

Tips

  • If readings are noisy, increase NPLC (integration time)
  • Use a fixed range when you know the expected value. Auto-ranging adds switching noise.
  • For low resistance (under 100 ohm), use 4-wire (CONF:FRES) to eliminate lead resistance
  • Check SYST:ERR? after configuration to catch typos in SCPI commands