diff --git a/dstat_interface/core/dstat/comm.py b/dstat_interface/core/dstat/comm.py index d78ea58e2522ec015db16a95728fe492be13c48a..66903c8a59eda2ddb33c4547deaaeb44df24529f 100755 --- a/dstat_interface/core/dstat/comm.py +++ b/dstat_interface/core/dstat/comm.py @@ -192,7 +192,7 @@ class SerialConnection(GObject.Object): def get_proc(self, block=False): self.assert_connected() - + if block is True: return self.proc_pipe_p.recv() else: @@ -211,7 +211,7 @@ class SerialConnection(GObject.Object): return self.ctrl_pipe_p.recv() else: return None - + def get_data(self, block=False): self.assert_connected() diff --git a/dstat_interface/core/dstat/dfu.py b/dstat_interface/core/dstat/dfu.py index 3b56288c0bb68ee81f3e4e2b3b25c7158331a376..101b9da84d944ed9560e9df26b2666635d590324 100755 --- a/dstat_interface/core/dstat/dfu.py +++ b/dstat_interface/core/dstat/dfu.py @@ -278,6 +278,7 @@ def test_firmware_version(current=None): logger.error('Unexpected git error. Git exited {}'.format(test)) return False, None + def dfu_program(path='./dstat-firmware.hex'): """Tries to program DStat over USB with DFU with hex file at path.""" try: diff --git a/dstat_interface/core/experiments/chronoamp.py b/dstat_interface/core/experiments/chronoamp.py index 5998178beb2328f7e206f2fae4bbfffc348b9f43..bce5ecb6ede083565f00aa929de93af4e2ec949c 100644 --- a/dstat_interface/core/experiments/chronoamp.py +++ b/dstat_interface/core/experiments/chronoamp.py @@ -2,9 +2,12 @@ import time import struct import numpy as np import serial +from copy import deepcopy + +from .experiment_template import PlotBox, Experiment, exp_logger, dstat_logger from ..interface.plot import mean, plotSpectrum, findBounds +from ..dstat import state -from .experiment_template import PlotBox, Experiment, exp_logger class ChronoampBox(PlotBox): def format_plots(self): @@ -63,10 +66,141 @@ class Chronoamp(Experiment): if newline is True: self.data['current_time'].append(deepcopy(self.line_data)) + try: + for i, item in enumerate(self.data['current_time'][line]): + item.append(data[i]) + except IndexError: + pass + + +class ManExp(Chronoamp): + id = 'man' + """Manual experiment""" + def setup(self): + self.handler_ids = [self.parameters['exp_window'].connect('new_voltage', self.new_voltage), + self.parameters['exp_window'].connect('new_gain', self.new_gain)] + + self.plots.append(ManBox('current_time')) + + self.datatype = "linearData" + self.datalength = 2 + self.databytes = 8 + self.data = {'current_time': [([], [], [])]} + self.line_data = ([], [], []) + self.columns = ['Time (s)', 'Current (A)', 'Voltage (mV)'] + self.plot_format = { + 'current_time': { + 'labels': self.columns, + 'xlims': (0, 10) + } + } + + self.commands.append("EN") + + def new_voltage(self, widget, voltage): + state.ser.send_ctrl("v{}\n".format(int(voltage*(65536./3000)+32768))) + + def new_gain(self, widget): + state.ser.send_ctrl("g{}\n".format(self.parameters['adc_pot'].params['gain'])) + + def serial_handler(self): + """Handles incoming serial transmissions from DStat. Returns False + if stop button pressed and sends abort signal to instrument. Sends + data to self.data_pipe as result of self.data_handler). + """ + + def check_ctrl(): + if self.ctrl_pipe.poll(): + input = self.ctrl_pipe.recv() + exp_logger.info("serial_handler: %s", input) + if input == "DISCONNECT": + self.serial.write('a') + self.serial.reset_input_buffer() + exp_logger.info("serial_handler: ABORT pressed!") + time.sleep(.3) + return False + elif input == 'a': + self.serial.write('a') + else: + self.serial.write(input) + + scan = 0 + voltage = 0 + + try: + while True: + check_ctrl() + + for line in self.serial: + check_ctrl() + line_in = line.lstrip() + if line_in.startswith('B'): + data = self.data_handler( + (scan, voltage, self.serial.read(size=self.databytes))) + data = self.data_postprocessing(data) + if data is not None: + self.data_pipe.send(data) + try: + self.datapoint += 1 + except AttributeError: # Datapoint counting is optional + pass + + elif line_in.startswith('S'): + scan += 1 + + elif line_in.startswith('G'): + self.gain = self.parameters["gain_table"][int(line.split(" ")[1])] + + elif line_in.startswith('V'): + voltage = int(line.split(" ")[1]) + + elif line_in.startswith("#"): + dstat_logger.info(line.lstrip().rstrip()) + + elif line_in.startswith("R"): + self.ctrl_pipe.send("R") + + elif line_in.startswith("@DONE"): + dstat_logger.debug(line.lstrip().rstrip()) + time.sleep(.3) + return True + + except serial.SerialException: + return False + + def ctrl_loop(self, data): + if data == 'R': + self.emit('exp_ready') + + def data_handler(self, data_input): + """Overrides Experiment method to not convert x axis to mV.""" + scan, voltage, data = data_input + # 2*uint16 + int32 + seconds, milliseconds, current = struct.unpack('