Пример #1
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()
start_time = time.time()
print("Clearing FIFO and starting data transfer...")
i = 0
scope.start_capture()
shutdown_event = scope.read_async(extend_callback, data_points, outstanding_transfers=10, raw=True)
while time.time() - start_time < 1:
    scope.poll()
scope.stop_capture()
print("Stopping new transfers.")
shutdown_event.set()
print("Snooze 1")
time.sleep(1)
print("Closing handle")
scope.close_handle()
print("Handle closed.")
print("Points in buffer:", len(data))
scaled_data = scope.scale_read_data(data, voltage_range)
with open('/tmp/continuous_read.out','wt') as ouf:
    ouf.write(str(scaled_data[:65536])[1:-1].replace(', ',chr(10)))
plt.figure(0)
plt.plot(scaled_data)
plt.figure(1)
plt.plot(np.fft.fft(scaled_data).real)
#plt.show()
stab = build_stability_array(scaled_data, threshold=np.average(scaled_data))
stab_avg, stab_std = np.average(stab), np.std(stab)
print("Stability", stab_avg, "+/-", stab_std, "({}% deviance)".format(100.0*stab_std/stab_avg))
bad_pulse_count = len([p for p in stab if abs(stab_avg - p) >= stab_std])
print("Pulses more than 1 std dev out: {}/{} ({} %)".format(bad_pulse_count, len(stab), 100.0*bad_pulse_count/len(stab)))
plt.show()
Пример #3
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()
                                  outstanding_transfers=25)
print("Clearing FIFO and starting data transfer...")
i = 0
scope.start_capture()
while time.time() - start_time < 1:
    scope.poll()
scope.stop_capture()
print("Stopping new transfers.")
shutdown_event.set()
print("Snooze 1")
time.sleep(1)
print("Closing handle")
scope.close_handle()
print("Handle closed.")
print("Points in buffer:", len(data))
scaled_data = scope.scale_read_data(data, voltage_range)
with open('/tmp/continuous_read.out', 'wt') as ouf:
    ouf.write(str(scaled_data[:2 ^ 16])[1:-1].replace(', ', chr(10)))
plt.figure(0)
plt.plot(scaled_data)
plt.figure(1)
plt.plot(np.fft.fft(scaled_data).real)
#plt.show()
stab = build_stability_array(scaled_data,
                             threshold=np.average(scaled_data[:2048]))
stab_avg, stab_std = np.average(stab), np.std(stab)
print("Stability", stab_avg, "+/-", stab_std,
      "({}% deviance)".format(100.0 * stab_std / stab_avg))
bad_pulse_count = len([p for p in stab if abs(stab_avg - p) >= stab_std])
print("Pulses more than 1 std dev out: {}/{} ({} %)".format(
    bad_pulse_count, len(stab), 100.0 * bad_pulse_count / len(stab)))
    new_data = data[:window]
    for i, point in enumerate(data[window:-window]):
        new_data.append(sum(data[i-window:i+window+1])/(2*window+1))
    new_data.extend(data[-window:])
    return new_data

sample_rate_index = 0x04
voltage_range = 0x01
data_points = 0x2000

scope = Oscilloscope()
scope.setup()
scope.open_handle()
scope.set_sample_rate(sample_rate_index)
scope.set_ch1_voltage_range(voltage_range)
ch1_data, _ = scope.read_data(data_points)
voltage_data = scope.scale_read_data(ch1_data, voltage_range)
timing_data, _ = scope.convert_sampling_rate_to_measurement_times(data_points, sample_rate_index)
scope.close_handle()
pylab.title('Scope Visualization Example')
pylab.plot(timing_data, voltage_data, color='#009900', label='Raw Trace')
pylab.plot(timing_data, apply_data_smoothing(voltage_data, window=3), color='#0033CC', label='Smoothed Trace')
pylab.xlabel('Time (s)')
pylab.ylabel('Voltage (V)')
pylab.grid()
pylab.legend(loc='best')
pylab.xticks(rotation=30)
pylab.tight_layout()
pylab.show()

Пример #6
0
cal_freq = 10

# skip first samples due to unstable xfer
skip = 2 * 0x400
data_points = skip + 20 * 0x400

scope = Oscilloscope()
scope.setup()
scope.open_handle()
scope.set_sample_rate(sample_rate_index)
scope.set_ch1_voltage_range(voltage_range)
print(scope.set_calibration_frequency(cal_freq))

ch1_data, _ = scope.read_data(data_points)  #,raw=True)#timeout=1)

voltage_data = scope.scale_read_data(ch1_data[skip:], voltage_range)
timing_data, _ = scope.convert_sampling_rate_to_measurement_times(
    data_points - skip, sample_rate_index)
scope.close_handle()

if len(timing_data) != len(voltage_data):
    w = sys.stderr.write
    w('data lengths differ!\n')
    w(str([(s, len(eval(s + '_data'))) for s in 'timing voltage'.split()]))
    w('\n')
    exit(1)

# store the data
with open('/tmp/scopevis.dat', 'wt') as ouf:
    ouf.write('\n'.join('{:8f}'.format(v) for v in voltage_data))
    ouf.write('\n')
Пример #7
0
    new_data.extend(data[-window:])
    return new_data

sample_rate_index = 0x04
voltage_range = 0x01
data_points = 0x2000

scope = Oscilloscope()
scope.setup()
scope.open_handle()
scope.set_sample_rate(sample_rate_index)
scope.set_ch1_voltage_range(voltage_range)

ch1_data, _ = scope.read_data(data_points)#,raw=True)#timeout=1)

voltage_data = scope.scale_read_data(ch1_data, voltage_range)
timing_data, _ = scope.convert_sampling_rate_to_measurement_times(data_points, sample_rate_index)
scope.close_handle()

if len(timing_data) != len(voltage_data):
    w = sys.stderr.write
    w('data lengths differ!\n')
    w(str([(s,len(eval(s+'_data')))for s in 'timing voltage'.split()]))
    w('\n')
    exit(1)

# store the data
with open('/tmp/scopevis.dat', 'wt') as ouf:
    ouf.write('\n'.join('{:8f}'.format(v) for v in voltage_data))
    ouf.write('\n')
def extend_callback(ch1_data, _):
    data_extend(ch1_data)

start_time = time.time()
shutdown_event = scope.read_async(extend_callback, data_points, outstanding_transfers=25)
print "Clearing FIFO and starting data transfer..."
i = 0
scope.start_capture()
while time.time() - start_time < 1:
    time.sleep(0.01)
scope.stop_capture()
print "Stopping new transfers."
shutdown_event.set()
print "Snooze 1"
time.sleep(1)
print "Closing handle"
scope.close_handle()
print "Handle closed."
print "Points in buffer:", len(data)
plt.figure(0)
plt.plot(scope.scale_read_data(data, voltage_range))
plt.figure(1)
plt.plot(np.fft.fft(scope.scale_read_data(data, voltage_range)))
stab = build_stability_array(scope.scale_read_data(data, voltage_range), threshold=1.2)
stab_avg, stab_std = np.average(stab), np.std(stab)
print "Stability", stab_avg, "+/-", stab_std, "({}% deviance)".format(100.0*stab_std/stab_avg)
bad_pulse_count = len([p for p in stab if abs(stab_avg - p) >= stab_std])
print "Pulses more than 1 std dev out: {}/{} ({} %)".format(bad_pulse_count, len(stab), 100.0*bad_pulse_count/len(stab))
print stab
plt.show()
                                  data_points,
                                  outstanding_transfers=25)
print "Clearing FIFO and starting data transfer..."
i = 0
scope.start_capture()
while time.time() - start_time < 1:
    time.sleep(0.01)
scope.stop_capture()
print "Stopping new transfers."
shutdown_event.set()
print "Snooze 1"
time.sleep(1)
print "Closing handle"
scope.close_handle()
print "Handle closed."
print "Points in buffer:", len(data)
plt.figure(0)
plt.plot(scope.scale_read_data(data, voltage_range))
plt.figure(1)
plt.plot(np.fft.fft(scope.scale_read_data(data, voltage_range)))
stab = build_stability_array(scope.scale_read_data(data, voltage_range),
                             threshold=1.2)
stab_avg, stab_std = np.average(stab), np.std(stab)
print "Stability", stab_avg, "+/-", stab_std, "({}% deviance)".format(
    100.0 * stab_std / stab_avg)
bad_pulse_count = len([p for p in stab if abs(stab_avg - p) >= stab_std])
print "Pulses more than 1 std dev out: {}/{} ({} %)".format(
    bad_pulse_count, len(stab), 100.0 * bad_pulse_count / len(stab))
print stab
plt.show()