Skip to content

scpi

tested on simulator

Tier Tier 1
Protocol SCPI over USB-TMC, SCPI over LAN (VXI-11, HiSLIP, raw socket), SCPI over serial, SCPI over GPIB
Covers bench power supplies, multimeters, oscilloscopes, function generators, electronic loads
Hazard default medium
Conformance control
Tested with TCP SCPI simulator through PyVISA and pyvisa-py, and pyvisa-sim

Estimated reach. Thousands of models. SCPI has been the standard command language for programmable test equipment since 1990, and every major vendor (Keysight, Rohde and Schwarz, Tektronix and Keithley, Rigol, Siglent, GW Instek, B&K Precision) ships SCPI on its current bench lines. Any of them works with a device file. describe() proposes channels for the common supply, meter, load, generator and scope families from the IDN reply.

The scpi driver connects to programmable test instruments over VISA with PyVISA 1.16.2 and pyvisa-py 0.8.1. Bench supplies, multimeters, electronic loads, function generators and oscilloscopes use SCPI over USB-TMC, LAN, serial or GPIB. Each channel map gives the query or setting command, and describe() drafts channels for common families from the *IDN? reply.

Supports

  • SYST:ERR? after every setting until the queue reports 0, so any error fails the command with the instrument's message, such as -222,"Data out of range".
  • Health through *OPC?.
  • resource: auto picks the one USB instrument matching match.usb, and match.scpi_idn is checked against *IDN? on every connect.
  • resource: sim:scope or sim:supply connects to a simulated oscilloscope or Rigol DP832 supply, served in the hub's process on a loopback port.

Channel maps

KeyUsed byMeaning
queryreadQuery such as MEAS:VOLT? CH1
setwriteSetting template with {value}, or {on_off} for ON or OFF on bools
getwriteReadback query. Without one, a read returns the last value sent
commandactionTemplate with the action's argument names
parse, scale, offset, unit, on, off, lookupread, writeAs in docs/drivers/serial.md

An image channel's query, such as :DISP:DATA? PNG, returns an IEEE 488.2 definite-length block holding a PNG, JPEG or GIF. A reading of 9.9E37 or more fails as an invalid measurement. unit is the instrument's unit, so a mA channel can read a query in amps. Numbers use Python format specs such as {value:.3f}. Templates are checked at load, and a rendered command with a control character is blocked. Each change records the SCPI lines sent in the audit entry's native field.

Describe

The draft always has device and match.scpi_idn, plus channels for the family.

FamilyMatched byDraft
Rigol DP800, Siglent SPDIDN model DP8.., SPD..voltage and current reads per channel, output switch, set actions when the ratings are known. Siglent SPD gets separate CHn:VOLT and CHn:CURR actions and no output read back
Keysight E36300E363..Athe same with (@n) channel lists
MultimetersKeysight 344xx, Rigol DM, Siglent SDM, Keithley 2000 and DMMDC voltage, DC current and resistance reads
Electronic loadsRigol DL3000, Siglent SDLvoltage, current and power reads, input switch
GeneratorsRigol DG, Siglent SDG, Keysight 33500 and 33600channel 1 frequency read and output switch
ScopesRigol DS, MSO and DHO, Siglent SDStrigger status
Simulated scopeOpenHAL,SIM-SCOPEthe channels of simulated-scope.hal.yaml

Drafted writes and actions are suggested: true with rated limits at most. High risk entries stay read-only until a person lowers and confirms the limits, and low and medium ones work within the rated limits.

Setup

  1. Install with uv tool install --compile-bytecode "halkit[scpi] @ git+https://github.com/sohan-bhat/OpenHAL", which brings pyusb and pyserial. USB-TMC also needs the system libusb.
  2. On Linux, add a udev rule for the vendor id.
  3. Find the resource with python -m pyvisa info and python -c "import pyvisa; print(pyvisa.ResourceManager('@py').list_resources())".
  4. Start from openhal/drivers/scpi/examples/rigol-dp832.hal.yaml or describe(). openhal/drivers/scpi/examples/simulated-scope.hal.yaml drives the simulated scope with no hardware.
KeyDefaultMeaning
resourcerequiredVISA resource such as USB0::0x1AB1::0x0E11::DP8C1234::INSTR or TCPIP0::192.168.1.20::5025::SOCKET, auto, sim:scope or sim:supply
visa_library@py@py for pyvisa-py, an NI-VISA path, or file.yaml@sim for pyvisa-sim
timeout2 sPer exchange
terminationlflf, crlf or cr
check_errorstrueRead SYST:ERR? after every setting
baudnoneBaud rate for ASRL resources

Known limitations

  • No binary block transfers such as screenshots or waveforms. string suits short text replies only.
  • Instruments without SYST:ERR? need check_errors: false, and failed settings then pass silently.
  • After a timeout the VISA session reopens, so a late reply can't pass as the next response and slow instruments may take one extra timeout to recover.
  • The first ResourceManager('@py') in a process can take several seconds.
  • Supplies keep outputs on after the host disconnects, and the safe state runs only while the hub reaches the instrument.

Hazard defaults

medium, since supplies and loads can damage circuits and start fires. safe_state comes from the device file only, since SCPI has no universal outputs-off command. Keep confirm-each-time on output switches and set actions.

Sources