A python library/GUI.
Project description
pyTriggerSync
pyTriggerSync is a Python library/GUI interface for a Teensy microcontroller running the Send_Trigger_Synced_With_External_Trigger_OnlyRemoteControl firmware. The Teensy generates an output trigger pulse synchronized to an external trigger signal received on its input pin, either continuously or in user-controlled bursts. The package is composed of two parts: a low-level driver for serial communication, and a high-level GUI written with PyQt5 that can be easily embedded into other GUIs.
The interface can work either as a stand-alone application, or as a module of ergastirio.
Table of Contents
- Installation
- Usage via the low-level driver
- Usage as a stand-alone GUI interface
- Embed the GUI within another GUI
Installation
Use the package manager pip to install,
pip install pyTriggerSync
This will install pyTriggerSync together with pyserial, which is required by the low-level driver. In order to use the GUI, it is also necessary to install
pip install abstract_instrument_interface>=0.10
pip install "PyQt5>=5.15.6"
Usage via the low-level driver
pyTriggerSync provides a low-level driver to communicate with the Teensy device over a USB serial connection.
from pyTriggerSync.driver import pyTriggerSync
device = pyTriggerSync()
available_devices = device.list_devices()
print(available_devices)
device.connect_device(port=available_devices[0].split(':')[0])
print(device.mode)
device.disconnect_device()
The method list_devices() scans all serial ports and returns a list of descriptor strings for compatible devices. Each string is in the form "<port>: <description> [<hwid>]", e.g. "COM4: USB Serial [USB VID:PID=16C0:0483 ...]". The port can be extracted from the first element by splitting on ':'.
The class pyTriggerSync exposes several properties and methods to communicate with the device and read or change its settings. All properties and methods that communicate with the device require a connection to be active; they raise RuntimeError if called while disconnected.
Creating a driver instance
pyTriggerSync(port='COM4', baudrate=115200, timeout=0.1)
| Parameter | Type | Description |
|---|---|---|
port |
str, optional | Default serial port to connect to. Used by connect_device() when no port is explicitly specified. Default is 'COM4'. |
baudrate |
int, optional | Baud rate for the serial connection. Must match the firmware (115200). Default is 115200. |
timeout |
float, optional | Read timeout in seconds for the serial connection. Default is 0.1. |
Properties
The following are implemented as Python @property, i.e. they are accessed without parentheses (e.g. device.mode) and, when settable, assigned with = (e.g. device.mode = 1). Reading or setting any of these requires a device to be connected, otherwise a RuntimeError is raised.
| Property | Type | Description | Can be set? |
|---|---|---|---|
identity |
str | The device's identity string (its response to idn?). |
No |
mode |
int | Operating mode: 0 = Continuous Trigger (every qualifying input edge fires an output pulse), 1 = Trigger Controlled by User (output pulses only fire in response to sendtrigger()). |
Yes â must be 0 or 1; raises ValueError otherwise. |
polarity |
int | Output pulse polarity: 0 = Negative (output idles high, pulses low), 1 = Positive (output idles low, pulses high). |
Yes â must be 0 or 1; raises ValueError otherwise. |
delay |
int | Delay in nanoseconds between an input trigger edge and the generated output pulse. | Yes â must be a non-negative integer; raises ValueError otherwise. |
triggerduration |
int | Duration of the generated output pulse in nanoseconds. | Yes â must be a positive integer; raises ValueError otherwise. |
divider |
int | Sub-sampling divider: in Continuous Trigger mode, one output pulse is emitted for every divider input edges. divider=1 passes every trigger through (no sub-sampling). |
Yes â must be a positive integer; raises ValueError otherwise. |
number_of_triggers |
int | Number of output pulses produced by a single sendtrigger() call. Only meaningful in mode 1. |
Yes â must be a positive integer; raises ValueError otherwise. |
After setting a property, the driver reads the value back from the device to confirm it took effect. If the device does not acknowledge the command, or if the read-back value does not match the requested value, a RuntimeError is raised.
Other attributes
These are plain instance attributes (not @property) that are useful to inspect directly.
| Attribute | Type | Description |
|---|---|---|
connected |
bool | True if a device is currently connected, False otherwise. |
port |
str | Serial port used for the current (or most recent) connection. |
baudrate |
int | Baud rate configured for the connection. |
timeout |
float | Read timeout (in seconds) configured for the connection. |
identifier |
str | Substring that must appear at the start of a device's identity string for it to be recognised as compatible. Default is 'Send_Trigger_Synced_With_External_Trigger'. |
Methods
| Method | Returns | Description |
|---|---|---|
list_devices() |
list of str | Scans all serial ports and returns a list of descriptor strings for compatible devices. Each string is in the form "<port>: <description> [<hwid>]". Raises RuntimeError if a device is already connected. |
connect_device(port=None, baudrate=None, timeout=None) |
(str, int) | Attempts to connect to the device on the specified serial port. If any parameter is None, the corresponding instance attribute is used. On success, queries the device for all current settings and caches them. Returns (message, 1) on success or (error, 0) on failure. |
disconnect_device() |
(str, int) | Closes the serial connection to the currently connected device. Returns (message, 1) on success or (error, 0) on failure. |
check_valid_connection() |
None | Raises RuntimeError if no device is currently connected. Called internally by all properties and sendtrigger(). |
query(q) |
str | Sends the command string q to the device and returns its reply as a stripped string. Clears any stale data from the input buffer before writing. |
sendtrigger() |
bool | Sends a trg command to start a burst of output pulses. Only valid in mode 1; raises RuntimeError in mode 0. Returns True if the device acknowledged the command, False otherwise. Note: the acknowledgement confirms the burst was armed, not that it has completed â completion depends on input trigger edges arriving at the device and is reported asynchronously by the device itself (it sends "01" over serial when done). |
Examples
from pyTriggerSync.driver import pyTriggerSync
device = pyTriggerSync()
# Scan for available devices
available_devices = device.list_devices()
print(available_devices)
# e.g. ['COM4: USB Serial [USB VID:PID=16C0:0483 SER=123456 LOCATION=1-1]']
# Connect to the first available device
port = available_devices[0].split(':')[0]
device.connect_device(port=port)
# Read device identity
print(device.identity)
# Set mode to "Trigger Controlled by User"
device.mode = 1
# Set output polarity to Negative (idles high, pulses low)
device.polarity = 0
# Set a 500 ns delay and a 200 ns pulse duration
device.delay = 500
device.triggerduration = 200
# Configure a burst of 5 pulses and fire
device.number_of_triggers = 5
success = device.sendtrigger()
print(f"Trigger sent: {success}")
# Switch to Continuous Trigger mode with a divider of 2
# (fires one output pulse for every 2 input edges)
device.mode = 0
device.divider = 2
# Disconnect
device.disconnect_device()
Usage as a stand-alone GUI interface
The installation sets up an entry point for the GUI. Just type
pyTriggerSync
in the command prompt to start the GUI.
Embed the GUI within another GUI
The GUI can also be easily integrated within a larger graphical interface:
import PyQt5.QtWidgets as Qt
import pyTriggerSync
app = Qt.QApplication([])
window = Qt.QWidget()
# The GUI must be contained inside a widget object
widget_containing_interface_GUI = Qt.QWidget()
widget_containing_interface_GUI.setStyleSheet(
".QWidget {
"
"border: 1px solid black;
"
"border-radius: 4px;
"
"}"
)
# Create the interface (model) object
Interface = pyTriggerSync.interface(app=app)
Interface.verbose = False
# Signals emitted by the interface can be connected to external functions, e.g.:
#
# Interface.sig_mode_changed.connect(my_function)
#
# my_function will be called with the new mode (0 or 1) every time the mode changes.
# Similarly, Interface.sig_external_trigger_changed, sig_polarity_changed, etc.
# can be used to react to any setting change.
#
# To fire a trigger from external code (e.g. in response to another instrument):
#
# Interface.fire_trigger()
# Create the GUI (view + controller) and bind it to the interface
view = pyTriggerSync.gui(interface=Interface, parent=widget_containing_interface_GUI)
# Add additional GUI elements alongside the pyTriggerSync panel
gridlayoutwidget = Qt.QWidget()
gridlayout = Qt.QGridLayout()
gridlayout.addWidget(Qt.QLabel("Additional GUI 1"), 0, 0)
gridlayout.addWidget(Qt.QLabel("Additional GUI 2"), 1, 0)
gridlayoutwidget.setLayout(gridlayout)
layout = Qt.QVBoxLayout()
layout.addWidget(widget_containing_interface_GUI)
layout.addWidget(gridlayoutwidget)
layout.addStretch(1)
window.setLayout(layout)
app.aboutToQuit.connect(Interface.close)
window.show()
app.exec()
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pytriggersync-0.3.tar.gz.
File metadata
- Download URL: pytriggersync-0.3.tar.gz
- Upload date:
- Size: 43.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
36859b04dd01f4396a4be9ba53e98d472c236199ec7d6e87a7d917aa2a68b828
|
|
| MD5 |
facf2fec124d2d4064147071d7e27300
|
|
| BLAKE2b-256 |
f764a0b748400f4f19d7146ae8acb44040cc4622c1e4837670ca2269867f509c
|
File details
Details for the file pytriggersync-0.3-py3-none-any.whl.
File metadata
- Download URL: pytriggersync-0.3-py3-none-any.whl
- Upload date:
- Size: 32.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
06e44c1c9e5b33149359d64281782c980eaaa42376638163f4bfda2c6140c596
|
|
| MD5 |
c701d9e778fe26009ae5f719dc52e9fd
|
|
| BLAKE2b-256 |
0d60a1c623dc6c838b123913f263d5a94950028618b1ad33dad1eab3f804bf6a
|