Developing instrument drivers¶
An instrument driver translates the public API of an instrument class into the protocol of a concrete device. Communication details and domain measurement workflows remain outside the specific driver.
See common instrument-driver behavior for the normative runtime rules covering status codes, return shapes, initialization, bus policy, quantities, and safety. This page focuses on implementing a concrete driver.
Choose the correct base class¶
A power meter derives from POWERMETER, a receiver from RECEIVER, and
a signal generator from SIGNALGENERATOR. These base classes define method
names, the unit contract, configuration schema, and shared fallbacks. Derive
directly from DRIVER only when introducing a new instrument class.
from mpylab.device.powermeter import POWERMETER as BasePowerMeter
class POWERMETER(BasePowerMeter):
def __init__(self, SearchPaths=None):
super().__init__(SearchPaths=SearchPaths)
self._internal_unit = "dBm"
Return shape and signature always follow the base class. Queries commonly
return (status, value); action methods may return status alone.
Measurement values are SCUQ quantities expressed in the requested channel
unit.
Initialization¶
All maintained drivers use the signature
Init(ini=None, channel=None, ignore_bus=None). None selects the
driver-specific default: active instruments normally open their bus, while
purely passive and virtual drivers set _default_ignore_bus = True.
Explicit True or False overrides that default.
super().Init(ini, channel, ignore_bus=ignore_bus) reads the INI file,
resolves the bus policy, and establishes the communication class when needed.
The resolved policy is available as self.bus_ignored. A concrete active
driver returns on self.error or self.bus_ignored before sending
presets, mode changes, or other instrument commands. A failed mode or range
change must not silently be treated as success.
Communication¶
DRIVER provides write, read, and query through a
communication class. This unifies GPIB, VISA, Prologix, and debug/virtual
operation. Access self.dev directly only when the shared interface cannot
represent a required operation.
Consume replies completely. Multiline or additionally terminated replies need an explicit drain strategy so residual data cannot corrupt the next query.
Units¶
_internal_unit is the fixed unit in which the device accepts or returns
values. The channel unit from the INI file is the unit requested by the user.
Use mpylab.tools.uconv for conversion instead of local dB formulas.
Virtual driver and tests¶
A virtual driver exposing the same public API is useful for new instrument classes and complex APIs. Tests cover at least:
initialization without hardware;
command formatting and response parsing;
units and uncertainty;
invalid parameters and instrument status;
multichannel instances without shared mutable state;
trigger, nonblocking, and timeout behavior;
safe
Quitand RF-off where applicable.
Inline smoke tests and example INI files help with later hardware testing but do not replace automated tests.
Drivers exposing several logical graph nodes through one physical device must additionally follow the multichannel controller and facade model.