diff --git a/qcodes/instrument_drivers/ZI/ZIUHFLI.py b/qcodes/instrument_drivers/ZI/ZIUHFLI.py index 1f78667d953a..e2e612947a3e 100644 --- a/qcodes/instrument_drivers/ZI/ZIUHFLI.py +++ b/qcodes/instrument_drivers/ZI/ZIUHFLI.py @@ -380,45 +380,60 @@ def get(self): meas_time = segs*(params['scope_duration'].get()+deadtime)+1 npts = params['scope_length'].get() - # Create a new scopeModule instance (TODO: Why a new instance?) - scope = self._instrument.daq.scopeModule() - - # Subscribe to the relevant... publisher? - scope.subscribe('/{}/scopes/0/wave'.format(self._instrument.device)) - - # Start the scope triggering/acquiring - params['scope_runstop'].set('run') - - log.info('[*] Starting ZI scope acquisition.') - # Start something... hauling data from the scopeModule? - scope.execute() - - starttime = time.time() + zi_error = True + error_counter = 0 + num_retries = 10 timedout = False - - while scope.progress() < 1: - time.sleep(0.1) # This while+sleep is how ZI engineers do it - if (time.time()-starttime) > meas_time: - scope.finish() # Force break the acquisition - timedout = True - log.warning('[-] ZI Scope acquisition did not finish correctly') - break - - # Stop the scope from running - params['scope_runstop'].set('stop') - - if not timedout: - log.info('[+] ZI scope acquisition completed OK') - rawdata = scope.read() - data = self._scopedataparser(rawdata, self._instrument.device, - npts, segs, channels) - else: - rawdata = None - data = (None, None) - - # kill the scope instance - scope.clear() - + while (zi_error or timedout) and error_counter < num_retries: + # one shot per trigger. This needs to be set every time + # a the scope is enabled as below using scope_runstop + self._instrument.daq.setInt('/{}/scopes/0/single'.format(self._instrument.device), 1) + self._instrument.daq.sync() + + scope = self._instrument.scope # There are issues reusing the scope. + + # Subscribe to the relevant... publisher? + scope.subscribe('/{}/scopes/0/wave'.format(self._instrument.device)) + + # Start the scope triggering/acquiring + params['scope_runstop'].set('run') # set /dev/scopes/0/enable to 1 + + log.info('[*] Starting ZI scope acquisition.') + # Start something... hauling data from the scopeModule? + scope.execute() + starttime = time.time() + timedout = False + + while scope.progress() < 1: + time.sleep(0.1) # This while+sleep is how ZI engineers do it + if (time.time()-starttime) > 2 * meas_time: + timedout = True + break + metadata = scope.get("scopeModule/*") + zi_error = bool(metadata['error'][0]) + + # Stop the scope from running + params['scope_runstop'].set('stop') + + if not (timedout or zi_error): + log.info('[+] ZI scope acquisition completed OK') + rawdata = scope.read() + data = self._scopedataparser(rawdata, self._instrument.device, + npts, segs, channels) + else: + log.warning('[-] ZI scope acquisition attempt {} ' + 'failed, Timeout: {}, Error: {}, ' + 'retrying'.format(error_counter, timedout, zi_error)) + rawdata = None + data = (None, None) + error_counter += 1 + + # cleanup and make ready for next scope acquisition + scope.finish() + scope.unsubscribe('/{}/scopes/0/wave'.format(self._instrument.device)) + if error_counter >= num_retries: + log.warning('[+] ZI scope acquisition failed, maximum number' + 'of retries performed. No data returned') return data @staticmethod @@ -1071,7 +1086,7 @@ def __init__(self, name, device_ID, **kwargs): vals=vals.Enum(1, 2, 3) ) - self._samplingrate_codes = {'1.80 Ghz': 0, + self._samplingrate_codes = {'1.80 GHz': 0, '900 MHz': 1, '450 MHz': 2, '225 MHz': 3, @@ -1926,5 +1941,7 @@ def close(self): """ Override of the base class' close function """ + self.scope.clear() + self.sweeper.clear() self.daq.disconnect() super().close()