示例#1
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()
示例#2
0
# 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__:
        pcb.av2 = 0
    if 'timestep' not in pcb.__dict__:
        pcb.timestep = 0
    if 'slowdown' not in pcb.__dict__: