DAQ (Data Acquisition)¤
Interface¤
Bases: Instrument
Parameters:
-
(name¤str) –Channel-name prefix for published data.
-
(driver¤DAQDriverBase) –Concrete DAQ driver; owns its own transport::
daq = InstroDAQ( "myDAQ", driver=Keysight34980A("USB0::0x0957::0x0507::MY44001757::INSTR"), )
-
(publishers¤list[Publisher] | None, default:None) –Publishers that receive emitted Measurement/Command data.
-
–**kwargs¤Default tags applied to every emitted Measurement/Command. Pass
dataset_rid="<rid>"to auto-create a NominalCorePublisher (uses the on-disk 'default' Nominal credential).
background_interval
property
writable
¤
background_interval: float
Always 0 for DAQ: blocking reads implicitly time the daemon loop via samples_per_channel.
background_enable
property
writable
¤
background_enable: bool
Whether the background daemon is enabled.
add_publisher
¤
add_publisher(publisher: Publisher)
Register a publisher to receive this instrument's Measurement/Command data.
publish
¤
publish(data: Measurement | Command, **kwargs)
Fan data out to every configured publisher; kwargs pass through.
add_background_daemon_function
¤
add_background_daemon_function(method: Callable, *args, **kwargs)
Append method to the daemon's call list. Use define_background_daemon to replace instead.
get_channel
¤
get_channel(
channel_name: str,
length: int = 1,
wait_for_latest: bool = False,
timeout: float = 10.0,
) -> Measurement
Return the most recent length samples for channel_name from the in-memory buffer.
Parameters:
-
(channel_name¤str) –Name of the channel to retrieve.
-
(length¤int, default:1) –Number of trailing samples to return.
-
(wait_for_latest¤bool, default:False) –Block until at least
lengthnew values arrive. -
(timeout¤float, default:10.0) –Seconds to wait when
wait_for_latest=True.
Raises:
-
RuntimeError–No background buffer;
start()was not called. -
ChannelNotFoundTimeoutError–wait_for_latest=Trueand channel did not appear withintimeout. -
ChannelValueTimeoutError–wait_for_latest=Trueand values did not arrive withintimeout.
define_background_daemon
¤
define_background_daemon(method: Callable, *args, **kwargs)
Replace all daemon functions with a single method (called with the given args).
configure_analog_channel
¤
configure_analog_channel(
direction: Direction,
physical_channel: str,
alias: str | None = None,
range_min: float = -10.0,
range_max: float = 10.0,
scaler: Scaler | None = None,
terminal_config: TerminalConfig | None = None,
)
Configure an analog channel.
Parameters:
-
(direction¤Direction) –INPUTorOUTPUT. -
(physical_channel¤str) –Vendor-specific channel id (e.g.
"ai0"or"Dev1/ai0"). -
(alias¤str | None, default:None) –Friendly name; defaults to
physical_channel. -
(range_min¤float, default:-10.0) –Lower voltage range (volts).
-
(range_max¤float, default:10.0) –Upper voltage range (volts).
-
(scaler¤Scaler | None, default:None) –Optional
Scalerapplied to AI samples after read. -
(terminal_config¤TerminalConfig | None, default:None) –Terminal wiring (RSE / NRSE / DIFF) for the channel.
configure_ai_sample_rate
¤
configure_ai_sample_rate(
sample_rate: float, samples_per_channel: int | None = None, **kwargs
)
start
¤
start(**kwargs)
Start hardware-timed acquisition.
Parameters:
-
–**kwargs¤channel_type(NI only) selects which DAQmx task to start.
read_analog
¤
read_analog(**kwargs) -> Measurement | list[Measurement]
Dispatch a hardware-timed buffer fetch or a software-timed conversion based on configuration.
Each branch publishes its own Measurements; this dispatcher does not. Hardware-timed with the background daemon running raises — the daemon owns the buffer. Returns a single Measurement when channels share a timebase, otherwise one Measurement per timebase cluster.
write_analog_value
¤
Write value (volts) to AO channel (alias). Raises KeyError if channel isn't configured.
configure_digital_channel
¤
configure_digital_channel(
direction: Direction,
physical_channel: str,
logic: Logic,
logic_level: float | None = None,
alias: str | None = None,
port_width: DigitalPortWidth | None = None,
)
Configure a digital channel.
Parameters:
-
(direction¤Direction) –INPUTorOUTPUT. -
(physical_channel¤str) –Vendor-specific id (e.g.
"di0"or"port0/line0"). -
(logic¤Logic) –Active-
HIGHor active-LOW. -
(logic_level¤float | None, default:None) –Voltage threshold (volts); the driver default is used when
None. -
(alias¤str | None, default:None) –Friendly name; defaults to
physical_channel. -
(port_width¤DigitalPortWidth | None, default:None) –Port width in bits (8/16/32/64) when treating the channel as a port rather than a line.
write_digital_line
¤
Write 0/1 to DO line channel (alias). Raises KeyError if channel isn't configured.
read_digital_line
¤
read_digital_line(channel: str, **kwargs) -> Measurement
Read DI line channel (alias). Raises KeyError if channel isn't configured.
write_digital_port
¤
Write data to DO port channel (alias). Raises KeyError if channel isn't configured.
read_digital_port
¤
read_digital_port(channel: str, **kwargs) -> Measurement
Read DI port channel (alias). Raises KeyError if channel isn't configured.
configure_relay_channel
¤
Configure a relay channel (physical_channel e.g. "3101" = slot 3 / channel 101).
close_relay
¤
Close relay channel (alias) — connects the circuit.
open_relay
¤
Open relay channel (alias) — disconnects the circuit.
get_actual_sample_rate
¤
get_actual_sample_rate() -> float | None
Hardware's actual sample rate after start(); None if unsupported or not started.
get_points_in_buffer
¤
get_points_in_buffer(**kwargs) -> Measurement
Publish the current DAQ buffer depth on channel {name}.buffer.
Types & Configuration¤
DAQ shared types: vendors, channel types, terminal configs, hardware-timing config.
ChannelType
¤
Logic
¤
Direction
¤
TerminalConfig
¤
HWTimingConfig
dataclass
¤
DAQChannel
dataclass
¤
AnalogChannel
dataclass
¤
AnalogChannel(
range_max: float,
range_min: float,
scaler: Scaler | None,
terminal_config: TerminalConfig | None = None,
*,
physical_channel: str,
alias: str,
direction: Direction,
)
Bases: DAQChannel
DigitalPortWidth
¤
DigitalChannel
dataclass
¤
DigitalPortChannel
dataclass
¤
DigitalPortChannel(
logic_level: float | None,
logic: Logic,
width: DigitalPortWidth,
*,
physical_channel: str,
alias: str,
direction: Direction,
)
Bases: DigitalChannel
DigitalLineChannel
dataclass
¤
DigitalLineChannel(
logic_level: float | None,
logic: Logic,
bit_position: int | None = None,
*,
physical_channel: str,
alias: str,
direction: Direction,
)
Bases: DigitalChannel
RelayChannel
dataclass
¤
Scaling¤
Thermocouple Scaling¤
Driver Interface¤
Bases: ABC
Vendor DAQ driver contract. Concrete drivers own their transport and lifecycle.
The composed InstroDAQ installs an InstroDAQFacade (implements
APIInstroDAQ) onto self.hal so drivers can read back configured
channels and timing without coupling to the instrument's internal state.
open
abstractmethod
¤
open()
Open the underlying transport (or verify the device is present, for handle-less SDKs).
configure_ai_channel
abstractmethod
¤
configure_ai_channel(channel: AnalogChannel)
Register an AI channel with the underlying driver (range, terminal mode, scaler — vendor-specific).
configure_ao_channel
¤
configure_ao_channel(channel: AnalogChannel)
Register an AO channel. Default is a no-op; override if the driver supports analog output.
configure_ai_hw_timing
abstractmethod
¤
configure_ai_hw_timing(hw_timing_config: HWTimingConfig)
Configure hardware-timed AI sampling at hw_timing_config.sample_rate.
Called before start() whenever InstroDAQ.configure_ai_sample_rate()
is invoked. The driver should program the sample clock and any
samples_per_channel buffer sizing the underlying SDK requires.
define_digital_channel
abstractmethod
¤
define_digital_channel(
direction: Direction,
physical_channel: str,
logic: Logic,
logic_level: float | None = None,
alias: str | None = None,
port_width: DigitalPortWidth | None = None,
) -> DigitalChannel
Parse a vendor-specific physical_channel string into a DigitalLineChannel or DigitalPortChannel.
port_width is supplied for port-mode channels; line-mode channels
encode their bit position in physical_channel per vendor convention
(e.g. "port0/line3" on NI, "5101/3" on Keysight 34980A,
"AUXPORT0/1" on MCC).
configure_do_channel
abstractmethod
¤
configure_do_channel(channel: DigitalChannel)
Register a DO channel (line or port) with the underlying driver.
configure_di_channel
abstractmethod
¤
configure_di_channel(channel: DigitalChannel)
Register a DI channel (line or port) with the underlying driver.
start
abstractmethod
¤
start(**kwargs)
Start hardware-timed acquisition.
InstroDAQ passes channel_type=<ChannelType> when the user
targets a specific task (e.g. on NI, where AI/AO/DI/DO each have their
own DAQmx task). Drivers without that distinction can ignore it.
stop
abstractmethod
¤
stop(**kwargs)
Stop a running acquisition and release any scan buffers. channel_type mirrors :meth:start.
read_analog
abstractmethod
¤
read_analog() -> Any
Software-timed read of every configured AI channel.
Returns a vendor-specific payload that _read_to_measurements then
unpacks into Measurements. response.dt should be None so
the wrapper timestamps with wall-clock time.
fetch_analog
abstractmethod
¤
fetch_analog() -> Any
Block until samples_per_channel new AI samples are available, then return them.
Drivers should set self.points_in_buffer for buffer-depth
telemetry and return dt (ns per sample) so the wrapper can
build contiguous timestamps via HWTimestamper.
get_actual_sample_rate
¤
get_actual_sample_rate() -> float | None
Actual hardware sample rate achieved after start().
Default returns None (driver doesn't know or hasn't started).
Override on drivers whose SDK reports the effective rate (NI, MCC,
LabJack T-series all do).
write_analog_value
¤
write_analog_value(channel: AnalogChannel, value: float)
Write value to AO channel. Override if the driver supports analog output.
write_digital_line
abstractmethod
¤
write_digital_line(channel: DigitalChannel, data: int)
Drive a single DO line. data is 0 or 1 (active-low channel.logic is handled in the driver).
read_digital_line
abstractmethod
¤
read_digital_line(channel: DigitalChannel) -> int
Sample a single DI line. Returns 0 or 1 after applying channel.logic.
write_digital_port
abstractmethod
¤
write_digital_port(channel: DigitalChannel, data: int)
Drive a multi-line DO port. data is an N-bit integer; bit i controls line i.
read_digital_port
abstractmethod
¤
read_digital_port(channel: DigitalChannel) -> int
Sample a multi-line DI port. Returns an N-bit integer; bit i reflects line i.
define_relay_channel
¤
define_relay_channel(
physical_channel: str, alias: str | None = None
) -> RelayChannel
Build a RelayChannel for physical_channel (e.g. "3101" = slot 3 / channel 101).
Default implementation suits the Keysight 34980A's slot/channel addressing; override if the driver needs different parsing.
close_relay
¤
close_relay(channel: RelayChannel)
Close the relay (connect the circuit). Override if the driver supports relays.
open_relay
¤
open_relay(channel: RelayChannel)
Open the relay (disconnect the circuit). Override if the driver supports relays.
Contiguous nanosecond timestamps for hardware-timed DAQ batches.
Anchors to the wall clock exactly once via seed(), then advances by
sample period on every next_batch() call — eliminates timestamp overlap
when consecutive reads return in rapid succession.
seed
classmethod
¤
Anchor the timeline at t_wall ns (read-return time of the first batch).
Vendor Drivers¤
Keysight 34980A¤
Keysight 34980A Multifunction Switch/Measure Unit DAQ driver.
KeysightData
dataclass
¤
Keysight34980A
¤
Keysight34980A(
visa_resource: str | VisaConfig, *, sync_system_clock: bool = True
)
Bases: DAQDriverBase
Keysight 34980A Multifunction Switch/Measure Unit.
Parameters:
-
(visa_resource¤str | VisaConfig) –VISA resource string or full
VisaConfig. -
(sync_system_clock¤bool, default:True) –Sync the instrument clock to host UTC on
open()so returned timestamps align with the host. Enabled by default.
configure_ai_channel
¤
configure_ai_channel(channel: AnalogChannel)
Configure an AI channel: CONF:VOLT:DC at computed range, then add to ROUT:SCAN and enable timestamps.
configure_ai_hw_timing
¤
configure_ai_hw_timing(hw_timing_config: HWTimingConfig)
Configure TRIG:SOUR TIMER at the configured sample period and infinite count.
fetch_analog
¤
fetch_analog() -> KeysightData
Block until the buffer holds at least one full per-channel batch, then drain a channel-aligned chunk.
define_digital_channel
¤
define_digital_channel(
direction: Direction,
physical_channel: str,
logic: Logic,
logic_level: float | None = None,
alias: str | None = None,
port_width: DigitalPortWidth | None = None,
) -> DigitalChannel
configure_do_channel
¤
configure_do_channel(channel: DigitalChannel)
Configure DO width/direction/polarity/drive/level for channel.
configure_di_channel
¤
configure_di_channel(channel: DigitalChannel)
Configure DI width/direction/polarity/drive/level for channel.
configure_ao_channel
¤
configure_ao_channel(channel: AnalogChannel)
Register an AO channel. Default is a no-op; override if the driver supports analog output.
get_actual_sample_rate
¤
get_actual_sample_rate() -> float | None
Actual hardware sample rate achieved after start().
Default returns None (driver doesn't know or hasn't started).
Override on drivers whose SDK reports the effective rate (NI, MCC,
LabJack T-series all do).
write_analog_value
¤
write_analog_value(channel: AnalogChannel, value: float)
Write value to AO channel. Override if the driver supports analog output.
define_relay_channel
¤
define_relay_channel(
physical_channel: str, alias: str | None = None
) -> RelayChannel
Build a RelayChannel for physical_channel (e.g. "3101" = slot 3 / channel 101).
Default implementation suits the Keysight 34980A's slot/channel addressing; override if the driver needs different parsing.
keysight_str_to_ns
¤
Convert a Keysight "YYYY,MM,DD,HH,MM,SS.sss" timestamp (UTC) to ns since the Unix epoch.
parse_datastring
¤
Split a Keysight reading/timestamp data string into (measurements, timestamps_ns).