mcp_io_scpi 0.2.1
mcp_io_scpi: ^0.2.1 copied to clipboard
SCPI (Standard Commands for Programmable Instruments) adapter for mcp_io. Text command/response protocol over TCP.
mcp_io_scpi #
SCPI / IEEE 488.2 adapter for mcp_io —
oscilloscopes, DMMs, signal generators and any other test instrument
that speaks SCPI over a byte transport.
Capability matrix #
| Area | Support |
|---|---|
| Transport | TCP raw (5024), Telnet (5025), pluggable ScpiTransport (USB-TMC / VXI-11 via integrator) |
| IEEE 488.2 mandatory | *IDN?, *RST, *CLS, *OPC[?], *WAI, *SRE[?], *STB?, *ESE[?], *ESR?, *TST? |
| Response parsers | NR1 / NR2 / NR3 numeric, boolean, string, comma list, IEEE 488.2 definite-length binary block (#<n><len>), indefinite block |
| Status | Status Byte (STB), Event Status Register (ESR), *OPC? sync, SCPI error queue (:SYST:ERR?) |
| Subscribe | Polling on :MEAS:*?, waveform binary streaming (chunked + preamble meta) |
| Terminator | \n / \r\n / \r / EOI (transport-configurable) |
| Vendor catalog | Keysight DSO-X / DMM, Tektronix DPO/MSO, Rohde & Schwarz RT, Yokogawa DLM/DL, Keithley DMM |
Quick start #
import 'package:mcp_io_scpi/mcp_io_scpi.dart';
// Use any ScpiTransport — `InMemoryScpiTransport` for tests, a TCP
// transport for production hardware.
final transport = InMemoryScpiTransport((cmd) {
if (cmd == '*IDN?') return 'Acme,DSO,SN001,1.0';
return null;
});
final adapter = ScpiAdapter(deviceId: 'scope-1', transport: transport);
await adapter.connect();
final r = await adapter.execute(const Command(
action: 'scope.identify', target: '',
));
print(r.result); // {manufacturer: Acme, model: DSO, serial: SN001, firmware: 1.0}
Vendor profiles #
Pre-built command catalogs decouple application-level intent (a
command key, e.g. singleAcquire, channelScaleSet) from the
vendor-specific SCPI line:
import 'package:mcp_io_scpi/mcp_io_scpi.dart';
// 1) Auto-pick a profile from `*IDN?`.
final idn = await Ieee488(transport).identify();
final profile = ScpiVendorProfiles.fromIdn(
'${idn.manufacturer},${idn.model},${idn.serial}',
)!;
// 2) Issue commands by stable key — no vendor branching at the call
// site.
await transport.send(profile.command(ScpiCommandKey.singleAcquire)!);
await transport.send(
profile.commandWith(
ScpiCommandKey.channelScaleSet, {'channel': 1, 'scale': 0.1},
)!,
);
Profiles can be cloned and tweaked with
ScpiVendorProfile.copyWith(base, overrides: {...}).
Capabilities exposed via execute #
scope.identify · scope.reset · scope.clear · scope.measure ·
scope.acquire · scope.set_trigger · scope.set_channel ·
scope.read_waveform · scope.run_recipe.
License #
MIT — see LICENSE.