Skip to content

Allow arbitrary terminal connections for NI DAQmx devices #103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Feb 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions docs/source/devices/ni_daqs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,55 @@ Note that the counter connection is specified using the logical label `'ctr0'`.
The physical wiring for this configuration would have port0/line0 wired directly to PFI9, with PFI1 being sent to the master pseudoclock retriggering system in case of timeout.
If timeouts are not expected/represent experiment failure, this physical connection can be omitted.

In addition to their external ports, some types of NI DAQ modules (PXI, PXIe, CompactDAQ) feature internal ports, known as "terminals" in NI terminology.
Terminals include most clocks and triggers in a module, as well as the external PFIN connections.
The buffered and static digital IO connections are not terminals.
Connections between terminals can be used for sharing clocks or triggers between modules in the same chassis (note: if sufficient clocklines and external inputs are available, it is likely preferable to simply use a unique clockline for each card).
Within labscript, there are two methods for accessing this functionality.
For sharing the clock input signal to other cards, the `clock_mirror_terminal` argument in the constructor can be specified. For example, in a system with two PXI-6733 analog cards in a PXI chassis (which supports 8 internal triggers, named `PXI_TrigN`), the connection table entries are

.. code-block:: python

NI_PXI_6733(name='dev_1',
...,
clock_terminal='/Dev1/PFI0',
clock_mirror_terminal='/Dev1/PXI_Trig0',
MAX_name='Dev1')

NI_PXI_6733(name='dev_2',
...,
clock_terminal='/Dev2/PXI_Trig0',
MAX_name='Dev2')

However, some NI DAQ modules can not be clocked from certain terminal.
To determine this, consult the `Device Routes` tab in NI MAX.
If there is not a `Direct Route` or `Indirect Route` between the clock source and clock destination, the best option is to choose a different `clock_mirror_terminal` if possible.
For some combinations of modules, there will be no pair of triggers linked to all the cards.
To handle this situation, two triggers can be linked using the `connected_terminals` argument.
This argument takes a list of tuples of terminal names, and connects the first terminal to the second terminal.
For example, to share the clock in the previous with an additional PXIe-6535 digital card (which can not use `PXI_Trig0` as a clock), the connection table entries are

.. code-block:: python

NI_PXI_6733(name='dev_1',
...,
clock_terminal='/Dev1/PFI0',
clock_mirror_terminal='/Dev1/PXI_Trig0',
MAX_name='Dev1')

NI_PXI_6733(name='dev_2',
...,
clock_terminal='/Dev2/PXI_Trig0',
MAX_name='Dev2')

NI_PXIe_6535(name='dev_3',
...,
clock_terminal='/Dev3/PXI_Trig7',
MAX_name='Dev3',
connected_terminals=[('/Dev3/PXI_Trig0', '/Dev3/PXI_Trig7')])

In addition to clocking, the `connected_terminals` argument can be used to link output terminals on an NI DAQ module to shared triggers, then link those shared triggers to input terminals of another NI DAQ module in the same chassis.


Detailed Documentation
~~~~~~~~~~~~~~~~~~~~~~
Expand Down
2 changes: 2 additions & 0 deletions labscript_devices/NI_DAQmx/blacs_tabs.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ def initialise_GUI(self):

clock_terminal = properties['clock_terminal']
clock_mirror_terminal = properties['clock_mirror_terminal']
# get to avoid error on older connection tables
connected_terminals = properties.get('connected_terminals', None)
static_AO = properties['static_AO']
static_DO = properties['static_DO']
clock_limit = properties['clock_limit']
Expand Down
23 changes: 23 additions & 0 deletions labscript_devices/NI_DAQmx/blacs_workers.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,23 @@ def set_mirror_clock_terminal_connected(self, connected):
else:
DAQmxDisconnectTerms(self.clock_terminal, self.clock_mirror_terminal)

def set_connected_terminals_connected(self, connected):
"""Connect the terminals in the connected terminals list.
Allows on daisy chaining of the clock line to/from other devices
that do not have a direct route (see Device Routes in NI MAX)."""
if self.connected_terminals is None:
return
if connected:
for terminal_pair in self.connected_terminals:
DAQmxConnectTerms(
terminal_pair[0],
terminal_pair[1],
DAQmx_Val_DoNotInvertPolarity,
)
else:
for terminal_pair in self.connected_terminals:
DAQmxDisconnectTerms(terminal_pair[0], terminal_pair[1])

def program_buffered_DO(self, DO_table):
"""Create the DO task and program in the DO table for a shot. Return a
dictionary of the final values of each channel in use"""
Expand Down Expand Up @@ -320,6 +337,9 @@ def transition_to_buffered(self, device_name, h5file, initial_values, fresh):
# Mirror the clock terminal, if applicable:
self.set_mirror_clock_terminal_connected(True)

# Mirror other terminals, if applicable
self.set_connected_terminals_connected(True)

# Program the output tasks and retrieve the final values of each output:
DO_final_values = self.program_buffered_DO(DO_table)
AO_final_values = self.program_buffered_AO(AO_table)
Expand Down Expand Up @@ -372,6 +392,9 @@ def transition_to_manual(self, abort=False):
# Remove the mirroring of the clock terminal, if applicable:
self.set_mirror_clock_terminal_connected(False)

# Remove connections between other terminals, if applicable:
self.set_connected_terminals_connected(False)

# Set up manual mode tasks again:
self.start_manual_mode_tasks()
if abort:
Expand Down
5 changes: 5 additions & 0 deletions labscript_devices/NI_DAQmx/labscript_devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class NI_DAQmx(IntermediateDevice):
"static_AO",
"static_DO",
"clock_mirror_terminal",
"connected_terminals",
"AI_range",
"AI_start_delay",
"AI_start_delay_ticks",
Expand Down Expand Up @@ -93,6 +94,7 @@ def __init__(
static_AO=None,
static_DO=None,
clock_mirror_terminal=None,
connected_terminals=None,
acquisition_rate=None,
AI_range=None,
AI_range_Diff=None,
Expand Down Expand Up @@ -132,6 +134,9 @@ def __init__(
clock_mirror_terminal (str, optional): Channel string of digital output
that mirrors the input clock. Useful for daisy-chaning DAQs on the same
clockline.
connected_terminals (list, optional): List of pairs of strings of digital inputs
and digital outputs that will be connected. Useful for daisy-chaining DAQs
on the same clockline when they do not have direct routes (see Device Routes in NI MAX).
acquisiton_rate (float, optional): Default sample rate of inputs.
AI_range (iterable, optional): A `[Vmin, Vmax]` pair that sets the analog
input voltage range for all analog inputs.
Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy