Пример #1
0
class tempProcedure(Procedure):
    sample_name = Parameter("Sample Name", default='undefined')
    save_dir = Parameter("Save Directory", default=r"\junk")
    stop_temp = FloatParameter("Target Temperature", units="C", default=20)
    ramp_time = IntegerParameter("Ramp Time", units="min", default=1)
    hold_time = IntegerParameter("Hold Time", units="min", default=1)
    DATA_COLUMNS = ["global_time", "temperature", "heating_time"]

    def startup(self):
        log.info("Stop, Ramp, Hold: %.1f, %d, %d" %
                 (self.stop_temp, self.ramp_time, self.hold_time))
        log.info("Connecting temperature controller")
        self.tempcontrol = ThorlabsTC200USB('COM3')
        self.tempcontrol.set_temp(self.tempcontrol.act_temp())
        if self.tempcontrol.get_stat():
            self.tempcontrol.toggleenable()
        self.tempcontrol.set_mode('cycle')
        self.tempcontrol.set_cycle_num(1)
        self.tempcontrol.set_stop_temp(self.stop_temp)
        self.tempcontrol.set_ramp_time(self.ramp_time)
        self.tempcontrol.set_hold_time(self.hold_time)
        self.tempcontrol.toggleenable()
        self.duration = (self.ramp_time + self.hold_time) * 60.

    def execute(self):
        num_progress = np.floor(self.duration / 0.05)
        start_time = time()
        end_time = start_time + self.duration
        progress_iterator = 0

        while time() < end_time:
            self.emit("progress", int(100 * progress_iterator / num_progress))
            progress_iterator += 1
            log.info("Recording results")
            self.emit(
                'results', {
                    "global_time": time(),
                    "heating_time": time() - start_time,
                    "temperature": self.tempcontrol.act_temp()
                })
            if self.should_stop():
                log.warning("Caught stop flag in procedure.")
                break
            sleep(0.05)

    def shutdown(self):
        log.info("Finished with scan. Shutting down instruments.")
        if self.tempcontrol.get_stat():
            self.tempcontrol.toggleenable()
        self.tempcontrol.adapter.connection.close(
        )  #close serial port to avoid port already open error
Пример #2
0
class tempProcedure(Procedure):
    sample_name = Parameter("Sample Name", default='undefined')
    save_dir = Parameter("Save Directory", default=r"\junk")
    stop_temperature = FloatParameter("Set Temperature", units="C", default=20)
    ramp_time = IntegerParameter("Ramp Time", units="min", default=1)
    hold_time = IntegerParameter("Hold Time", units="min", default=1)
    DATA_COLUMNS = ["global_time", "temperature", "heating_time"]

    def startup(self):
        self.duration = (self.ramp_time + self.hold_time) * 60.
        log.info(self.duration)
        log.info("Connecting temperature controller")
        self.tempcontrol = ThorlabsTC200USB('/dev/ttyUSB0')
        if self.tempcontrol.get_stat():
            self.tempcontrol.toggleenable()

        self.tempcontrol.set_mode('cycle')
        self.tempcontrol.set_cycle_num(1)
        self.tempcontrol.set_stop_temp(self.stop_temperature)
        self.tempcontrol.set_ramp_time(self.ramp_time)
        self.tempcontrol.set_hold_time(self.hold_time)
        self.tempcontrol.toggleenable()
        #log.info('Heater enabled, heating to:%.1f in %d minutes and holding for %d minutes' % (self.stop_temperature, self.ramp_time, self.hold_time))

    def execute(self):
        num_progress = np.floor(self.duration / 0.05)
        start_time = time.time()
        end_time = start_time + self.duration
        progress_iterator = 0

        while time.time() < end_time:
            #self._update_parameters()
            self.emit("progress", int(100 * progress_iterator / num_progress))
            progress_iterator += 1
            log.info("Recording results")
            self.emit(
                'results', {
                    "global_time": time.time(),
                    "temperature": self.tempcontrol.act_temp(),
                    "heating_time": time.time() - start_time
                })
            if self.should_stop():
                log.warning("Caught stop flag in procedure.")
                break
            sleep(0.05)

    def shutdown(self):
        log.info("Finished with scan. Shutting down instruments.")
        if self.tempcontrol.get_stat():
            self.tempcontrol.toggleenable()
Пример #3
0
class TestProcedure(Procedure):

    iterations = IntegerParameter('Loop Iterations', default=100)
    delay = FloatParameter('Delay Time', units='s', default=0.2)
    seed = Parameter('Random Seed', default='12345')

    DATA_COLUMNS = ['Iteration', 'Random Number']

    def startup(self):
        log.info("Setting up random number generator")
        random.seed(self.seed)

    def execute(self):
        log.info("Starting to generate numbers")
        for i in range(self.iterations):
            data = {'Iteration': i, 'Random Number': random.random()}
            log.debug("Produced numbers: %s" % data)
            self.emit('results', data)
            self.emit('progress', 100 * i / self.iterations)
            sleep(self.delay)
            if self.should_stop():
                log.warning("Catch stop command in procedure")
                break

    def shutdown(self):
        log.info("Finished")
class TestProcedure(Procedure):

    iterations = IntegerParameter('Loop Iterations', default=100)
    delay = FloatParameter('Delay Time', units='s', default=0.2)
    seed = Parameter('Random Seed', default='12345')
    iteration = Measurable('Iteration', default=0)
    random_number = Measurable('Random Number', random.random)
    offset = Measurable('Random Number + 1', default=0)

    def startup(self):
        log.info("Setting up random number generator")
        random.seed(self.seed)

    def measure(self):
        data = self.get_datapoint()
        data['Random Number + 1'] = data['Random Number'] + 1
        log.debug("Produced numbers: %s" % data)
        self.emit('results', data)
        self.emit('progress', 100. * self.iteration.value / self.iterations)

    def execute(self):
        log.info("Starting to generate numbers")
        for self.iteration.value in range(self.iterations):
            self.measure()
            sleep(self.delay)
            if self.should_stop():
                log.warning("Catch stop command in procedure")
                break

    def shutdown(self):
        log.info("Finished")
Пример #5
0
class RandomProcedure(Procedure):

    iterations = IntegerParameter('Loop Iterations')
    delay = FloatParameter('Delay Time', units='s', default=0.2)
    seed = Parameter('Random Seed', default='12345')

    DATA_COLUMNS = ['Iteration', 'Random Number']

    def startup(self):
        log.info("Setting the seed of the random number generator")
        random.seed(self.seed)

    def execute(self):
        log.info("Starting the loop of %d iterations" % self.iterations)
        for i in range(self.iterations):
            data = {
                'Iteration': i,
                'Random Number': random.random()
            }
            self.emit('results', data)
            log.debug("Emitting results: %s" % data)
            sleep(self.delay)
            if self.should_stop():
                log.warning("Caught the stop flag in the procedure")
                break
Пример #6
0
class tempControlProcedure(Procedure):
    """
    Procedure for calibrating the voltage to field strength relationship
    on Daedalus. Assumes that the center calibration has already ran.
    """

    # control parameters
    calib_name = Parameter("Calibration Name", default='')
    temp_start = FloatParameter("Temperature start", units="C", default=-30.)
    temp_stop = FloatParameter("Temperature stop", units="C", default=100.)
    temp_step = FloatParameter("Temperature step", units="C", default=0.1)
    #heating_time = FloatParameter("Heating time", units="s", default=60.)
    #queued_time = Parameter("Queued Time")

    DATA_COLUMNS = ["set_temp","act_temp","elapsed_time"]

    def startup(self):
        log.info("Connecting and configuring the instruments")
        self.heatcontrol = ThorlabsTC200USB('/dev/ttyUSB0')
        self.heatcontrol.toggleenable()
        
    def execute(self):
        start_time = time()
        temp_points = np.arange(self.temp_start, self.temp_stop, self.temp_step)
        if self.temp_stop not in temp_points:
            temp_points = np.append(temp_points, self.temp_stop)

        temp_points = np.concatenate((temp_points, temp_points[::-1]))
        num_progress = temp_points.size

        for progress_iterator, t in enumerate(temp_points):
            log.info("Setting temperature %f C"%t)
            self.heatcontrol.set_temp = t
            sleep(1)
            self.emit('progress', int(100*progress_iterator/num_progress))
            self.emit('results',
                      {
                          "set_temp": self.heatcontrol.get_temp(),
                          "act_temp": self.heatcontrol.act_temp(),
                          "elapsed_time": time()-start_time
                      })
            if self.should_stop():
                log.warning("Caught stop flag in procedure.")
                break

    def shutdown(self):
        log.info("Done with scan. Shutting down instruments")
        self.heatcontrol.toggleenable()
Пример #7
0
class RandomProcedure(Procedure):

    iterations = IntegerParameter('Loop Iterations', default=100)
    delay = FloatParameter('Delay Time', units='s', default=0.001)
    seed = Parameter('Random Seed', default='12345')

    DATA_COLUMNS = ['Iteration', 'Random Number']

    def startup(self):
        random.seed(self.seed)

    def execute(self):
        for i in range(self.iterations):
            data = {'Iteration': i, 'Random Number': random.random()}
            self.emit('results', data)
            self.emit('progress', 100. * i / self.iterations)
            sleep(self.delay)
            if self.should_stop():
                break
class SS9Procedure(Procedure):

    your_name = Parameter("Your Name", default='')
    field_strength = FloatParameter("Field Strength", units='T', default=0)
    delay = FloatParameter('Delay Time', units='s', default=20)
    T_max = IntegerParameter('Maximum Temp.', units='K', default=350)
    num_averages = IntegerParameter('Number of Averages', default=5)

    mm1_measurement = BooleanParameter('Voltage', default=True)
    mm1_range = FloatParameter('Range', units='SI', default=1)
    mm1_address = Parameter("MM1 Address", default='')

    mm2_measurement = BooleanParameter('Voltage', default=True)
    mm2_range = FloatParameter('Range', units='SI', default=1)
    mm2_address = Parameter("MM2 Address", default='')

    mm3_measurement = BooleanParameter('Voltage', default=True)
    mm3_range = FloatParameter('Range', units='SI', default=1)
    mm3_address = Parameter("MM3 Address", default='')

    mm4_measurement = BooleanParameter('Voltage', default=True)
    mm4_range = FloatParameter('Range', units='SI', default=1)
    mm4_address = Parameter("MM4 Adress", default='')

    DATA_COLUMNS = [
        'elapsed_time', 'T', 'T_err', 'MM1_reading', 'MM1_error',
        'MM2_reading', 'MM2_error', 'MM3_reading', 'MM3_error', 'MM4_reading',
        'MM4_error'
    ]

    def startup(self):
        log.info("Setting up Multimeters")
        self.mm1 = Keithley2000(self.mm1_address)
        self.mm2 = Keithley2000(self.mm2_address)
        self.mm3 = Keithley2000(self.mm3_address)
        self.mm4 = Keithley2000(self.mm4_address)

        if self.mm1_measurement:
            self.mm1.measure_voltage(self.mm1_range)
        else:
            self.mm1.measure_current(self.mm1_range)

        if self.mm2_measurement:
            self.mm2.measure_voltage(self.mm2_range)
        else:
            self.mm2.measure_current(self.mm2_range)

        if self.mm3_measurement:
            self.mm3.measure_voltage(self.mm3_range)
        else:
            self.mm3.measure_current(self.mm3_range)

        if self.mm4_measurement:
            self.mm4.measure_voltage(self.mm4_range)
        else:
            self.mm4.measure_current(self.mm4_range)

        log.info("Setting up Thermocouple")

        self.mm2.voltage_nplc = 1  # Integration constant to Medium
        self.mm3.voltage_nplc = 1  # Integration constant to Medium
        self.mm4.voltage_nplc = 1  # Integration constant to Medium
        sleep(2)

    def execute(self):
        log.info("Starting Measurement")
        #prev_T = read_T
        T_min = ul.t_in(0, 0, TempScale.KELVIN)
        T = [T_min]
        start_time = time.time()
        while np.mean(T) < self.T_max:
            log.info("Temperature is at %d, waiting for it to reach %d" % \
                     (np.mean(T), self.T_max))
            sleep(self.delay)
            elapsed_time = time.time() - start_time

            T, M1, M2, M3, M4 = [], [], [], [], []

            for i in range(self.num_averages):
                log.info("Doing average %d of %d" % (i, self.num_averages))
                if self.mm1_measurement:
                    M1.append(self.mm1.voltage)
                else:
                    M1.append(self.mm1.current)

                if self.mm2_measurement:
                    M2.append(self.mm2.voltage)
                else:
                    M2.append(self.mm2.current)

                if self.mm3_measurement:
                    M3.append(self.mm3.voltage)
                else:
                    M3.append(self.mm3.current)

                if self.mm4_measurement:
                    M4.append(self.mm4.voltage)
                else:
                    M4.append(self.mm4.current)

                T.append(ul.t_in(0, 0, TempScale.KELVIN))

                sleep(self.delay / (self.num_averages + 1))

            prog = int(100 * np.abs(
                (np.mean(T) - T_min) / (self.T_max - T_min)))
            self.emit("progress", prog)

            data = {
                'elapsed_time': elapsed_time,
                'T': np.mean(T),
                'T_err': np.std(T),
                'MM1_reading': np.mean(M1),
                'MM1_error': np.std(M1),
                'MM2_reading': np.mean(M2),
                'MM2_error': np.std(M2),
                'MM3_reading': np.mean(M3),
                'MM3_error': np.std(M3),
                'MM4_reading': np.mean(M4),
                'MM4_error': np.std(M4)
            }

            self.emit('results', data)
            if self.should_stop():
                log.warning("Catch stop command in procedure")
                break
            else:
                continue

    def shutdown(self):
        log.info("Finished")
        log.info("Please shut off heater, magnet and other instruments")
class MagFieldProcedure(Procedure):

    #Magnetic Field calibration (input field, get current)

    pA = -6.78951587e-06       #Constant
    pB = 3.27549922e-03       #First order term
    
    def IfromB(self,B):
        if B < 0:
            return 0
        elif B >= self.pA:
            return self.pA + (B)*self.pB + (B*B)*self.pC + (B*B*B)*self.pD #Calculating the current to produce a given H
        else:
            return 0.0

    fileroot = Parameter('File Root',default='.')
    filename = Parameter('File Prepend',default='2ndHarm')
    field = FloatParameter('Applied Field', units='T', default=.1)
    lockinamp = FloatParameter('Lockin Amplitude', units='V', default = 1.0)
    lockinfreq = FloatParameter('Lockin Reference', units='Hz', default = 1337.7)
    start_angle = FloatParameter('Start Angle', units='degrees', default=0)
    stop_angle = FloatParameter('Stop Angle', units='degrees', default=270)
    angle_step = FloatParameter('Angle Step', units='degrees', default=1)
    delay = FloatParameter('Delay Time', units='ms', default=100)

    inverse_spacing = BooleanParameter('Inverse Spacing')
    field_start = FloatParameter('Start Field', units='T', default=.05)
    field_stop = FloatParameter('Stop Field', units='T', default=.3)
    field_steps = IntegerParameter('Field Steps', default=10)

    shutdown_after = BooleanParameter('Shutdown Field After?')


    

    DATA_COLUMNS = ['Angle (deg)','Current (A)', 'Magnetic Field (T)',
     '1X Voltage (V)', '1Y Voltage (V)',
     '2X Voltage (V)', '2Y Voltage (V)']

    def inmotion(self,rotator):
        moving = -1
        success = False
        while not success:
            try:
                moving=int(rotator.query('LOC?'))
            except pyvisa.VisaIOError:
                pass
            except ValueError:
                moving = 0
                success = True
            else:
                success = True
                if moving > -1:
                    moving = 0
                else:
                    moving = -1
            sleep(0.1)
        return moving


    def homeangle(self, rotator):
        success = False
        while not success:
            try:
                rotator.write('HOME')
            except pyvisa.VisaIOError:
                pass
            else:
                success = True
        moving = -1
        while moving ==-1:
            moving = self.inmotion(self.rotator)
            sleep(1)

    def setangle(self, rotator,angle):
        success = False
        while not success:
            try:
                rotator.write('GOTO %f' % angle)
            except pyvisa.VisaIOError:
                pass
            else:
                success = True

    def getangle(self, rotator):
        moving = -1
        while moving == -1:
            moving = self.inmotion(rotator)
            sleep(0.1)

        success = False
        while not success:
            try:
                angle = float(rotator.query('LOC?'))
            except pyvisa.VisaIOError:
                pass
            except ValueError:
                pass
            else:
                success = True
            sleep(0.1)
        return angle



    def startup(self):
        log.info("Setting up instruments")
        self.source = Sorensen30035E(7)

        self.lockin1 = DSP7265(27)
        self.lockin2 = DSP7265(12)


        self.rm = pyvisa.ResourceManager()
        self.rotator = self.rm.open_resource('ASRL4::INSTR')
        sleep(2)
        self.rotator.clear()
        sleep(1)
        self.homeangle(self.rotator)


    def execute(self):
        #Defining the current values
        angles_up = np.arange(self.start_angle, self.stop_angle+self.angle_step, self.angle_step)
        steps_up = len(angles_up)

        ###Ramping up the magnet current to minimum current
        log.info("Ramping to field value.")
        self.current = self.IfromB(self.field)
        if self.current > 0 :
            self.source.ramp_to_current(self.current, self.current/1e-1)
        self.source.ramp_to_current(self.current)
        sleep(1)

        log.info('Setting Lockin Parameters')
        self.lockin1.voltage = self.lockinamp
        self.lockin1.frequency = self.lockinfreq

        log.info("Starting to sweep through angle.")
        for i, angle in enumerate(angles_up):
            log.debug("Setting angle: %g degrees" % angle)
            self.setangle(self.rotator,angle)
            true_angle = self.getangle(self.rotator)
            sleep(self.delay*1e-3)
            magfield = self.field
            lockinX1 = self.lockin1.x
            lockinY1 = self.lockin1.y
            lockinX2 = self.lockin2.x
            lockinY2 = self.lockin2.y
            data = {
                'Angle (deg)' : true_angle,
                'Current (A)': self.current,
                'Magnetic Field (T)': magfield,
                '1X Voltage (V)': lockinX1,
                '1Y Voltage (V)': lockinY1,
                '2X Voltage (V)': lockinX1,
                '2Y Voltage (V)': lockinY1,,
            }
            self.emit('results', data)
            self.emit('progress', 100.*i/steps_up)
            if self.should_stop():
                log.warning("Catch stop command in procedure")
                return


    def shutdown(self):
        log.info("Shutting down.")

        #Ramping down the magnetic field
        if self.shutdown_after:
            now = self.current
            self.source.ramp_to_current(0.0,now/1e-1)
            sleep(1)
        sleep(1)
        self.rotator.close()
        #Turning off the RF source
        #self.RFsource.power = -100
        log.info("Finished")
Пример #10
0
class PulseIVCycle(ProcedureWithInstruments):
    """
    Uses a Keithley 26XX device to perform the following measurement:
    1. Pulse at voltage `pulse_voltage` for `pulse_duration` in ms
    2. Perform `cycles` sweeps from `min_voltage` to `max_voltage` starting with a sweep from 0 to max and ending with a sweep from max to 0
    """

    # define measurement paramters here
    max_voltage = FloatParameter('Maximum Voltage', units='V', default=1)
    min_voltage = FloatParameter('Minimum Voltage', units='V', default=-1)
    compliance = FloatParameter('Compliance', units='A', default=0.1)
    cycles = IntegerParameter('No. of Cycles', default=1)
    voltage_step = FloatParameter('Voltage Step', units='V', default=0.1)
    stime = FloatParameter('Settling Time', units='s', default=0.5)

    # Add Comments as parameters to show up in measurement file
    operator = Parameter('Operator', default='JD')
    location = Parameter('Location', default='Mun')
    setup = Parameter('Setup', default='Probe Station')

    # define DATA_COLUMNS that are written to the file
    DATA_COLUMNS = ['Voltage (V)', 'Current (A)', 'Current Std (A)', 'Cycle']

    def startup(self):
        # System startup: Build instances of all necessary device objects here
        log.info("Connecting and configuring the instrument")
        log.info("Instrument Adress" + instrument_adress)
        self.sourcemeter = Keithley2600(instrument_adress)
        self.sourcemeter.reset()
        self.sourcemeter.clear_buffer()
        self.sourcemeter.triad()
        self.sourcemeter.set_screentext(
            '$R PulseIVCycle $N$B Ready to measure')

    def execute(self):
        # Make Pulse

        # Make Sweep
        log.info("Starting sweep")
        steps = (self.max_voltage - self.min_voltage) / self.voltage_step
        self.sourcemeter.autosweep(0, self.max_voltage, self.stime, steps,
                                   'lin', 'V')
        for i in cycles:
            if self.should_stop():
                log.info("User aborted the procedure")
                break
            log.info(f"Performing sweep number {i}")
            self.soucemeter.autosweep(self.max_voltage, self.min_voltage,
                                      self.stime, steps, 'lin', 'V')
            # TODO:Wait for finished measurement?!
            self.soucemeter.autosweep(self.min_voltage, self.max_voltage,
                                      self.stime, steps, 'lin', 'V')
            # TODO:Wait for finished measurement?!
        else:
            self.sourcemeter.autosweep(self.max_voltage, 0, self.stime, steps,
                                       'lin', 'V')
            # TODO:Wait for finished measurement?!

        data_array = self.sourcemeter.get_buffer_data()

        # print to console to check array
        print(data_array)
        # emit data
        for i in range(0, len(data_array) - 1):
            self.emit(
                'results', {
                    'Voltage (V)': data_array[0][i],
                    'Current (A)': data_array[1][i],
                    'Voltage Std (V)': data_array[2][i]
                })

    def shutdown(self):
        self.sourcemeter.shutdown()
Пример #11
0
 class FakeProcedure(Procedure):
     str_param = Parameter("String Parameter")
     bool_param = BooleanParameter("Boolean Parameter")
     float_param = FloatParameter("Float Parameter")
Пример #12
0
class DepProcedure(Procedure):

    plate_current = FloatParameter('Plating Current',
                                   units='A',
                                   minimum=-1,
                                   maximum=1,
                                   default=0.000268055577)
    pulse = FloatParameter('Pulse length', units='s', maximum=1e8, default=0.1)
    delay = FloatParameter('Delay Time', units='s', maximum=1e8, default=5.9)
    repeats = IntegerParameter('Cycles',
                               units=None,
                               minimum=1,
                               maximum=1e8,
                               default=500)
    deltat = FloatParameter('Measurement Frequency', units='Hz', default=20)
    voltage_range = FloatParameter('Potential Range', units='V', default=10)
    directory = Parameter('Working Directory', default='C:/Data/')
    filename = Parameter('Filename',
                         default=unique_filename(str(directory),
                                                 prefix='Plate_'))
    DATA_COLUMNS = ['Current (A)', 'Potential (V)', 'Time (s)']

    def startup(self):
        log.info("Setting up instruments")
        """
        To use the Nanovoltmeter instead of the Sourcemeter to measure
        potential, uncomment the following section and change the corresponding
        section in execute routine to measure from meter instead of source    
        """
        #        self.meter = Keithley2182("GPIB::7::INSTR")
        #        self.meter.measure_voltage()
        #        self.meter.voltage_range = self.voltage_range
        #        self.meter.voltage_nplc = 1 # Integration constant to Medium

        self.source = Keithley2400("GPIB::24::INSTR")
        self.source.apply_current()
        self.source.measure_voltage()
        self.source.source_current_range = self.plate_current * 1.1  # Current range is 10% over target
        self.source.compliance_voltage = self.voltage_range
        self.source.enable_source()
        sleep(2)

    def execute(self):
        pulses = np.repeat(self.plate_current,
                           (self.pulse) * 1 // (1 / self.deltat))
        rest = np.repeat(0, (self.delay) * 1 // (1 / self.deltat))
        currents = np.concatenate((pulses, rest))
        currents = np.tile(currents, np.int(self.repeats))
        #        currents *= 1e-3 # to mA from A
        steps = len(currents)
        log.info("Starting Pulsed electrodeposition")
        for i, current in enumerate(currents):
            log.debug("Applying current: %g A" % current)

            self.source.source_current = current
            # Or use self.source.ramp_to_current(current, delay=0.1)
            sleep(1 / self.deltat)

            voltage = self.source.voltage
            time = i / self.deltat
            data = {
                'Current (A)': current,
                'Potential (V)': voltage,
                'Time (s)': time
            }
            self.emit('results', data)
            self.emit('progress', 100. * i / steps)
            if self.should_stop():
                log.warning("Catch stop command in procedure")
                break

    def shutdown(self):
        self.source.shutdown()
        self.source.beep(783.991, 0.1)
        sleep(0.125)
        self.source.beep(1046.50, 0.1)
        sleep(0.125)
        self.source.beep(1318.51, 0.1)
        sleep(0.125)
        self.source.beep(1567.98, 0.22)
        sleep(0.25)
        self.source.beep(1318.51, 0.1)
        sleep(0.125)
        self.source.beep(1567.98, 0.25)
        log.info("Finished")
Пример #13
0
class IVProcedure(Procedure):

    max_current = FloatParameter('Maximum Current', units='mA', default=10)
    min_current = FloatParameter('Minimum Current', units='mA', default=-10)
    current_step = FloatParameter('Current Step', units='mA', default=0.1)
    delay = FloatParameter('Delay Time', units='ms', default=20)
    voltage_range = FloatParameter('Voltage Range', units='V', default=10)
    directory = Parameter('Working Directory', default='C:/Data/')
    filename = Parameter('Filename', default=unique_filename(str(directory), prefix='IV'))
    DATA_COLUMNS = ['Current (A)', 'Voltage (V)', 'Resistance (Ohm)']

    def startup(self):
        log.info("Setting up instruments")
#        self.meter = Keithley2182("GPIB::7::INSTR")
#        self.meter.measure_voltage()
#        self.meter.voltage_range = self.voltage_range
#        self.meter.voltage_nplc = 1 # Integration constant to Medium
        
        self.source = Keithley2400("GPIB::24::INSTR")
        self.source.apply_current()
        self.source.source_current_range = self.max_current*1e-3 # A
        self.source.complinance_voltage = self.voltage_range
        self.source.enable_source()
        sleep(2)

    def execute(self):
        currents_up = np.arange(self.min_current, self.max_current, self.current_step)
        currents_down = np.arange(self.max_current, self.min_current, -self.current_step)
        currents = np.concatenate((currents_up, currents_down)) # Include the reverse
        currents *= 1e-3 # to mA from A
        steps = len(currents)
        
        log.info("Starting to sweep through current")
        for i, current in enumerate(currents):
            log.debug("Measuring current: %g mA" % current)

            self.source.source_current = current
            # Or use self.source.ramp_to_current(current, delay=0.1)
            sleep(self.delay*1e-3)
            
            voltage = self.meter.voltage

            if abs(current) <= 1e-10:
                resistance = np.nan
            else:
                resistance = voltage/current
            data = {
                'Current (A)': current,
                'Voltage (V)': voltage,
                'Resistance (Ohm)': resistance
            }
            self.emit('results', data)
            self.emit('progress', 100.*i/steps)
            if self.should_stop():
                log.warning("Catch stop command in procedure")
                break

    def shutdown(self):
        self.source.shutdown()
        self.source.beep(783.991,0.1)
        sleep(0.125)
        self.source.beep(1046.50,0.1)
        sleep(0.125)
        self.source.beep(1318.51,0.1)
        sleep(0.125)
        self.source.beep(1567.98,0.22)
        sleep(0.25)
        self.source.beep(1318.51,0.1)
        sleep(0.125)
        self.source.beep(1567.98,0.25)
        log.info("Finished")
Пример #14
0
class TestProcedure(Procedure):

    iterations = IntegerParameter('Loop Iterations', default=100)
    delay = FloatParameter('Delay Time', units='s', default=0.2)
    seed = Parameter('Random Seed', default='12345')

    DATA_COLUMNS = ['Iteration', 'Random Number']

    def startup(self):
        log.info("Setting up random number generator")
        random.seed(self.seed)

    def execute(self):
        log.info("Starting to generate numbers")
        for i in range(self.iterations):
            data = {'Iteration': i, 'Random Number': random.random()}
            log.debug("Produced numbers: %s" % data)
            self.emit('results', data)
            self.emit('progress', 100 * i / self.iterations)
            sleep(self.delay)
            if self.should_stop():
                log.warning("Catch stop command in procedure")
                break

    def get_estimates(self, sequence_length=None, sequence=None):
        """ Function that returns estimates for the EstimatorWidget. If this function
        is implemented (and does not return a NotImplementedError) the widget is
        automatically activated.

        The function is expected to return an int or float, or a list of tuples. If an int or
        float is returned, it should represent the duration in seconds.If a list of
        tuples is returned, each tuple containing two strings, a label and the estimate
        itself:
        estimates = [
            ("label 1", "estimate 1"),
            ("label 2", "estimate 2"),
        ]
        The length of the number of estimates is not limited but has to remain unchanged after
        initialisation. Note that also the label can be altered after initialisation.

        The keyword arguments `sequence_length` and `sequence` are optional and return
        (if asked for) the length of the current sequence (of the `SequencerWidget`) or
        the full sequence.

        """
        duration = self.iterations * self.delay
        """
        A simple implementation of the get_estimates function immediately returns the duration
        in seconds.
        """
        # return duration

        estimates = list()

        estimates.append(("Duration", "%d s" % int(duration)))
        estimates.append(("Number of lines", "%d" % int(self.iterations)))

        estimates.append(("Sequence length", str(sequence_length)))

        estimates.append(
            ('Measurement finished at',
             str(datetime.now() + timedelta(seconds=duration))[:-7]))
        estimates.append(
            ('Sequence finished at',
             str(datetime.now() +
                 timedelta(seconds=duration * sequence_length))[:-7]))

        return estimates

    def shutdown(self):
        log.info("Finished")
Пример #15
0
class IVCycles(ProcedureWithInstruments):

    #define required instruments
    required_instruments = ['Keithley Instruments Inc., Model 2635B']

    # define measurement paramters here
    averages = IntegerParameter('Averages', default=50)
    measurement_delay = FloatParameter('Measurement Delay', default=0.5)
    max_voltage = FloatParameter('Maximum Voltage', units='V', default=0.5)
    min_voltage = IntegerParameter('Minimum Voltage', units='V', default=-1.0)
    compliance = FloatParameter('Compliance', units='A', default=0.1)
    cycles = IntegerParameter('No. of Cycles', default=1)
    voltage_step = FloatParameter('Voltage Step', units='V', default=0.1)

    # Add Comments as parameters to show up in measurement file
    operator = Parameter('Operator', default='JD')
    location = Parameter('Location', default='Mun')
    setup = Parameter('Setup', default='Probe Station')

    # Calculate the number of data points from range and step
    data_points = IntegerParameter(
        'Data points',
        default=np.ceil(
            (max_voltage.value - min_voltage.value) / voltage_step.value))

    # define DATA_COLUMNS that are written to the file
    DATA_COLUMNS = ['Voltage (V)', 'Current (A)']

    def startup(self):
        print('startup')
        for adress, name in self.instruments_dict.items():
            if 'Keithley Instruments Inc., Model 2635B' in name:
                self.instrument_adress = adress
        log.info("Connecting and configuring the instrument")
        log.info("Instrument Adress: " + self.instrument_adress)
        log.info("Instrument Dict: " + str(self.instruments_dict))
        self.sourcemeter = Keithley2600(self.instrument_adress)
        self.sourcemeter.triad()
        self.sourcemeter.set_screentext(
            '$R PulseIVCycle $N$B Ready to measure')

    def execute(self):
        print('execute')
        # reset instrument and its dedicated buffer
        self.sourcemeter.reset()
        self.sourcemeter.clear_buffer()
        self.sourcemeter.setup_buffer(precision=6)
        log.info(
            f'start: {self.min_voltage}. stop {self.max_voltage}, stime {self.measurement_delay}. points = {self.data_points}'
        )

        self.sourcemeter.set_output(state='ON')
        self.sourcemeter.auto_sweep(start=0,
                                    stop=self.max_voltage,
                                    stime=self.measurement_delay,
                                    points=np.ceil(self.data_points / 2 + 1),
                                    source='V')
        self.sourcemeter.wait_for_srq()
        results = self.sourcemeter.get_buffer_data()
        for i in range(0, len(results['sourced']) - 1):
            self.emit(
                'results', {
                    'Voltage (V)': results['sourced'][i],
                    'Current (A)': results['measured'][i],
                })

    def shutdown(self):
        self.sourcemeter.shutdown()
        log.info("Finished measuring")
        print('shutdown')
Пример #16
0
class DepProcedure(Procedure):
    capacity = FloatParameter('Capacity',
                              units='mAh',
                              minimum=0,
                              maximum=10,
                              default=4.29)
    c_rate = FloatParameter('Charge Rate',
                            units='C',
                            minimum=0.01,
                            maximum=20,
                            default=1)
    repeats = IntegerParameter('Cycles',
                               units=None,
                               minimum=1,
                               maximum=1e8,
                               default=50)
    deltat = FloatParameter('Measurement Frequency', units='Hz', default=1)
    voltage_range = FloatParameter('Potential Range', units='V', default=10)
    directory = Parameter('Working Directory', default='C:/Data/')
    filename = Parameter('Filename',
                         default=unique_filename(str(directory),
                                                 prefix='charge_'))
    DATA_COLUMNS = ['Time (s)', 'Current (A)', 'Potential (V)']

    def startup(self):
        log.info("Setting up instruments")
        """
        To use the Nanovoltmeter instead of the Sourcemeter to measure
        potential, uncomment the following section and change the corresponding
        section in execute routine to measure from meter instead of source    
        """
        #        self.meter = Keithley2182("GPIB::7::INSTR")
        #        self.meter.measure_voltage()
        #        self.meter.voltage_range = self.voltage_range
        #        self.meter.voltage_nplc = 1 # Integration constant to Medium

        self.source = Keithley2400("GPIB::24::INSTR")
        self.source.source_current()
        self.source.measure_voltage()
        self.source.source_current_range = self.capacity * self.c_rate * 5
        self.source.compliance_voltage = self.voltage_range
        self.source.enable_source()
        sleep(2)

    def execute(self):
        charge_rate = self.capacity * self.c_rate * 0.001  # Charge rate, in A
        discharge_rate = charge_rate * -1  # Discharge rate, in A
        currents = np.repeat(charge_rate, )
        currents_up = np.arange(self.min_current, self.max_current,
                                self.current_step)
        currents_down = np.arange(self.max_current, self.min_current,
                                  -self.current_step)

        currents = np.concatenate(
            (currents_up, currents_down))  # Include the reverse
        currents *= 1e-3  # to mA from A
        steps = len(currents)

        # To calculate the e_step, convert to V/s and divide by measurement frequency
        self.source.ramp_to_voltage(hi_e)
        e_step = 0.001 * self.sweep_rate / self.deltat
        sweep1 = np.arange(in_e, hi_e, e_step)
        sweep2 = np.arange(hi_e, lo_e, -e_step)
        sweep3 = np.arange(lo_e, hi_e, e_step)
        potentials = np.concatenate((sweep2, sweep3))
        potentials = np.tile(potentials, np.int(self.repeats))
        sweep4 = np.arange(hi_e, in_e, -e_step)
        potentials = np.concatenate((sweep1, potentials))
        potentials = np.concatenate((potentials, sweep4))
        steps = len(potentials)
        log.info("Starting Discharge-Charge")

        for i, e in enumerate(potentials):
            log.debug("Measuring potential: %g V" % e)
            self.source.source_voltage = e
            sleep(1 / self.deltat)
            current = self.source.current
            time = i / self.deltat
            data = {
                'Time (s)': time,
                'Potential (V)': e,
                'Current (A)': current
            }
            self.emit('results', data)
            self.emit('progress', 100. * i / steps)
            if self.should_stop():
                log.warning("Catch stop command in procedure")
                break

    def shutdown(self):
        self.source.shutdown()
        self.source.beep(783.991, 0.1)
        sleep(0.125)
        self.source.beep(1046.50, 0.1)
        sleep(0.125)
        self.source.beep(1318.51, 0.1)
        sleep(0.125)
        self.source.beep(1567.98, 0.22)
        sleep(0.25)
        self.source.beep(1318.51, 0.1)
        sleep(0.125)
        self.source.beep(1567.98, 0.25)
        log.info("Finished")
Пример #17
0
class Measure2ndHarmonic(Procedure):

    version = Parameter('Software Version', default="2.0.1")

    current = FloatParameter('Magnet Current',
                             units='A', default=1)
    delay = FloatParameter('Delay Time',
                           units='s', default=0.35)
    max_angle = FloatParameter('Maximum Angle',
                               units='deg', default=180)
    ramp_rate = FloatParameter('Magnet Ramping Rate',
                               units='A/s', default=0.1)
    fieldcal = FloatParameter('Magnetic Field Calibration',
                              units='mT/A', default=13.69)
    Lockin1_use = Parameter('Lock-in 1')
    Lockin2_use = Parameter('Lock-in 2')

    # degrees per edge
    # it moves at degpulse at both the rise and fall of a pulse
    degpulse = FloatParameter('Degrees per step',
                              units='deg/step', default=(90 / 50 / 2))

    # Define motorsteps where +1 is CW step and -1 is CCW step
    motorstep = 0

    DATA_COLUMNS = [
        'Angle (deg)',
        'Magnet Current (A)',
        'Magnetic Field (mT)',
        'Lock-In 1 X (V)',
        'Lock-In 1 Y (V)',
        'Lock-In 2 X (V)',
        'Lock-In 2 Y (V)'
    ]

    """
    ###########################################################################
    ###########################################################################
    #############################  STARTUP PROCEDURE  #########################
    ###########################################################################
    ###########################################################################
    """

    def startup(self):
        log.info("Setting up instruments")

        self.lockin = DSP7265("GPIB::12")
        self.lockin.dac3 = 0.
        self.lockin.dac4 = 0.

        self.lockin2 = DSP7265("GPIB::11")

        self.source = SM7045D("GPIB::8")
        log.info("Ramping magnet power supply to zero and enabling it.")
        self.source.ramp_to_zero(self.ramp_rate)
        self.source.enable()

        sleep(5)

    """
    ###########################################################################
    ###########################################################################
    #############################  EXECUTE PROCEDURE  #########################
    ###########################################################################
    ###########################################################################
    """

    def step_motor(self, delay=None):
        """
        Step the rotation motor
        """
        if self.lockin.dac3 < 2.5:
            self.lockin.dac3 = 5.
        else:
            self.lockin.dac3 = 0.

        print("Step: dac3: {:.1f}, dac4: {:.1f}, motorstep: {:d}".format(
            self.lockin.dac3, self.lockin.dac4, self.motorstep))

        # Add or subtract one to the number of motor steps
        if self.lockin.dac4 < 2.5:
            self.motorstep += 1
        else:
            self.motorstep -= 1

        # Wait for the motor to stop moving
        if delay is not None:
            sleep(delay)
        else:
            sleep(self.delay)

    def home_motor(self):
        # SETTING DIRECTION OF ROTATION
        # 0 = CLOCKWISE; 5 = COUNTERCLOCKWISE
        if self.motorstep > 0:
            self.lockin.dac4 = 5.
        else:
            self.lockin.dac4 = 0.

        # Rotate the sample back to 0
        while not self.motorstep == 0.:
            self.step_motor(delay=0.350)

    def calc_angle(self):
        return self.degpulse * self.motorstep

    def calc_magfield(self):
        return self.current * self.fieldcal

    def measure(self):
        log.debug("Measuring angle: %g deg." % self.calc_angle())
        data = {
            'Angle (deg)': self.calc_angle(),
            'Magnet Current (A)': self.current,
            'Magnetic Field (mT)': self.calc_magfield(),
            'Lock-In 1 X (V)': self.lockin.x,
            'Lock-In 1 Y (V)': self.lockin.y,
            'Lock-In 2 X (V)': self.lockin2.x,
            'Lock-In 2 Y (V)': self.lockin2.y,
        }
        self.emit('results', data)

    def measurement_procedure(self, Npulses, progress0=0, progress1=100):
        for i in range(Npulses):
            self.measure()
            self.emit('progress', progress0 +
                      (progress1 - progress0) * i / Npulses)
            if self.should_stop():
                log.warning("Catch stop command in procedure")
                return

            self.step_motor()

        self.measure()
        self.emit('progress', progress1)

    def execute(self):
        """
        Prepare this specific measurement
        """

        # Setting Magnetic Field
        self.source.ramp_to_current(self.current, self.ramp_rate)

        # Number of pulses (per degree times degree)
        Npulses = round((1 / self.degpulse) * self.max_angle)

        # Number of motor steps is initially zero.
        self.motorstep = 0

        """
        #############################      CLOCKWISE      ####################
        """
        # SETTING DIRECTION OF ROTATION
        # 0 = CLOCKWISE; 5 = COUNTERCLOCKWISE
        self.lockin.dac4 = 0.
        sleep(self.delay)
        log.info("Starting to rotate the sample clockwise.")
        self.measurement_procedure(Npulses, 0, 50)

        """
        #############################  COUNTERCLOCKWISE   #####################
        """
        # SETTING DIRECTION OF ROTATION
        # 0 = CLOCKWISE; 5 = COUNTERCLOCKWISE
        self.lockin.dac4 = 5.
        sleep(self.delay)
        log.info("Starting to rotate the sample clockwise.")
        self.measurement_procedure(Npulses, 50, 100)

        """
        #############################  COUNTERCLOCKWISE   #####################
        """

    """
    ###########################################################################
    ###########################################################################
    #############################  SHUTDOWN PROCEDURE  ########################
    ###########################################################################
    ###########################################################################
    """

    def shutdown(self):
        log.info("Shutting down.")

        # Ramp magnet current back to zero.
        self.source.ramp_to_zero(self.ramp_rate)
        sleep(1)

        # Disable magnet power supply.
        self.source.disable()

        # Rotate the motor back to 0
        self.home_motor()

        # Setting DACs to zero.
        self.lockin.dac3 = 0.
        self.lockin.dac4 = 0.

        log.info("Finished")
Пример #18
0
class DepProcedure(Procedure):
    in_e = IntegerParameter('Start E', units='mV', minimum=-10000, maximum=10000, default=0)
    lo_e = IntegerParameter('Low E', units='mV', minimum=-10000, maximum=10000, default=-50)
    hi_e = IntegerParameter('High E', units='mV', minimum=-10000, maximum=10000, default=50)
#    sweepdirection = 
    sweep_rate = FloatParameter('Sweep Rate', units='mV/s', minimum=0.01, maximum=500, default=10)
    repeats = IntegerParameter('Cycles', units=None, minimum=1, maximum=1e8, default=10)
    deltat = FloatParameter('Measurement Frequency', units='Hz', default=20)
    voltage_range = FloatParameter('Potential Range', units='V', default=10)
    current_range = FloatParameter('Current Range', units='A', default=0.5)
    directory = Parameter('Working Directory', default='C:/Data/')
    filename = Parameter('Filename', default=unique_filename(str(directory), prefix='CV_'))
    DATA_COLUMNS = ['Time (s)', 'Potential (V)', 'Current (A)']

    def startup(self):
        log.info("Setting up instruments")
        """
        To use the Nanovoltmeter instead of the Sourcemeter to measure
        potential, uncomment the following section and change the corresponding
        section in execute routine to measure from meter instead of source    
        """
#        self.meter = Keithley2182("GPIB::7::INSTR")
#        self.meter.measure_voltage()
#        self.meter.voltage_range = self.voltage_range
#        self.meter.voltage_nplc = 1 # Integration constant to Medium
        
        self.source = Keithley2400("GPIB::24::INSTR")
        self.source.apply_voltage()
        self.source.measure_current()
        self.source.source_current_range = self.current_range
        self.source.compliance_voltage = self.voltage_range
        self.source.enable_source()
        sleep(2)

    def execute(self):
        in_e = self.in_e/1000   # Convert from mV to V
        hi_e = self.hi_e/1000   # Convert from mV to V
        lo_e = self.lo_e/1000   # Convert from mV to V
        
        # To calculate the e_step, convert to V/s and divide by measurement frequency 
        self.source.ramp_to_voltage(hi_e)
        e_step = 0.001*self.sweep_rate/self.deltat
        sweep1 = np.arange(in_e, hi_e, e_step)
        sweep2 = np.arange(hi_e, lo_e, -e_step)
        sweep3 = np.arange(lo_e, hi_e, e_step)
        potentials = np.concatenate((sweep2, sweep3))
        potentials = np.tile(potentials, np.int(self.repeats))
        sweep4 = np.arange(hi_e, in_e, -e_step)
        potentials = np.concatenate((sweep1, potentials))
        potentials = np.concatenate((potentials, sweep4))
        steps = len(potentials)
        log.info("Starting Cyclic Voltammetry")
        for i, e in enumerate(potentials):
            log.debug("Measuring potential: %g V" % e)
            self.source.source_voltage = e
            sleep(1/self.deltat)
            current = self.source.current
            time = i/self.deltat
            data = {
                    'Time (s)': time,
                    'Potential (V)': e,
                    'Current (A)': current
                    }
            self.emit('results', data)
            self.emit('progress', 100.*i/steps)
            if self.should_stop():
                log.warning("Catch stop command in procedure")
                break

    def shutdown(self):
        self.source.shutdown()
        self.source.beep(783.991,0.1)
        sleep(0.125)
        self.source.beep(1046.50,0.1)
        sleep(0.125)
        self.source.beep(1318.51,0.1)
        sleep(0.125)
        self.source.beep(1567.98,0.22)
        sleep(0.25)
        self.source.beep(1318.51,0.1)
        sleep(0.125)
        self.source.beep(1567.98,0.25)
        log.info("Finished")
Пример #19
0
class DepProcedure(Procedure):

    plate_e = FloatParameter('Plating Potential',
                             units='V',
                             minimum=-5,
                             maximum=5,
                             default=-1.5)
    pulse = FloatParameter('Pulse length', units='s', default=0.1)
    delay = FloatParameter('Delay Time', units='s', default=5.9)
    repeats = IntegerParameter('Cycles', units=None, default=50)
    deltat = FloatParameter('Measurement Frequency', units='Hz', default=20)
    current_range = FloatParameter('Current Range', units='A', default=0.1)
    directory = Parameter('Working Directory', default='C:/Data/')
    filename = Parameter('Filename',
                         default=unique_filename(str(directory),
                                                 prefix='Plate_'))
    DATA_COLUMNS = ['Current (A)', 'Potential (V)', 'Time (s)']

    def startup(self):
        #        log.info("Setting up instruments")
        #        self.meter = Keithley2182("GPIB::7::INSTR")
        #        self.meter.measure_voltage()
        #        self.meter.voltage_range = self.voltage_range
        #        self.meter.voltage_nplc = 1 # Integration constant to Medium

        self.source = Keithley2400("GPIB::24::INSTR")
        self.source.apply_voltage()
        self.source.measure_current()
        self.source.voltage_nplc = 1  # Integration constant to Medium
        self.source.complinance_current = self.current_range
        self.source.enable_source()
        sleep(2)

    def execute(self):
        pulses = np.repeat(self.plate_e, (self.pulse) * 1 // (1 / self.deltat))
        rest = np.repeat(0, (self.delay) * 1 // (1 / self.deltat))
        potentials = np.concatenate((pulses, rest))
        potentials = np.tile(potentials, np.int(self.repeats))
        #        currents *= 1e-3 # to mA from A
        steps = len(potentials)
        log.info("Starting Pulsed electrodeposition")
        for i, potential in enumerate(potentials):
            log.debug("Applying potential: %g V" % potential)

            self.source.source_voltage = potential
            # Or use self.source.ramp_to_current(current, delay=0.1)
            sleep(1 / self.deltat)

            current = self.source.current
            time = i / self.deltat
            data = {
                'Current (A)': current,
                'Potential (V)': potential,
                'Time (s)': time
            }
            self.emit('results', data)
            self.emit('progress', 100. * i / steps)
            if self.should_stop():
                log.warning("Catch stop command in procedure")
                break

    def shutdown(self):
        self.source.shutdown()
        self.source.beep(783.991, 0.1)
        sleep(0.125)
        self.source.beep(1046.50, 0.1)
        sleep(0.125)
        self.source.beep(1318.51, 0.1)
        sleep(0.125)
        self.source.beep(1567.98, 0.22)
        sleep(0.25)
        self.source.beep(1318.51, 0.1)
        sleep(0.125)
        self.source.beep(1567.98, 0.25)
        log.info("Finished")
Пример #20
0
class PotentiostaticProcedure(Procedure):

    potential = FloatParameter('Potential', units='V', default=0.1)
    max_current = FloatParameter('Maximum Current', units='mA', default=10)
    time = FloatParameter('Experiment Length', units='s', default=5)
    dt = FloatParameter('Measurement frequency', units='Hz', default=5)
    voltage_range = FloatParameter('Voltage Range', units='V', default=10)
    directory = Parameter('Working Directory', default='C:/Data/')
    filename = Parameter('Filename',
                         default=unique_filename(str(directory),
                                                 prefix='StaticE'))
    DATA_COLUMNS = ['Time (s)', 'Current (A)', 'Potential (V)']

    def startup(self):

        self.source = Keithley2400("GPIB::24::INSTR")
        self.source.apply_voltage(voltage_range=None, compliance_current=0.1)
        self.source.measure_current(nplc=1,
                                    current=self.max_current,
                                    auto_range=True)
        #        self.source.apply_current()
        #        self.source.source_current_range = self.max_current*1e-3 # A
        #        self.source.complinance_voltage = self.voltage_range
        self.source.enable_source()
        sleep(2)

    def execute(self):
        potential = self.potential
        times = np.arange(0, self.time, 1 / self.dt)
        steps = len(times)
        log.info("Applying potential of %f V" % potential)
        self.source.source_voltage = potential
        for i, time in enumerate(times):
            #            self.source.source_current = potential
            sleep(1 / self.dt)
            # sleep between current measurements (Hz -> s)

            current = self.source.current

            data = {
                #                'Time (s)': time,
                'Potential (V)': potential,
                'Current': current
            }
            self.emit('results', data)
            self.emit('progress', 100. * i / steps)
            if self.should_stop():
                log.warning("Catch stop command in procedure")
                break

    def shutdown(self):
        self.source.shutdown()
        self.source.beep(783.991, 0.1)
        sleep(0.125)
        self.source.beep(1046.50, 0.1)
        sleep(0.125)
        self.source.beep(1318.51, 0.1)
        sleep(0.125)
        self.source.beep(1567.98, 0.22)
        sleep(0.25)
        self.source.beep(1318.51, 0.1)
        sleep(0.125)
        self.source.beep(1567.98, 0.25)
        log.info("Finished")