diff --git a/README.md b/README.md index 8a43ac4..58a89c3 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ PyQt6-приложение для управления лазерной плат - ручной режим: `T1/T2/I1/I2` - live telemetry: `T1/T2`, внешние термисторы, фотодиоды, `3V3/5V1/5V2/7V0` - TEC drive modulation: синусоидальная добавка к выходу TEC PID для выбранного лазера -- свипирование тока лазера 2 и STM32 DAC: лесенка min..max с заданным шагом, временем шага и паузой между свипами +- свипирование тока лазера 2 и STM32 DAC: лесенка min..max с заданным шагом, временем шага и паузой между свипами; настройки сохраняются в SD-профиль - AD9102: saw/SRAM режимы и загрузка custom waveform - AD9833, DS1809 и STM32 DAC через отдельные firmware-команды - сохранение профиля на SD-карту устройства diff --git a/laser_control/gui/sections.py b/laser_control/gui/sections.py index 9bd1ca7..a60ed94 100644 --- a/laser_control/gui/sections.py +++ b/laser_control/gui/sections.py @@ -148,6 +148,11 @@ class SweepControls(QGroupBox): self._minimum = minimum self._maximum = maximum self._step = step + # Keep min <= max so every input state is a valid sweep, both when applied and when saved to a profile. + minimum.valueChanged.connect(maximum.setMinimum) + maximum.valueChanged.connect(minimum.setMaximum) + maximum.setMinimum(minimum.value()) + minimum.setMaximum(maximum.value()) self._step_period_us = _int_spinbox( SWEEP_STEP_PERIOD_MIN_US, SWEEP_STEP_PERIOD_MAX_US, diff --git a/laser_control/gui/window.py b/laser_control/gui/window.py index 2cdfbda..be02ae3 100644 --- a/laser_control/gui/window.py +++ b/laser_control/gui/window.py @@ -776,9 +776,24 @@ class MainWindow(QMainWindow): "", f"ds1809_apply={'true' if self._ds1809_profile_apply.isChecked() else 'false'}", f"ds1809_position_from_min={self._ds1809_profile_position.value()}", + "", + *self._build_sweep_profile_lines("laser2_current_sweep", self._laser2_sweep.settings()), + "", + *self._build_sweep_profile_lines("stm32_dac_sweep", self._stm32_dac_sweep.settings()), ] return "\n".join(lines) + "\n" + @staticmethod + def _build_sweep_profile_lines(prefix: str, settings: SweepSettings) -> list[str]: + return [ + f"{prefix}_enable={1 if settings.enabled else 0}", + f"{prefix}_min_code={settings.min_code}", + f"{prefix}_max_code={settings.max_code}", + f"{prefix}_step_code={settings.step_code}", + f"{prefix}_step_period_us={settings.step_period_us}", + f"{prefix}_pause_ms={settings.pause_ms}", + ] + @staticmethod def _build_waveform_text(samples: list[int]) -> str: return "\n".join(str(sample) for sample in samples) + "\n"