From 5505a553b564239d4ed725aa057d369ad5d277fa Mon Sep 17 00:00:00 2001 From: Jasper-Harvey0 Date: Thu, 22 Jan 2026 10:24:45 +1100 Subject: [PATCH 1/5] Update waveform function --- src/fixate/drivers/dso/agilent_mso_x.py | 45 ++++++++++++------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/fixate/drivers/dso/agilent_mso_x.py b/src/fixate/drivers/dso/agilent_mso_x.py index 7d1fbf35..265993be 100644 --- a/src/fixate/drivers/dso/agilent_mso_x.py +++ b/src/fixate/drivers/dso/agilent_mso_x.py @@ -643,39 +643,38 @@ def waveform_preamble(self): preamble[labels[index]] = val return preamble - def waveform_values(self, signals, file_name="", file_type="csv"): + def waveform_values(self, signal, file_name="", file_type="csv"): """ - :param signals: + :param signal: The channel ie "1", "2", "3", "4", "MATH", "FUNC" :param file_name: If :param file_type: :return: """ - signals = self.digitize(signals) - return_vals = {} - for sig in signals: - return_vals[sig] = [] - results = return_vals[sig] - self.write(":WAV:SOUR {}".format(sig)) - self.write(":WAV:FORM BYTE") - self.write(":WAV:POIN:MODE RAW") - preamble = self.waveform_preamble() - data = self.retrieve_waveform_data() - for index, datum in enumerate(data): - time_val = index * preamble["x_increment"] - y_val = ( - preamble["y_origin"] - + (datum - preamble["y_reference"]) * preamble["y_increment"] - ) - results.append((time_val, y_val)) + signal = self.digitize(signal) + # digitize returns a list: + self.write(":WAV:SOUR {}".format(signal[0])) + self.write(":WAV:FORM BYTE") + self.write(":WAV:POIN:MODE RAW") + + preamble = self.waveform_preamble() + data = self.retrieve_waveform_data() + time_values = [] + values = [] + for index, datum in enumerate(data): + time_val = index * preamble["x_increment"] + y_val = ( + preamble["y_origin"] + + (datum - preamble["y_reference"]) * preamble["y_increment"] + ) + time_values.append(time_val) + values.append(y_val) if file_name and file_type == "csv": # Needs work for multiple references with open(file_name, "w") as f: f.write("x,y") - for label in sorted(preamble): - f.write(",{},{}".format(label, preamble[label])) f.write("\n") - for time_val, y_val in enumerate(results): + for time_val, y_val in zip(time_values, values): f.write( "{time_val},{voltage}\n".format( time_val=time_val, voltage=y_val @@ -683,7 +682,7 @@ def waveform_values(self, signals, file_name="", file_type="csv"): ) elif file_name and file_type == "bin": raise NotImplementedError("Binary Output not implemented") - return results + return time_values, values def retrieve_waveform_data(self): self.instrument.write(":WAV:DATA?") From 40c226e2893460b508581e34ab0ad0b7ddf72adb Mon Sep 17 00:00:00 2001 From: Jasper-Harvey0 Date: Wed, 4 Feb 2026 13:29:00 +1100 Subject: [PATCH 2/5] Updated waveform_values to not set the scope to run when getting data --- src/fixate/drivers/dso/agilent_mso_x.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/fixate/drivers/dso/agilent_mso_x.py b/src/fixate/drivers/dso/agilent_mso_x.py index 265993be..a190fdf8 100644 --- a/src/fixate/drivers/dso/agilent_mso_x.py +++ b/src/fixate/drivers/dso/agilent_mso_x.py @@ -652,11 +652,16 @@ def waveform_values(self, signal, file_name="", file_type="csv"): :param file_type: :return: """ - signal = self.digitize(signal) - # digitize returns a list: - self.write(":WAV:SOUR {}".format(signal[0])) - self.write(":WAV:FORM BYTE") - self.write(":WAV:POIN:MODE RAW") + # Check if there is actually data to acquire: + # This line also makes the channel the source for the data export! + data_available = int( + self.query(":WAVeform:SOURce CHANnel" + str(signal) + ";POINTs?") + ) + if data_available == 0: + # No data is available + # Setting a channel to be a waveform source turns it on, so we need to turn it off now: + self.write(":CHANnel" + str(signal) + ":DISPlay OFF") + raise ValueError("No data is available") preamble = self.waveform_preamble() data = self.retrieve_waveform_data() From 667d4e039556de72e8c6aefbe51ed32276403fca Mon Sep 17 00:00:00 2001 From: Jasper-Harvey0 Date: Wed, 4 Feb 2026 14:31:08 +1100 Subject: [PATCH 3/5] Shift waveform to be centered on trigger --- src/fixate/drivers/dso/agilent_mso_x.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fixate/drivers/dso/agilent_mso_x.py b/src/fixate/drivers/dso/agilent_mso_x.py index a190fdf8..f255dc60 100644 --- a/src/fixate/drivers/dso/agilent_mso_x.py +++ b/src/fixate/drivers/dso/agilent_mso_x.py @@ -668,7 +668,7 @@ def waveform_values(self, signal, file_name="", file_type="csv"): time_values = [] values = [] for index, datum in enumerate(data): - time_val = index * preamble["x_increment"] + time_val = index * preamble["x_increment"] + preamble["x_origin"] y_val = ( preamble["y_origin"] + (datum - preamble["y_reference"]) * preamble["y_increment"] From f6923d3625eada3093b7396dd1c55a40f654f549 Mon Sep 17 00:00:00 2001 From: Jasper-Harvey0 Date: Wed, 11 Feb 2026 10:31:01 +1100 Subject: [PATCH 4/5] Update release notes --- docs/release-notes.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/release-notes.rst b/docs/release-notes.rst index 1d4a4ac4..e41a756f 100644 --- a/docs/release-notes.rst +++ b/docs/release-notes.rst @@ -20,6 +20,8 @@ Improvements - Sequencer logic now handles exceptions raised on sequence abort. GUI will no longer hang when a test raises an exception during a test abort. - Fix bug where DSOX1202G appeared to hang both the program and scope - LCR Driver now supports instruments reporting as Keysight or Agilent. Newer models of the LCR meter report as Keysight, whereas older models report as Agilent. +- DSO Driver function 'waveform_value' now returns a single channels x and y data as two separate lists, without re-acquiring the signal. This function should + now be called after performing singal acquisition. ************* Version 0.6.4 From 8c56d6ff8a12f114bba7a1d10840bf13b93388f8 Mon Sep 17 00:00:00 2001 From: Jasper-Harvey0 Date: Wed, 11 Feb 2026 10:39:33 +1100 Subject: [PATCH 5/5] Update docstring --- src/fixate/drivers/dso/agilent_mso_x.py | 26 +++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/fixate/drivers/dso/agilent_mso_x.py b/src/fixate/drivers/dso/agilent_mso_x.py index f255dc60..9ff2d2ba 100644 --- a/src/fixate/drivers/dso/agilent_mso_x.py +++ b/src/fixate/drivers/dso/agilent_mso_x.py @@ -645,13 +645,27 @@ def waveform_preamble(self): def waveform_values(self, signal, file_name="", file_type="csv"): """ - :param signal: - The channel ie "1", "2", "3", "4", "MATH", "FUNC" - :param file_name: - If - :param file_type: - :return: + Retrieves waveform data from the specified channel and optionally saves it to a file. + + This method queries the instrument for raw data points, scales them using + the waveform preamble (origin, increment, and reference values), and + converts them into time and voltage arrays. + + Args: + signal (str|int): The source channel (e.g., "1", "2", "MATH", "FUNC"). + file_name (str, optional): The path/name of the file to save data to. + Defaults to "", which skips file saving. + file_type (str, optional): The format for the output file. + Supported: "csv". Defaults to "csv". + + Returns: + tuple: A tuple containing (time_values, values) as lists of floats. + + Raises: + ValueError: If no data is available on the selected channel. + NotImplementedError: If an unsupported file_type is requested. """ + # Check if there is actually data to acquire: # This line also makes the channel the source for the data export! data_available = int(