2026-02-18 18:41:19 +03:00
2026-02-18 18:41:19 +03:00
2026-02-18 18:41:19 +03:00
2025-10-22 18:11:34 +03:00
2025-11-24 15:56:36 +03:00
2025-10-22 18:11:34 +03:00
2025-10-22 18:11:34 +03:00
2025-10-22 18:11:34 +03:00
2026-02-18 17:28:02 +03:00
2025-11-24 15:57:57 +03:00
fix
2026-02-18 18:26:41 +03:00
2026-02-18 17:44:18 +03:00
2025-11-24 15:57:57 +03:00

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 FreeSimpleGUI pyserial

# 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

Note: Steps 35 can be run via the existing deploy script (steps 13), then manually run pip install -e . && pip install pytest once inside the venv.

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
Readme 11 MiB
Languages
Python 99.6%
Shell 0.4%