Skip to main content

PSU simulator

The PSU simulator is a local SCPI server for development, tests, and demos. It listens on a TCP socket, exposes a programmable power-supply command set, and includes a terminal UI for editing channel loads, probe resistance, and channel limits while your code is running.

Quickstart

Start the simulator in one terminal:
It binds to 127.0.0.1:5025 by default. If you are working from a source checkout, run the same command through uv:
Connect from another terminal or script with the SimulatedPSU driver. This small Python client opens an InstroPSU, configures channel 1, and reads voltage and current measurements:
Use CLI flags to change the bind address, port, or initial channel count:

Usage

The simulator runs a terminal UI while the TCP server listens in the background. The UI is organized by panel header. PSU simulator terminal UI showing the PSU panel, channel panels, and SCPI log Filled labels are selectable actions. Use the arrow keys to move between controls. Focused actions use a light highlight. Press Enter to select an action, Escape to close an edit prompt, and q to quit.

PSU

The ⟢ NOMINAL PSU panel shows the simulator identity and VISA resource string. Use the resource string when driver code connects to the simulator.

Channel

Each CHANNEL panel shows the live state for one output. The panel is split into status, voltage, and current sections. Changing V LIMIT or I LIMIT runs *RST. The output turns off, programmed voltage and current return to zero, protection state turns off, and OVP/OCP levels return to the configured V/I limits.

Probe

The PROBE panel shows sense lead resistance. Select PROBE R to edit the probe resistance in ohms.

Load

The LOAD panel shows the external load model. Select R to edit load resistance in ohms. Select EMF to edit the series electromotive force in volts.

+ channel

The + CHANNEL panel adds a new output channel with the next available channel ID.

SCPI log

The SCPI LOG panel records incoming commands, responses, and queued errors. It is read-only.

Programming guide

Brackets mark optional SCPI path components. For example, [SOURce:]VOLTage[:LEVel] accepts VOLT, VOLT:LEV, SOUR:VOLT, and SOUR:VOLT:LEV. Angle brackets mark command arguments. They are notation only; do not include the angle brackets in the command.
  • <NRf+> is a positive flexible numeric value, such as 0, 1.25, or 1e-3.
  • <literal|literal> is one literal value from the listed options.
The pipe character (|) means OR. For example, <LOC|REM> accepts LOC or REM, and <NRf+|MIN|MAX> accepts one numeric value, MIN, or MAX. Do not send the pipe character in the command. MIN maps to 0. MAX maps to V LIMIT for voltage and OVP commands, and I LIMIT for current and OCP commands. Do not send MIN or MAX to queries.

Defaults and reset

On startup and after *RST, each channel uses the reset operating state: *RST preserves simulator configuration, including channel count, channel IDs, load resistance, series EMF, probe resistance, sense mode, and configured channel limits.

Error queue

Errors are queued and returned one at a time by SYSTem:ERRor?. The simulator can emit these error codes:

Common commands

*IDN?
Query simulator identityResponse: String
*RST
Reset channel operating state and clear errorsResponse: None
*CLS
Clear the error queueResponse: None

MEASure subsystem

MEASure:CURRent?
Measure output currentResponse: Number
MEASure:VOLTage?
Measure output voltageResponse: Number

OUTPut subsystem

OUTPut[:STATe] <0|1|OFF|ON>
Enable or disable outputResponse: None
OUTPut[:STATe]?
Query output stateResponse: 0 or 1
OUTPut:PROTection:CLEar
Clear latched OVP and OCP faultsResponse: None
OUTPut:PROTection:TRIPped?
Query latched OVP or OCP fault stateResponse: 0 or 1

SOURce subsystem

[SOURce:]CURRent[:LEVel][:IMMediate][:AMPLitude] <NRf+|MIN|MAX>
Set current limitResponse: None
[SOURce:]CURRent[:LEVel][:IMMediate][:AMPLitude]?
Query current limitResponse: Number
[SOURce:]CURRent:PROTection[:LEVel] <NRf+|MIN|MAX>
Set OCP levelResponse: None
[SOURce:]CURRent:PROTection[:LEVel]?
Query OCP levelResponse: Number
[SOURce:]CURRent:PROTection:STATe <0|1|OFF|ON>
Enable or disable OCPResponse: None
[SOURce:]CURRent:PROTection:STATe?
Query OCP stateResponse: 0 or 1
[SOURce:]VOLTage[:LEVel][:IMMediate][:AMPLitude] <NRf+|MIN|MAX>
Set programmed voltageResponse: None
[SOURce:]VOLTage[:LEVel][:IMMediate][:AMPLitude]?
Query programmed voltageResponse: Number
[SOURce:]VOLTage:PROTection[:LEVel] <NRf+|MIN|MAX>
Set OVP levelResponse: None
[SOURce:]VOLTage:PROTection[:LEVel]?
Query OVP levelResponse: Number
[SOURce:]VOLTage:PROTection:STATe <0|1|OFF|ON>
Enable or disable OVPResponse: None
[SOURce:]VOLTage:PROTection:STATe?
Query OVP stateResponse: 0 or 1

SYSTem subsystem

SYSTem:ERRor?
Pop one error from the error queueResponse: code,“message”
SYSTem:SENSe[:STATe] <LOC|REM>
Select local or remote senseResponse: None
SYSTem:SENSe[:STATe]?
Query sense modeResponse: LOC or REM