From b3bb6d8e4769acf6418300d02ed5426b7203137c Mon Sep 17 00:00:00 2001 From: CPD Date: Thu, 3 Apr 2025 19:03:08 +0200 Subject: [PATCH] Update docs --- cpdctrl_gui/resources/about.md | 2 +- .../resources/controller_calibration.md | 13 ++++++ cpdctrl_gui/resources/data_recording.md | 15 ------- cpdctrl_gui/resources/measurement_settings.md | 25 +++++++++++ cpdctrl_gui/resources/sample_changing.md | 8 +--- .../resources/technical_information.md | 22 ++++++---- cpdctrl_gui/resources/troubleshooting.md | 15 +++++++ cpdctrl_gui/resources/user_guide.md | 11 ++++- cpdctrl_gui/ui/widgets/help.py | 4 +- .../widgets/settings/measurement_settings.py | 42 +++++++++++++++++-- 10 files changed, 119 insertions(+), 38 deletions(-) create mode 100644 cpdctrl_gui/resources/controller_calibration.md delete mode 100644 cpdctrl_gui/resources/data_recording.md create mode 100644 cpdctrl_gui/resources/measurement_settings.md diff --git a/cpdctrl_gui/resources/about.md b/cpdctrl_gui/resources/about.md index b520443..6d1a3ef 100644 --- a/cpdctrl_gui/resources/about.md +++ b/cpdctrl_gui/resources/about.md @@ -3,4 +3,4 @@ - Author: Matthias Quintern - License: [GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html) -- Source Code: https://git.quintern.xyz/MatthiasQuintern/cpdctrl-gui \ No newline at end of file +- Source Code: https://git.quintern.xyz/MatthiasQuintern/cpdctrl-gui[controller_calibration.md](controller_calibration.md) \ No newline at end of file diff --git a/cpdctrl_gui/resources/controller_calibration.md b/cpdctrl_gui/resources/controller_calibration.md new file mode 100644 index 0000000..75ac63c --- /dev/null +++ b/cpdctrl_gui/resources/controller_calibration.md @@ -0,0 +1,13 @@ +## CPD Controller Calibration +**TODO: validate and extend** + +This process is not always necessary. Ask the superuser! +1. Set CPD Controller to: + - Manual + - Offset=Gold Work Function + - Filter off (so you can see what happens immediately) + - Oscillator to ~2 +2. Move the micrometer screw close until a signal appears +3. Set Automatic offset so that the output is 0V + + diff --git a/cpdctrl_gui/resources/data_recording.md b/cpdctrl_gui/resources/data_recording.md deleted file mode 100644 index 874dab6..0000000 --- a/cpdctrl_gui/resources/data_recording.md +++ /dev/null @@ -1,15 +0,0 @@ -## Data recording - -### Buffer mode -**TODO** - -### Data flushing -Measurements can be performed over many hours or multiple days. -To make sure that unforeseen accidents like Windows Updates do not ruin the entire measurement, -the data can be continuously written to the disk. -To enable this feature, set `Flush After` to a non-zero value (in the Measurement Settings tab). -After \ number of datapoints are recorded, they are written to the cache directory -as serialized numpy array. -When the measurement is finished, all partial arrays are loaded again and the complete data -can be saved as `csv` or serialized numpy array (`.pkl`). - diff --git a/cpdctrl_gui/resources/measurement_settings.md b/cpdctrl_gui/resources/measurement_settings.md new file mode 100644 index 0000000..d81ba8a --- /dev/null +++ b/cpdctrl_gui/resources/measurement_settings.md @@ -0,0 +1,25 @@ +## Measurement settings + +### Measurement Modes +In the **normal** measurement mode, the `cpdctrl` asks the voltage measurement device +for a new value in regular intervals. +This has the advantage that the LED state is always correctly synced with the voltage values, +however, the intervals might not be consistent since a software timer is used, which +is very inconsistent below 500ms. +The signal-to-noise ratio might also not be good, since the device will spend a lot of time not measuring the voltage. + +The **buffer** mode fixes this, by using voltage measurement device's internal data buffer and timing capabilities. +This allows for lower and very consistent intervals, but the timing of the LED value might be off +by a few tens of milliseconds, since these are still controlled by the lab computer. +Since this should not be big problem, **buffer mode should be preferred**. + +### Data Flushing +Measurements can be performed over many hours or multiple days. +To make sure that unforeseen accidents like Windows Updates do not ruin the entire measurement, +the data can be continuously written to the disk. +To enable this feature, set `Flush After` to a non-zero value (in the Measurement Settings tab). +After \ number of datapoints are recorded, they are written to the cache directory +as serialized numpy array. +When the measurement is finished, all partial arrays are loaded again and the complete data +can be saved as `csv` or serialized numpy array (`.pkl`). + diff --git a/cpdctrl_gui/resources/sample_changing.md b/cpdctrl_gui/resources/sample_changing.md index 5e9bec2..4d5ae11 100644 --- a/cpdctrl_gui/resources/sample_changing.md +++ b/cpdctrl_gui/resources/sample_changing.md @@ -33,10 +33,4 @@ 4. Fully open the valve 5. **Wait** until the vacuum is in the lower 1E-2 range, eg 4.0E-2 (read the value from the sensor attached to the turbopump) 6. Only when this target pressure is reached, turn on the turbopump (control panel on top shelf) - 7. Wait until the desired vacuum for measurement is reached (usually 1E-5) - - 1E-4: **TODO** - - 1E-5: **TODO** - - 1E-6: after 1-2 days - - If the pressure does not drop enough: Use isopropanol to inspect for leaks - + 7. Wait until the desired vacuum for measurement is reached (usually 1E-5) \ No newline at end of file diff --git a/cpdctrl_gui/resources/technical_information.md b/cpdctrl_gui/resources/technical_information.md index e561289..54a6275 100644 --- a/cpdctrl_gui/resources/technical_information.md +++ b/cpdctrl_gui/resources/technical_information.md @@ -4,8 +4,6 @@ Most functionality like interaction with the various devices is provided by the `cpdctrl` package, which can be used without the GUI in an ipython shell for advanced or debugging purposes. - - ### Arduino Code To control the ThorLabs LEDD1B, it is connected to an Arduino Nano, which is connected to the lab PC via USB. The Arduino must have the correct software loaded in order to communicate with `cpdctrl` and the LEDD1B. @@ -13,11 +11,19 @@ via USB. The Arduino must have the correct software loaded in order to communica 2. Open the sketch `~/cpd-dev/cpdctrl/arduino-thorlabs-led/led_control/led_control.ino` 3. Select `COM4` and `Arduino Nano` and then 'Upload Sketch' -### CPD Controller Calibration -**TODO** -This process is not always necessary. -1. Set CPD Controller to Manual, Offset=Gold Work Function, Filter off (so you can see what happens immediately), Oscillator to ~2 -2. Move the micrometer screw close until a signal appears -3. Set Automatic offset so that the output is 0V +### Documentation +The documentation files are in the `cpdtrl-gui` directory: `cpdctl-gui/cpdctrl_gui/resources`. +**Only edit these files** and then generate the documentation for the Wiki and the PDF manual using +the scripts in the repository. +#### PDF Manual +To generate the pdf manual, adapt and run the script found in the cpdctrl-gui repository, in `.scripts/make-manual.py`. +It converts the markdown files to html and generates the PDF from that. + +#### Wiki +Convert the markdown files to html and directly copy-paste that into the BayernCollab Wiki. +1. Adapt and run the script in the cpdctrl-gui repository, in `.scripts/convert_docs_for_website.py`. +4. Open the `.html` files in a text editor (Notepad) and copy the content +3. While editing a page in collab, click the `` button in the top right corner to enable source code editing +4. Paste the html in the appropriate place \ No newline at end of file diff --git a/cpdctrl_gui/resources/troubleshooting.md b/cpdctrl_gui/resources/troubleshooting.md index 5b451be..6ffcb47 100644 --- a/cpdctrl_gui/resources/troubleshooting.md +++ b/cpdctrl_gui/resources/troubleshooting.md @@ -10,3 +10,18 @@ 2) Reset the Arduino by pressing the white button on the top and restart the program 3) Unplug and replug the Arduino and restart the program 4) Re-upload the code (see section "Technical Information/Arduino Code") + +### 3) Pressure does not drop enough +Usual values: + +- Before turbo tump: + - 1E-3: ~5 minutes + - 2E-2: ~25 minutes +- With turbo tump: + - 1E-4: **TODO** + - 1E-5: **TODO** + - 1E-6: after 1-2 days + +1) Make sure the housing sits properly on the baseplate, and no cable is sticking out (check the backside!) +2) Inspect for leaks using isopropanol +3) Perhaps the grease has to be re-applied, ask superuser diff --git a/cpdctrl_gui/resources/user_guide.md b/cpdctrl_gui/resources/user_guide.md index 5ac9983..54e33b7 100644 --- a/cpdctrl_gui/resources/user_guide.md +++ b/cpdctrl_gui/resources/user_guide.md @@ -1 +1,10 @@ -## User Guide +## Quickstart Guide +1. Start the `cpdctrl-gui` software (cpd icon) +2. Click "Power On" to power on devices connected to the USB Switch +3. Make sure all devices are turned on +4. If not connected already, click "CPD devices" and "LED devices" to connect the measurement device and LED controller +5. Set the LED to a constant brightness value or load a LED script file +6. Set the measurement name +7. Click Start +8. In the "LED Script" tab, you can see the current LED state during measurement +9. When done, power off the devices \ No newline at end of file diff --git a/cpdctrl_gui/ui/widgets/help.py b/cpdctrl_gui/ui/widgets/help.py index fd683e8..e343bf1 100644 --- a/cpdctrl_gui/ui/widgets/help.py +++ b/cpdctrl_gui/ui/widgets/help.py @@ -10,8 +10,8 @@ log = logging.getLogger(__name__) GUI_FILES = [ ("about.md", "About"), ("sample_changing.md", "Changing the Sample"), - ("data_recording.md", "Data recording"), - ("led_control.md", "LED control"), + ("measurement_settings.md", "Measurement Settings"), + ("led_control.md", "LED Control"), ("troubleshooting.md", "Troubleshooting"), ("technical_information.md", "Technical Information"), ] diff --git a/cpdctrl_gui/ui/widgets/settings/measurement_settings.py b/cpdctrl_gui/ui/widgets/settings/measurement_settings.py index 4bc6abb..9d9597e 100644 --- a/cpdctrl_gui/ui/widgets/settings/measurement_settings.py +++ b/cpdctrl_gui/ui/widgets/settings/measurement_settings.py @@ -1,9 +1,12 @@ +import os.path + from PyQt6.QtCore import pyqtSignal from PyQt6.QtWidgets import QWidget, QRadioButton, QVBoxLayout, QHBoxLayout, QPushButton, QSpinBox, QFileDialog, QLabel from PyQt6.QtWidgets import QFormLayout, QDoubleSpinBox, QCheckBox, QLineEdit, QGroupBox from os import path +from cpdctrl.led_script import LedScript, InvalidScript from cpdctrl_gui.utility.config import AppConfig from .base import SettingsForm @@ -47,7 +50,7 @@ class ScriptSelection(QGroupBox): # Radio buttons self.radio_script_file = QRadioButton("Script file") - self.radio_constant_value = QRadioButton("Constant value") + self.radio_constant_value = QRadioButton("Constant brightness (%)") self.radio_script_file.toggled.connect(self.on_radio_button_toggled) self.radio_constant_value.toggled.connect(self.on_radio_button_toggled) @@ -56,6 +59,15 @@ class ScriptSelection(QGroupBox): self.btn_load_script.clicked.connect(self.load_file) self.w_script_file = QLineEdit() self.w_script_file.setEnabled(False) + last_file = AppConfig.MAIN_CFG.get_or("tmp_last_script_file", "") + # only use last file if exists and is valid + if os.path.isfile(last_file): + try: + LedScript.parse_script(last_file) + except InvalidScript: + last_file = "" + self.w_script_file.setText(last_file) + self.file_path = last_file # QSpinBox for constant value self.w_constant_value = QSpinBox() @@ -84,12 +96,14 @@ class ScriptSelection(QGroupBox): self.on_radio_button_toggled() self.layout.addStretch(1) - self.file_path = None def on_radio_button_toggled(self): if self.radio_script_file.isChecked(): self.btn_load_script.setEnabled(True) self.w_constant_value.setEnabled(False) + # if a file is set, load it when the button is toggled + if self.file_path: + self.loadScript.emit() else: self.btn_load_script.setEnabled(False) self.w_constant_value.setEnabled(True) @@ -101,6 +115,7 @@ class ScriptSelection(QGroupBox): if file_path: dir_name = path.dirname(file_path) AppConfig.MAIN_CFG.set("tmp_last_script_dir", dir_name) + AppConfig.MAIN_CFG.set("tmp_last_script_file", file_path) self.file_path = file_path self.w_script_file.setText(self.file_path) # signal the change @@ -150,8 +165,15 @@ class MeasurementSettings(QWidget): w_box_max_measurements = QSpinBox(self) w_box_max_measurements.setMaximum(2147483647) # max int32 w_box_max_measurements.setMinimum(0) # 0 for infinite measurements - self.w_form.add_form_row("max_measurements", "Max Measurements", 0, w_box_max_measurements, "Number of measurements to take. Set to 0 for infinite measurements") - self.w_form.add_form_row("stop_on_script_end", "Stop on Script End", False, QCheckBox(self), "Stop measurement when LED script ends") + self.w_form.add_form_row("max_measurements", "Max Measurement Points", 0, w_box_max_measurements, "Number of measurements to take. Set to 0 for infinite measurements") + w_stop_script_end = QCheckBox(self) + self.w_form.add_form_row("stop_on_script_end", "Stop on Script End", False, w_stop_script_end, "Stop measurement when LED script ends") + self.w_poweroff_script_end = QCheckBox(self) + # do after adding to form, since the actual value will have been loaded + w_stop_script_end.stateChanged.connect(self._update_poweroff_checkbox) + w_box_max_measurements.valueChanged.connect(self._update_poweroff_checkbox) + self._update_poweroff_checkbox() + self.w_form.add_form_row("power_off_script_end", "Power Off on Script End", False, self.w_poweroff_script_end, "Turn off the USB power switch when the measurement ends") self.w_form.add_form_row("use_buffer", "Use Buffer", False, QCheckBox(self), "If available, use the voltage device buffer for more accurate measurement timings.\nLeads to a lower accuracy of LED update timings, up to 1*interval") w_box_flush_after = QSpinBox(self) w_box_flush_after.setMaximum(2147483647) # max int32 @@ -159,6 +181,18 @@ class MeasurementSettings(QWidget): self.w_form.add_form_row("flush_after", "Flush-Data Interval", 0, w_box_flush_after, "Number of measurements to take before writing the data to an intermediate file") self.l_vbox.addStretch(1) + def _update_poweroff_checkbox(self): + """ + Enable the power-off-on-end checkbox only if the measurement + will stopped automatically + """ + max_meas = self.w_form.get_value("max_measurements") + stop_script_end = self.w_form.get_value("stop_on_script_end") + if max_meas > 0 or stop_script_end == True: + self.w_poweroff_script_end.setEnabled(True) + else: + self.w_poweroff_script_end.setEnabled(False) + def set_value(self, key, value): if key in self.w_form: self.w_form.set_value(key, value)