A pure Python driver and Qt-based control interface for the Twinleaf CSB (Current Supply Bipolar).
This project provides a robust backend for communicating with Twinleaf CSB hardware via serial connection, along with a modern PySide6/QML graphical user interface for easy control and monitoring.
- Pure Python Core: The core driver (
twinleaf_csb.core) is completely decoupled from the GUI, making it suitable for headless automation, scripts, and integration into other systems. - Hardware & Mock Support: Includes a full hardware transport (using
pyserial) and a Mock transport for development and testing without physical devices. - Reactive GUI: A responsive Qt Quick (QML) interface that updates in real-time as device parameters change.
- Channel Management: Independent control for X, Y, and Z coil channels (Current, Max Current, Frequency, Amplitude).
- Robust Threading: Dedicated threads for serial communication ensure the UI remains responsive during heavy data transfer.
- Python 3.13+
Clone the repository and install using pip:
git clone https://github.com/svennniiii/twinleaf-csb-driver.git
cd twinleaf-csb-driver
# Install core dependencies
pip install .
# Install with GUI dependencies
pip install ".[gui]"If you installed with the [gui] option, you can launch the controller using: Bash
# Assuming you have set up the entry point (see configuration below)
csb-controllerOr run the script directly:
python gui/qt_driver.pyYou can use the driver in your own Python scripts for automation:
import time
from twinleaf_csb.core.driver import TwinleafCSBDriver
from twinleaf_csb.transport.pyserial_transport import PyserialTransport
# Initialize driver with Serial Transport
transport = PyserialTransport()
driver = TwinleafCSBDriver([transport])
# Connect to a specific port
driver.connect("/dev/ttyUSB0") # or "COM3" on Windows
if driver.is_connected():
# Set X Channel Current to 500mA
driver.x_channel.set_offset(0.5)
# Set Y Channel Modulation
driver.y_channel.set_frequency(10.0) # 10 Hz
driver.y_channel.set_amplitude(0.1) # 100 mA
# Read back values (updates happen asynchronously via callbacks)
def my_listener(val):
print(f"X Offset changed to: {val}")
driver.x_channel.add_listener('offset', my_listener)
# Keep script alive to receive data
try:
while True: time.sleep(1)
except KeyboardInterrupt:
driver.disconnect()- twinleaf_csb/core/: Contains the main TwinleafCSBDriver logic and Channel models.
- twinleaf_csb/transport/: Handles low-level communication (Serial or Mock).
- twinleaf_csb/gui/: Contains the PySide6/QML frontend application.
