43d490e2f8b9472d2ce61ab12f17bb047995d31a
RadioPhotonic PCB — Laser Controller
GUI application and embeddable Python module for controlling a dual-laser board over UART (115 200 baud). Designed to run on a Raspberry Pi or any Linux machine.
Project structure
.
├── _device_main.py # GUI application entry point
├── gui.py # FreeSimpleGUI layout definition
├── device_interaction.py # High-level device commands (legacy)
├── device_commands.py # Low-level protocol helpers (legacy)
├── device_conversion.py # Physical-unit conversion formulas (legacy)
│
├── laser_control/ # Standalone embeddable module
│ ├── __init__.py # Public API
│ ├── controller.py # LaserController class
│ ├── protocol.py # Command encoding / response decoding
│ ├── validators.py # Input validation
│ ├── conversions.py # Physical-unit conversions
│ ├── models.py # Dataclasses (Measurements, DeviceStatus, …)
│ ├── constants.py # Protocol constants and physical limits
│ ├── exceptions.py # Exception hierarchy
│ └── example_usage.py # Usage examples
│
├── tests/ # pytest test suite (75 tests)
│ ├── conftest.py
│ ├── test_validation.py
│ ├── test_protocol.py
│ └── test_integration.py
│
├── pyproject.toml # Package metadata (laser_control)
├── run # Launch script for the GUI app
└── deploy # First-time environment setup script
Setting up the virtual environment
First-time setup
# 1. Create virtual environment
python3 -m venv .venv
# 2. Activate it
source .venv/bin/activate
# 3. Install GUI and serial dependencies
pip install -r requirements.txt
# 4. Install laser_control as an editable package
# (required for imports to work in any subdirectory)
pip install -e .
# 5. Install pytest (for running tests)
pip install pytest
Every subsequent session
source .venv/bin/activate
Running the GUI application
source .venv/bin/activate
./run
# or directly:
python3 _device_main.py
The application auto-detects the USB serial port. If more than one port is present, the first one found is used.
Running the tests
source .venv/bin/activate
python3 -m pytest tests/ -v
Expected result: 75 passed.
Running the usage example
source .venv/bin/activate
# Auto-detect port:
python3 laser_control/example_usage.py
# Specify port explicitly:
python3 laser_control/example_usage.py /dev/ttyUSB0
Embedding laser_control in another application
After pip install -e . (or copying the laser_control/ folder into your
project and running pip install -e . there), import as follows:
from laser_control import (
LaserController,
VariationType,
ValidationError,
CommunicationError,
)
# --- Manual mode ---
with LaserController(port='/dev/ttyUSB0') as ctrl:
try:
ctrl.set_manual_mode(
temp1=25.0, # °C [15 … 40]
temp2=30.0, # °C [15 … 40]
current1=40.0, # mA [15 … 60]
current2=35.0, # mA [15 … 60]
)
data = ctrl.get_measurements()
if data:
print(f"3.3 V rail: {data.voltage_3v3:.3f} V")
print(f"Laser 1 temperature: {data.temp1:.2f} °C")
except ValidationError as e:
print(f"Bad parameter: {e}")
except CommunicationError as e:
print(f"Device not responding: {e}")
# --- Current variation mode ---
def on_data(m):
print(f"I1={m.current1:.3f} mA T1={m.temp1:.2f} °C")
with LaserController(port=None, on_data=on_data) as ctrl: # port=None → auto-detect
ctrl.start_variation(
variation_type=VariationType.CHANGE_CURRENT_LD1,
params={
'min_value': 20.0, # mA
'max_value': 50.0, # mA
'step': 0.5, # mA [0.002 … 0.5]
'time_step': 50, # µs [20 … 100]
'delay_time': 5, # ms [3 … 10]
'static_temp1': 25.0,
'static_temp2': 30.0,
'static_current1': 35.0,
'static_current2': 35.0,
}
)
import time; time.sleep(2)
ctrl.stop_task()
Parameter limits
| Parameter | Min | Max | Unit |
|---|---|---|---|
| Temperature (T1, T2) | 15.0 | 40.0 | °C |
| Current (I1, I2) | 15.0 | 60.0 | mA |
| Current variation step | 0.002 | 0.5 | mA |
| Temperature variation step | 0.05 | 1.0 | °C |
| Time step | 20 | 100 | µs |
| Delay time | 3 | 10 | ms |
Exception hierarchy
LaserControlError
├── ValidationError
│ ├── TemperatureOutOfRangeError
│ ├── CurrentOutOfRangeError
│ └── InvalidParameterError
├── CommunicationError
│ ├── PortNotFoundError
│ ├── DeviceNotRespondingError
│ ├── CRCError
│ └── ProtocolError
└── DeviceError
├── DeviceOverheatingError
├── PowerSupplyError
└── DeviceStateError
Device output
Each measurement response contains:
| Field | Description | Unit |
|---|---|---|
temp1, temp2 |
Laser temperatures | °C |
temp_ext1, temp_ext2 |
External thermistor temperatures | °C |
current1, current2 |
Photodiode currents | mA |
voltage_3v3 |
3.3 V power rail | V |
voltage_5v1, voltage_5v2 |
5 V power rails | V |
voltage_7v0 |
7 V power rail | V |
Description
GUI программа для управления основной PCB генератора: задает токи, температуры лазеров, режимы варьирования. Написано на python3 + FreeSimpleGUI + PySerial
Languages
Python
99.6%
Shell
0.4%