Beispiel #1
0
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
Beispiel #2
0
 def test_find_device(self):
     print "Testing finding device and flashing stock firmware."
     scope = Oscilloscope()
     assert scope.setup()
     assert scope.open_handle()
     assert scope.flash_firmware()
     assert scope.close_handle()
Beispiel #3
0
 def test_clear_fifo(self):
     print "Testing explicitly clearing the FIFO."
     scope = Oscilloscope()
     assert scope.setup()
     assert scope.open_handle()
     assert scope.flash_firmware()
     assert scope.clear_fifo()
     assert scope.close_handle()
Beispiel #4
0
 def test_read_firmware(self):
     print "Testing read_firmware method on scope."
     scope = Oscilloscope()
     assert scope.setup()
     assert scope.open_handle()
     assert scope.flash_firmware()
     assert scope.read_firmware()
     assert scope.close_handle()
Beispiel #5
0
 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()
Beispiel #6
0
 def test_get_cal_values(self):
     print "Testing getting calibration values."
     scope = Oscilloscope()
     assert scope.setup()
     assert scope.open_handle()
     assert scope.flash_firmware()
     cal_values = scope.get_calibration_values()
     assert cal_values
     assert scope.close_handle()
Beispiel #7
0
 def test_flash_firmware(self):
     print "Testing flashing multiple firmwares."
     scope = Oscilloscope()
     assert scope.setup()
     assert scope.open_handle()
     assert scope.flash_firmware(stock_firmware, supports_single_channel=False)
     assert scope.flash_firmware(mod_firmware_01)
     assert scope.flash_firmware(stock_firmware, supports_single_channel=False)
     assert scope.close_handle()
Beispiel #8
0
 def test_set_channel_voltage_range(self):
     print "Testing setting the voltage range."
     scope = Oscilloscope()
     assert scope.setup()
     assert scope.open_handle()
     assert scope.flash_firmware()
     for vrange in scope.VOLTAGE_RANGES.keys():
         assert scope.set_ch1_voltage_range(vrange)
         assert scope.set_ch1_voltage_range(vrange)
     assert scope.close_handle()
Beispiel #9
0
 def test_read_data(self):
     print "Testing reading data from the oscilloscope."
     scope = Oscilloscope()
     assert scope.setup()
     assert scope.open_handle()
     assert scope.flash_firmware()
     ch1_data, _ = scope.read_data(data_size=0x400)
     print ch1_data
     assert ch1_data
     assert scope.close_handle()
Beispiel #10
0
 def test_set_num_channels(self):
     print "Testing setting the number of channels with modified firmware."
     scope = Oscilloscope()
     assert scope.setup()
     assert scope.open_handle()
     assert scope.flash_firmware(mod_firmware_01)
     assert scope.set_num_channels(1)
     assert scope.set_num_channels(2)
     assert scope.set_num_channels(1)
     assert scope.close_handle()
Beispiel #11
0
 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()
Beispiel #12
0
 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()
Beispiel #13
0
 def test_read_many_sizes(self):
     print "Testing reading many different data sizes"
     scope = Oscilloscope()
     assert scope.setup()
     assert scope.open_handle()
     assert scope.flash_firmware()
     data_size = 0x400
     for _ in xrange(11):
         print "DATA SIZE", data_size
         ch1_data, ch2_data = scope.read_data(data_size=data_size, raw=True)
         print len(ch1_data)
         print len(ch2_data)
         assert ch1_data, ch2_data
         data_size <<= 1
     assert scope.close_handle()
Beispiel #14
0
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
Beispiel #15
0
#!/usr/bin/python3

__author__ = 'Robert Cope'

from PyHT6022.LibUsbScope import Oscilloscope
from PyHT6022.HantekFirmware import mod_firmware_iso as Firmware

scope = Oscilloscope()
scope.setup()
scope.open_handle()
scope.flash_firmware(firmware=Firmware)
scope.close_handle()
Beispiel #16
0
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()