class ScopeInterface(QObject): new_data = pyqtSignal(list) def __init__(self, parent=None): super(ScopeInterface, self).__init__(parent) self.inprogress = False def initialize(self): self.sample_rate_index = 8 self.voltage_range = 0x01 self.data_points = 3 * 1024 self.trigger_level = 150 self.trigger_type = +1 self.scope = Oscilloscope() self.scope.setup() self.scope.open_handle() if (not self.scope.is_device_firmware_present): self.scope.flash_firmware() self.scope.set_interface(1) # choose ISO self.scope.set_num_channels(1) self.scope.set_sample_rate(self.sample_rate_index) self.scope.set_ch1_voltage_range(self.voltage_range) time.sleep(0.1) return None def capture(self): if not self.inprogress: self.inprogress = True self.scope.start_capture() shutdown_event = self.scope.read_async(self.data_callback, self.data_points, outstanding_transfers=25) print("Clearing FIFO and starting data transfer...") def data_callback(self, ch1_data, _): d = list(ch1_data) i = 0 #print("got new data ", time.time(), " : ", len(d)) if self.trigger_type > 0: while (i < len(d) - 1) and not (d[i + 1] > self.trigger_level and d[i] < self.trigger_level): i += 1 #print("Trigger at ", i) if (i != len(d) - 1): self.new_data.emit(d[i:]) def stop(self): self.scope.stop_capture() print("Stopping new transfers.") shutdown_event.set() print("Snooze 1") time.sleep(1) print("Closing handle") self.scope.close_handle() print("Handle closed.") self.inprogress = False
def test_set_sample_rate(self): print "Testing setting the sample rate." scope = Oscilloscope() assert scope.setup() assert scope.open_handle() assert scope.flash_firmware() for rate_index in scope.SAMPLE_RATES.keys(): scope.set_sample_rate(rate_index) assert scope.close_handle()
class ScopeInterface(QObject): new_data = pyqtSignal(list) def __init__(self, parent=None): super(ScopeInterface, self).__init__(parent) self.inprogress = False def initialize(self): self.sample_rate_index = 8 self.voltage_range = 0x01 self.data_points = 3 * 1024 self.trigger_level = 150 self.trigger_type = +1 self.scope = Oscilloscope() self.scope.setup() self.scope.open_handle() if (not self.scope.is_device_firmware_present): self.scope.flash_firmware() self.scope.set_interface(1); # choose ISO self.scope.set_num_channels(1) self.scope.set_sample_rate(self.sample_rate_index) self.scope.set_ch1_voltage_range(self.voltage_range) time.sleep(0.1) return None def capture(self): if not self.inprogress: self.inprogress = True self.scope.start_capture() shutdown_event = self.scope.read_async(self.data_callback, self.data_points, outstanding_transfers=25) print("Clearing FIFO and starting data transfer...") def data_callback(self, ch1_data, _): d = list(ch1_data) i = 0 #print("got new data ", time.time(), " : ", len(d)) if self.trigger_type > 0: while (i < len(d) - 1) and not (d[i+1] > self.trigger_level and d[i] < self.trigger_level): i += 1 #print("Trigger at ", i) if (i != len(d) - 1): self.new_data.emit(d[i:]) def stop(self): self.scope.stop_capture() print("Stopping new transfers.") shutdown_event.set() print("Snooze 1") time.sleep(1) print("Closing handle") self.scope.close_handle() print("Handle closed.") self.inprogress = False
def test_set_one_channel_and_read(self): print "Testing setting one channel and reading it." scope = Oscilloscope() assert scope.setup() assert scope.open_handle() assert scope.flash_firmware(mod_firmware_01) assert scope.set_ch1_voltage_range(0xA) assert scope.set_sample_rate(0x10) assert scope.set_num_channels(1) ch1_data, ch2_data = scope.read_data(0x4000) assert ch1_data assert not ch2_data assert scope.close_handle()
def test_data_scaling(self): print "Testing setting various scale facotrs and reading." scale_factor = 0x01 scope = Oscilloscope() assert scope.setup() assert scope.open_handle() assert scope.flash_firmware() assert scope.set_ch1_voltage_range(scale_factor) assert scope.set_sample_rate(27) ch1_data, _ = scope.read_data(0x100000) ch1_data = scope.scale_read_data(ch1_data, scale_factor) print "Max:", max(ch1_data), "(V), Min:", min(ch1_data), "(V)" assert ch1_data assert scope.close_handle()
def setup_scope(): scope = Oscilloscope() if not scope.setup(): raise AttributeError('Scope not available!') scope.open_handle() if (not scope.is_device_firmware_present): logger.info('flash firmware') scope.flash_firmware() else: scope.supports_single_channel = True logger.info("Setting up scope!") scope.set_interface(1) # choose ISO logger.info('%s %s' % ("ISO" if scope.is_iso else "BULK", "packet size: %d" % scope.packetsize)) scope.set_num_channels(numchannels) scope.set_ch1_voltage_range(voltage_range) scope.set_sample_rate(sample_rate_index) time.sleep(1) return scope
scope = Oscilloscope() scope.setup() scope.open_handle() if (not scope.is_device_firmware_present): scope.flash_firmware() else: scope.supports_single_channel = True print("Setting up scope!") scope.set_interface(alternative) print("ISO" if scope.is_iso else "BULK", "packet size:", scope.packetsize) scope.set_num_channels(numchannels) # set voltage range scope.set_ch1_voltage_range(voltagerange) # set sample rate scope.set_sample_rate(samplerate) # we divide by 100 because otherwise audacity lets us not zoom into it samplerate = samplerate * 1000 * 10 print("Reading data from scope! in ", ) for x in range(3): print( 3 - x, "..", ) sys.stdout.flush() time.sleep(1) print("now") data = [] data_extend = data.append
running = False else: continue return stability[1:-1] sample_rate_index = 24 voltage_range = 0x01 data_points = 3 * 1024 scope = Oscilloscope() scope.setup() scope.open_handle() scope.flash_firmware() scope.set_interface(1) # choose ISO scope.set_num_channels(1) scope.set_sample_rate(sample_rate_index) scope.set_ch1_voltage_range(voltage_range) time.sleep(1) data = deque(maxlen=2*1024*1024) data_extend = data.extend def extend_callback(ch1_data, _): global data_extend data_extend(ch1_data) start_time = time.time() print("Clearing FIFO and starting data transfer...") i = 0 scope.start_capture()
rates.append(rate) print "Average: {} MB/s".format(sum(rates) / (len(rates) * 1e6)) return rates voltage_range = 0x01 time_fxn = time.time scope = Oscilloscope() scope.setup() scope.open_handle() scope.set_ch1_voltage_range(voltage_range) for sample_rate_index in [0x30, 0x10, 0x08, 0x04, 0x01, 0x32, 0x14, 0x0A]: scope.set_sample_rate(sample_rate_index) _, label = scope.convert_sampling_rate_to_measurement_times( 1, sample_rate_index) print "Sample rate: {}".format(label) print "-" * 40 for data_points in [ 0x800, 0x1000, 0x8000, 0x10000, 0x80000, 0x100000, 0x200000 ]: reader_fxn = scope.build_data_reader(raw=True) times = [] times_append = times.append times_append(time_fxn()) for _ in xrange(iterations): ch1_data, _ = reader_fxn(data_points) times_append(time_fxn()) print "Raw Mode, Data Points: 0x{:x}".format(data_points)
scope.setup() scope.open_handle() scope.flash_firmware() if (not scope.is_device_firmware_present): scope.flash_firmware() else: scope.supports_single_channel = True; print "Setting up scope!" scope.set_interface(alternative); print "ISO" if scope.is_iso else "BULK", "packet size:", scope.packetsize print scope.set_num_channels(numchannels) # set voltage range scope.set_ch1_voltage_range(voltagerange) # set sample rate scope.set_sample_rate(samplerate) # we divide by 100 because otherwise audacity lets us not zoom into it samplerate = samplerate * 1000 * 10 print "Reading data from scope! in ", for x in range(0, 3): print 3-x,"..", sys.stdout.flush() time.sleep(1) print "now" data = [] data_extend = data.append def extend_callback(ch1_data, _): data_extend(ch1_data)
class Plugin(LoggerPlugin): """ Diese Gerät zeichnet die Daten eines Hantek6022 (und möglicherweise anderer) Oszilloskops auf. """ def __init__(self, *args, **kwargs): # Plugin setup super(Plugin, self).__init__(*args, **kwargs) self.setDeviceName(DEVICENAME) self.smallGUI = False self._scope = None self.setPerpetualTimer(self._updateT, samplerate=SAMPLERATE) self._blocksize = 6 * 1024 # should be divisible by 6*1024 self._alternative = 1 # choose ISO 3072 bytes per 125 us self._recordLength = 5000 self._blocksize = self._recordLength self._yData1 = deque(maxlen=self._recordLength) self._yData2 = deque(maxlen=self._recordLength) self._yData1Triggered = deque(maxlen=self._recordLength) self._yData2Triggered = deque(maxlen=self._recordLength) self._singleTriggerFound = False self.__capturer = Thread(target=self.__captureT) self.__capturer.start() # THIS IS YOUR THREAD def _updateT(self): if not self.widget.pauseButton.isChecked(): if self.widget.enableTriggerButton.isChecked(): yData1, yData2, stop = self.__trigger(list(self._yData1), list(self._yData2)) else: yData1 = self._yData1 yData2 = self._yData2 stop = False samplerate = self._str2Samplerate( self.widget.samplerateComboBox.currentText()) xData = [(i - len(yData1)) / samplerate for i in range(len(yData1))] if len(self._yData1) > 1: self.plot(xData, yData1, dname='Hantek', sname='CH1', unit='V') if self.widget.channel2CheckBox.isChecked(): self.plot(xData, yData2, dname='Hantek', sname='CH2', unit='V') if stop: self.widget.pauseButton.setChecked(True) def __captureT(self): #self.last_time = time.time() shutdown_event = self._scope.read_async(self._extend_callback, self._blocksize, outstanding_transfers=10, raw=True) self._scope.start_capture() while self.run: self._scope.poll() # logging.info("Stopping new transfers.") # scope.stop_capture() self._scope.stop_capture() shutdown_event.set() time.sleep(0.1) self._scope.close_handle() def loadGUI(self): self.widget = QtWidgets.QWidget() packagedir = self.getDir(__file__) uic.loadUi(packagedir + "/Hantek6022/hantek.ui", self.widget) # self.setCallbacks() self.widget.reconnectButton.clicked.connect( self.__openConnectionCallback) self.widget.samplerateComboBox.currentTextChanged.connect( self._updateScopeSettings) self.widget.recordLengthSpinBox.valueChanged.connect(self.changeLength) # self.widget.channel1CheckBox.valueChanged.connect(self.enableChannel1) self.widget.channel1CheckBox.setEnabled(False) self.widget.channel1ACDCComboBox.hide() # valueChanged.connect(self.) self.widget.channel1VoltPDivComboBox.currentTextChanged.connect( self._updateScopeSettings) self.widget.channel2VoltPDivComboBox.currentTextChanged.connect( self._updateScopeSettings) self.widget.channel2CheckBox.stateChanged.connect( self._updateScopeSettings) self.widget.channel2ACDCComboBox.hide() # valueChanged.connect(self.) # self.widget.pauseButton.clicked.connect(self.) # self.widget.triggerChannelComboBox.textChanged.connect(self.) # self.widget.triggerLevelSpinBox.valueChanged.connect(self.) # self.widget.enableTriggerButton.clicked.connect(self.) self._recordLength = self.widget.recordLengthSpinBox.value() self.xData = deque(maxlen=self._recordLength) self._yData1 = deque(maxlen=self._recordLength) self._yData2 = deque(maxlen=self._recordLength) self.__openConnectionCallback() return self.widget def __openConnectionCallback(self): self.widget.reconnectButton.setEnabled(False) if self.run: self.cancel() self.widget.reconnectButton.setText("Reconnect") self.__base_address = "" self.widget.reconnectButton.setEnabled(True) else: self._updateScopeSettings() self.widget.reconnectButton.setText("Stop") self.widget.reconnectButton.setEnabled(True) def __trigger(self, data1, data2): if not self._singleTriggerFound: if self.widget.channel2CheckBox.isChecked( ) and self.widget.triggerChannelComboBox.currentText() == 'CH2': triggerSignal = list(data2) else: triggerSignal = list(data1) flanke = self.widget.comboBox.currentText() triggerLevel = self.widget.triggerLevelSpinBox.value() cutoff = 0 mean = self.widget.smoothSpinBox.value() triggerPrepared = False if flanke == 'Rising': if max(triggerSignal) > triggerLevel: for idx in range(len(triggerSignal)): if triggerSignal[ idx] >= triggerLevel - mean and triggerSignal[ idx] <= triggerLevel: triggerPrepared = True elif triggerSignal[ idx] < triggerLevel - mean and triggerPrepared: triggerPrepared = False elif triggerSignal[ idx] > triggerLevel and triggerPrepared == True: cutoff = idx break else: if min(triggerSignal) < triggerLevel: for idx in range(len(triggerSignal)): if triggerSignal[ idx] <= triggerLevel + mean and triggerSignal[ idx] >= triggerLevel: triggerPrepared = True elif triggerSignal[ idx] > triggerLevel + mean and triggerPrepared: triggerPrepared = False elif triggerSignal[ idx] < triggerLevel and triggerPrepared == True: cutoff = idx break stop = False if len(data2) > cutoff: data2 = list(data2)[cutoff:] if len(data1) > cutoff: data1 = list(data1)[cutoff:] if cutoff != 0 and self.widget.checkBox.isChecked( ) and not self._singleTriggerFound: self._singleTriggerFound = True else: self._singleTriggerFound = False if self.widget.checkBox.isChecked(): self._yData1Triggered = deque(list(data1), maxlen=self._recordLength) self._yData2Triggered = deque(list(data2), maxlen=self._recordLength) else: if len(self._yData1Triggered) < self._recordLength: stop = False else: self._singleTriggerFound = False stop = True data1 = self._yData1Triggered data2 = self._yData2Triggered return data1, data2, stop def _updateScopeSettings(self): if self._scope: self.cancel() self._scope = Oscilloscope() self._scope.setup() self._scope.open_handle() if (not self._scope.is_device_firmware_present): self._scope.flash_firmware() else: self._scope.supports_single_channel = True logging.info("Setting up scope!") self._scope.set_interface(self._alternative) logging.info("ISO" if self._scope.is_iso else "BULK", "packet size:", self._scope.packetsize) if self.widget.channel2CheckBox.isChecked(): self._scope.set_num_channels(2) else: self._scope.set_num_channels(1) # set voltage range voltagerange1 = self._strVoltageToID( self.widget.channel1VoltPDivComboBox.currentText()) voltagerange2 = self._strVoltageToID( self.widget.channel2VoltPDivComboBox.currentText()) self._scope.set_ch1_voltage_range(voltagerange1) self._scope.set_ch2_voltage_range(voltagerange2) self._scope.set_sample_rate( self._str2SamplerateID( self.widget.samplerateComboBox.currentText())) self._blocksize = self._recordLength self.start() # self.widget.reconnectButton.setText("Stop") # self.widget.reconnectButton.setEnabled(True) def calibrate(self): if self._scope: self._scope.setup_dso_cal_level() cal_level = self._scope.get_calibration_data() self._scope.set_dso_calibration(cal_level) def _str2SamplerateID(self, strung): if 'MHz' in strung: strung = strung.replace(' MHz', '') return int(strung) else: strung = strung.replace(' kHz', '') return int(int(strung) / 10) def _str2Samplerate(self, strung): if 'MHz' in strung: strung = strung.replace(' MHz', '') return int(strung) * 1000000 else: strung = strung.replace(' kHz', '') return int(strung) * 1000 # def __changeChannel1VoltPDiv(self, strung): # if self._scope: # voltagerange = self._strVoltageToID(strung) # self._scope.set_ch1_voltage_range(voltagerange) # # def __changeChannel2VoltPDiv(self, strung): # if self._scope: # voltagerange = self._strVoltageToID(strung) # self._scope.set_ch2_voltage_range(voltagerange) def _enableChannel2(self, value): if value: self._scope.set_num_channels(2) else: self._scope.set_num_channels(1) def _strVoltageToID(self, strung): voltagerange = 1 if strung == '2.6 V': voltagerange = 2 elif strung == '5 V': voltagerange = 5 elif strung == '10 V': voltagerange = 10 return voltagerange def _extend_callback(self, ch1_data, ch2_data): voltage_data = self._scope.scale_read_data( ch1_data, self._strVoltageToID( self.widget.channel1VoltPDivComboBox.currentText())) if len(voltage_data) > 1: self._yData1.extend(voltage_data) if len(self._yData1Triggered) < self._recordLength: if len(self._yData1Triggered) + len( voltage_data) < self._recordLength: self._yData1Triggered.extend(voltage_data) else: self._yData1Triggered.extend( voltage_data[0:self._recordLength - len(self._yData1Triggered)]) if ch2_data != '': voltage_data = self._scope.scale_read_data( ch2_data, self._strVoltageToID( self.widget.channel1VoltPDivComboBox.currentText())) self._yData2.extend(voltage_data) if len(self._yData2Triggered) < self._recordLength: if len(self._yData2Triggered) + len( voltage_data) < self._recordLength: self._yData2Triggered.extend(voltage_data) else: self._yData2Triggered.extend( voltage_data[0:self._recordLength - len(self._yData2Triggered)]) def changeLength(self, newlen: int = 10000): self._recordLength = newlen self._yData1 = deque(maxlen=self._recordLength) self._yData2 = deque(maxlen=self._recordLength) self._yData1Triggered = deque(maxlen=self._recordLength) self._yData2Triggered = deque(maxlen=self._recordLength) self._updateScopeSettings()
scope.flash_firmware() # read calibration values from EEPROM calibration = scope.get_calibration_values() # set interface: 0 = BULK, >0 = ISO, 1=3072,2=2048,3=1024 bytes per 125 us scope.set_interface(0) # use BULK unless you have specific need for ISO xfer scope.set_num_channels(channels) # calculate and set the sample rate ID from real sample rate value if sample_rate < 1e6: sample_id = int(100 + sample_rate / 10e3) else: sample_id = int(sample_rate / 1e6) scope.set_sample_rate(sample_id) # set the gain for CH1 and CH2 scope.set_ch1_voltage_range(ch1gain) scope.set_ch2_voltage_range(ch2gain) ########################################################## # this callback is called every time a data packet arrives # scale the data packets and write them into the outfile # def pcb(ch1_data, ch2_data): # define "static" variables if 'av1' not in pcb.__dict__: pcb.av1 = 0 if 'av2' not in pcb.__dict__: