Exemple #1
0
    def __init__(self, master=None):
        super(ULDI03, self).__init__(master)
        # By default, the example detects all available devices and selects the
        # first device listed.
        # If use_device_detection is set to False, the board_num property needs
        # to match the desired board number configured with Instacal.
        use_device_detection = True
        self.board_num = 0

        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)
            dio_info = self.device_info.get_dio_info()
            # Find the first port that supports input, defaulting to None
            # if one is not found.
            self.port = next(
                (port
                 for port in dio_info.port_info if port.supports_input_scan),
                None)

            if self.port is not None:
                self.create_widgets()
            else:
                self.create_unsupported_widgets()

        except ULError:
            self.create_unsupported_widgets(True)
Exemple #2
0
def run_example():
    # By default, the example detects and displays all available devices and
    # selects the first device listed. Use the dev_id_list variable to filter
    # detected devices by device ID (see UL documentation for device IDs).
    # If use_device_detection is set to False, the board_num variable needs to
    # match the desired board number configured with Instacal.
    use_device_detection = True
    dev_id_list = []
    board_num = 0

    try:
        if use_device_detection:
            config_first_detected_device(board_num, dev_id_list)

        daq_dev_info = DaqDeviceInfo(board_num)
        if not daq_dev_info.supports_digital_io:
            raise Exception('Error: The DAQ device does not support '
                            'digital I/O')

        print('\nActive DAQ device: ',
              daq_dev_info.product_name,
              ' (',
              daq_dev_info.unique_id,
              ')\n',
              sep='')

        dio_info = daq_dev_info.get_dio_info()

        # Find the first port that supports input, defaulting to None
        # if one is not found.
        port = next(
            (port for port in dio_info.port_info if port.supports_output),
            None)
        if not port:
            raise Exception('Error: The DAQ device does not support '
                            'digital output')

        # If the port is configurable, configure it for output.
        if port.is_port_configurable:
            ul.d_config_port(board_num, port.type, DigitalIODirection.OUT)

        port_value = 0xFF

        print('Setting', port.type.name, 'to', port_value)

        # Output the value to the port
        ul.d_out(board_num, port.type, port_value)

        bit_num = 0
        bit_value = 0
        print('Setting', port.type.name, 'bit', bit_num, 'to', bit_value)

        # Output the value to the bit
        ul.d_bit_out(board_num, port.type, bit_num, bit_value)

    except Exception as e:
        print('\n', e)
    finally:
        if use_device_detection:
            ul.release_daq_device(board_num)
Exemple #3
0
    def __init__(self, master=None):
        super(TimerOutStart01, self).__init__(master)
        master.protocol("WM_DELETE_WINDOW", self.exit)
        # By default, the example detects all available devices and selects the
        # first device listed.
        # If use_device_detection is set to False, the board_num property needs
        # to match the desired board number configured with Instacal.
        use_device_detection = True
        self.board_num = 0

        self.first_chan_num = -1
        self.last_chan_num = -1

        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)
            counter_info = self.device_info.get_ctr_info()

            # Find the first pulse counter
            first_chan = next((channel for channel in counter_info.chan_info
                               if channel.type == CounterChannelType.CTRTMR),
                              None)
            if first_chan is not None:
                last_chan = next(
                    (channel for channel in reversed(counter_info.chan_info)
                     if channel.type == CounterChannelType.CTRTMR), None)
                self.first_chan_num = first_chan.channel_num
                self.last_chan_num = last_chan.channel_num
                self.create_widgets()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets(True)
Exemple #4
0
    def __init__(self, master=None):
        super(ULAI15, self).__init__(master)
        # By default, the example detects all available devices and selects the
        # first device listed.
        # If use_device_detection is set to False, the board_num property needs
        # to match the desired board number configured with Instacal.
        use_device_detection = True
        self.board_num = 0

        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)
            self.ai_info = self.device_info.get_ai_info()
            example_supported = (self.ai_info.is_supported
                                 and self.ai_info.supports_scan
                                 and ScanOptions.SCALEDATA in
                                 self.ai_info.supported_scan_options)
            if example_supported:
                self.create_widgets()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets(True)
Exemple #5
0
    def __init__(self, master=None):
        super(ULAI10, self).__init__(master)
        # By default, the example detects all available devices and selects the
        # first device listed.
        # If use_device_detection is set to False, the board_num property needs
        # to match the desired board number configured with Instacal.
        use_device_detection = True
        self.board_num = 0

        self.num_elements = 4
        self.queue_loaded = False

        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)
            self.ai_info = self.device_info.get_ai_info()
            if self.ai_info.is_supported:
                self.create_widgets()
                self.scan_loop()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets(True)
Exemple #6
0
    def __init__(self, board_num: int, dev_handle: ul.DaqDeviceDescriptor,
                 sampling: params.Sampling):
        self.dev_info = DaqDeviceInfo(board_num)
        self.sampling = sampling
        self.ao_range = self.dev_info.get_ao_info().supported_ranges[0]
        self.channels = []
        self.num_ao_channels: int = self.dev_info.get_ao_info().num_chans
        self.points_per_channel: int = 1024
        self.buffer_size = self.num_ao_channels * self.points_per_channel

        dev.Device.__init__(self, self.board_num, self.dev_info)

        if MCCDAQ.__registered_board_nums.index(board_num) == -1:
            ul.ignore_instacal()
            ul.create_daq_device(board_num, dev_handle)
            MCCDAQ.__registered_board_nums.append(board_num)
            MCCDAQ.__memhandles.append(ul.win_buf_alloc(self.buffer_size))

        self.memhandle = MCCDAQ.__memhandles.index(self.board_num)
        if not self.memhandle:
            raise Exception('MCCDAQChannel: Failed to allocate memory')

        self.cdata = cast(self.memhandle, POINTER(c_ushort))

        for channel_idx in range(self.num_ao_channels):
            self.channels.append(MCCDAQChannel(self, channel_idx))
Exemple #7
0
    def __init__(self, master=None):
        super(CInScan02, self).__init__(master)
        # By default, the example detects all available devices and selects the
        # first device listed.
        # If use_device_detection is set to False, the board_num property needs
        # to match the desired board number configured with Instacal.
        use_device_detection = True
        self.board_num = 0

        self.chan_num = -1

        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)
            counter_info = self.device_info.get_ctr_info()

            chan = next(
                (channel for channel in counter_info.chan_info
                 if channel.type == CounterChannelType.CTRSCAN), None)
            if chan:
                self.chan_num = chan.channel_num

            if self.chan_num != -1:
                self.create_widgets()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets(True)
Exemple #8
0
    def __init__(self, master=None):
        super(DaqInScan02, self).__init__(master)
        # By default, the example detects all available devices and selects the
        # first device listed.
        # If use_device_detection is set to False, the board_num property needs
        # to match the desired board number configured with Instacal.
        use_device_detection = True
        self.board_num = 0

        self.chan_list = []
        self.chan_type_list = []
        self.gain_list = []
        self.num_chans = 0
        self.resolution = 16

        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)
            if self.device_info.supports_daq_input:
                self.init_scan_channel_info()
                self.create_widgets()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets(True)
Exemple #9
0
def run_example():
    # By default, the example detects and displays all available devices and
    # selects the first device listed. Use the dev_id_list variable to filter
    # detected devices by device ID (see UL documentation for device IDs).
    # If use_device_detection is set to False, the board_num variable needs to
    # match the desired board number configured with Instacal.
    use_device_detection = True
    dev_id_list = []
    board_num = 0

    try:
        if use_device_detection:
            config_first_detected_device(board_num, dev_id_list)

        daq_dev_info = DaqDeviceInfo(board_num)
        if not daq_dev_info.supports_counters:
            raise Exception('Error: The DAQ device does not support counters')

        print('\nActive DAQ device: ',
              daq_dev_info.product_name,
              ' (',
              daq_dev_info.unique_id,
              ')\n',
              sep='')

        ctr_info = daq_dev_info.get_ctr_info()

        # Find a pulse timer channel on the board
        first_chan = next((channel for channel in ctr_info.chan_info
                           if channel.type == CounterChannelType.CTRPULSE),
                          None)

        if not first_chan:
            raise Exception('Error: The DAQ device does not support '
                            'pulse timers')

        timer_num = first_chan.channel_num
        frequency = 100
        duty_cycle = 0.5

        # Start the pulse timer output (optional parameters omitted)
        actual_frequency, actual_duty_cycle, _ = ul.pulse_out_start(
            board_num, timer_num, frequency, duty_cycle)

        # Print information about the output
        print('Outputting', actual_frequency, 'Hz with a duty cycle of',
              actual_duty_cycle, 'to pulse timer channel', timer_num)

        # Wait for 5 seconds
        sleep(5)

        # Stop the pulse timer output
        ul.pulse_out_stop(board_num, timer_num)
        print('Timer output stopped')
    except Exception as e:
        print('\n', e)
    finally:
        if use_device_detection:
            ul.release_daq_device(board_num)
Exemple #10
0
def run_example():
    # By default, the example detects and displays all available devices and
    # selects the first device listed. Use the dev_id_list variable to filter
    # detected devices by device ID (see UL documentation for device IDs).
    # If use_device_detection is set to False, the board_num variable needs to
    # match the desired board number configured with Instacal.
    use_device_detection = True
    dev_id_list = []
    board_num = 0

    try:
        if use_device_detection:
            config_first_detected_device(board_num, dev_id_list)

        daq_dev_info = DaqDeviceInfo(board_num)
        if not daq_dev_info.supports_counters:
            raise Exception('Error: The DAQ device does not support counters')

        print('\nActive DAQ device: ',
              daq_dev_info.product_name,
              ' (',
              daq_dev_info.unique_id,
              ')\n',
              sep='')

        ctr_info = daq_dev_info.get_ctr_info()

        # Use the first counter channel on the board (some boards start channel
        # numbering at 1 instead of 0, the CtrInfo class is used here to find
        # the first one).
        counter_num = ctr_info.chan_info[0].channel_num

        ul.c_clear(board_num, counter_num)
        print('Please enter CTRL + C to terminate the process\n')
        try:
            while True:
                try:
                    # Read and display the data.
                    counter_value = ul.c_in_32(board_num, counter_num)
                    print('\r    Counter ',
                          counter_num,
                          ':',
                          str(counter_value).rjust(12),
                          sep='',
                          end='')
                    stdout.flush()
                    sleep(0.1)
                except (ValueError, NameError, SyntaxError):
                    break
        except KeyboardInterrupt:
            pass

    except Exception as e:
        print('\n', e)
    finally:
        if use_device_detection:
            ul.release_daq_device(board_num)
Exemple #11
0
def run_example():
    # By default, the example detects and displays all available devices and
    # selects the first device listed. Use the dev_id_list variable to filter
    # detected devices by device ID (see UL documentation for device IDs).
    # If use_device_detection is set to False, the board_num variable needs to
    # match the desired board number configured with Instacal.
    use_device_detection = True
    dev_id_list = []
    board_num = 0

    try:
        if use_device_detection:
            config_first_detected_device(board_num, dev_id_list)

        daq_dev_info = DaqDeviceInfo(board_num)
        if not daq_dev_info.supports_analog_input:
            raise Exception('Error: The DAQ device does not support '
                            'analog input')

        print('\nActive DAQ device: ',
              daq_dev_info.product_name,
              ' (',
              daq_dev_info.unique_id,
              ')\n',
              sep='')

        ai_info = daq_dev_info.get_ai_info()
        ai_range = ai_info.supported_ranges[0]
        channel = 0

        # Get a value from the device
        if ai_info.resolution <= 16:
            # Use the a_in method for devices with a resolution <= 16
            value = ul.a_in(board_num, channel, ai_range)
            # Convert the raw value to engineering units
            eng_units_value = ul.to_eng_units(board_num, ai_range, value)
        else:
            # Use the a_in_32 method for devices with a resolution > 16
            # (optional parameter omitted)
            value = ul.a_in_32(board_num, channel, ai_range)
            # Convert the raw value to engineering units
            eng_units_value = ul.to_eng_units_32(board_num, ai_range, value)

        # Display the raw value
        print('Raw Value:', value)
        # Display the engineering value
        print('Engineering Value: {:.3f}'.format(eng_units_value))
    except Exception as e:
        print('\n', e)
    finally:
        if use_device_detection:
            ul.release_daq_device(board_num)
Exemple #12
0
def run_example():
    # By default, the example detects and displays all available devices and
    # selects the first device listed. Use the dev_id_list variable to filter
    # detected devices by device ID (see UL documentation for device IDs).
    # If use_device_detection is set to False, the board_num variable needs to
    # match the desired board number configured with Instacal.
    use_device_detection = True
    dev_id_list = []
    board_num = 0

    try:
        if use_device_detection:
            config_first_detected_device(board_num, dev_id_list)

        daq_dev_info = DaqDeviceInfo(board_num)
        if not daq_dev_info.supports_analog_input:
            raise Exception('Error: The DAQ device does not support '
                            'analog input')

        print('\nActive DAQ device: ',
              daq_dev_info.product_name,
              ' (',
              daq_dev_info.unique_id,
              ')\n',
              sep='')

        ai_info = daq_dev_info.get_ai_info()
        if ai_info.num_temp_chans <= 0:
            raise Exception('Error: The DAQ device does not support '
                            'temperature input')
        channel = 0

        # Get the value from the device (optional parameters omitted)
        value = ul.t_in(board_num, channel, TempScale.CELSIUS)

        # Display the value
        print('Channel', channel, 'Value (deg C):', value)
    except Exception as e:
        print('\n', e)
    finally:
        if use_device_detection:
            ul.release_daq_device(board_num)
Exemple #13
0
def run_example():
    # By default, the example detects and displays all available devices and
    # selects the first device listed. Use the dev_id_list variable to filter
    # detected devices by device ID (see UL documentation for device IDs).
    # If use_device_detection is set to False, the board_num variable needs to
    # match the desired board number configured with Instacal.
    use_device_detection = True
    dev_id_list = []
    board_num = 0

    try:
        if use_device_detection:
            config_first_detected_device(board_num, dev_id_list)

        daq_dev_info = DaqDeviceInfo(board_num)
        if not daq_dev_info.supports_analog_output:
            raise Exception('Error: The DAQ device does not support '
                            'analog output')

        print('\nActive DAQ device: ',
              daq_dev_info.product_name,
              ' (',
              daq_dev_info.unique_id,
              ')\n',
              sep='')

        ao_info = daq_dev_info.get_ao_info()
        ao_range = ao_info.supported_ranges[0]
        channel = 0

        data_value = ao_range.range_max / 2

        print('Outputting', data_value, 'Volts to channel', channel)
        # Send the value to the device (optional parameter omitted)
        ul.v_out(board_num, channel, ao_range, data_value)
    except Exception as e:
        print('\n', e)
    finally:
        if use_device_detection:
            ul.release_daq_device(board_num)
Exemple #14
0
    def __init__(self, master=None):
        super(DaqSetSetpoints01, self).__init__(master)
        # By default, the example detects all available devices and selects the
        # first device listed.
        # If use_device_detection is set to False, the board_num property needs
        # to match the desired board number configured with Instacal.
        use_device_detection = True
        self.board_num = 0

        self.chan_list = []
        self.chan_type_list = []
        self.gain_list = []
        self.num_chans = 4

        self.setpoint_flags_list = []
        self.setpoint_output_list = []
        self.limit_a_list = []
        self.limit_b_list = []
        self.output_1_list = []
        self.output_2_list = []
        self.output_mask_1_list = []
        self.output_mask_2_list = []
        self.setpoint_count = 3

        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)

            daqi_info = self.device_info.get_daqi_info()
            if (self.device_info.supports_daq_input
                    and daqi_info.supports_setpoints):
                self.init_scan_channel_info()
                self.init_setpoints()
                self.create_widgets()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets(True)
Exemple #15
0
    def update_board_info(self):
        info_text = ""

        try:
            # Raises exception is board_num is not valid
            self.device_info = DaqDeviceInfo(self.board_num)

            info_text += self.get_ad_info()
            info_text += self.get_temperature_info()
            info_text += self.get_da_info()
            info_text += self.get_digital_info()
            info_text += self.get_counter_info()
            info_text += self.get_expansion_info()
            # Remove the last "newline" character
            info_text = info_text[:-1]
        except ULError:
            info_text = (
                "No board found at board number " + str(self.board_num) +
                ".\nRun InstaCal to add or remove boards before running this "
                + "program.")
        finally:
            self.info_label["text"] = info_text
Exemple #16
0
    def list_installed(self):
        installed_text = ""
        for board_num in range(0, self.max_board_num):
            try:
                device_info = DaqDeviceInfo(board_num)
                installed_text += ("Board #" + str(board_num) + " = " +
                                   device_info.product_name + "\n")
            except ULError:
                pass

        self.info_groupbox["text"] = "Installed Devices"
        self.info_text.delete(0.0, tk.END)
        self.info_text.insert(0.0, installed_text[:-1])
Exemple #17
0
    def __init__(self, master):
        super(ULTI02, self).__init__(master)
        # By default, the example detects all available devices and selects the
        # first device listed.
        # If use_device_detection is set to False, the board_num property needs
        # to match the desired board number configured with Instacal.
        # BOARD NUMBER IS DEFINED IN TKINTER AT START OF TEST
        use_device_detection = False
        self.running = False
        # Device Detection not used in this test
        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)
            self.ai_info = self.device_info.get_ai_info()
            if self.ai_info.temp_supported:
                self.create_widgets()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets(True)
Exemple #18
0
    def __init__(self, master):
        super(ULAI01, self).__init__(master)
        # By default, the example detects all available devices and selects the
        # first device listed.
        # If use_device_detection is set to False, the board_num property needs
        # to match the desired board number configured with Instacal.
        use_device_detection = True
        self.board_num = 0

        self.running = False

        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)
            if self.device_info.supports_analog_input:
                self.ai_info = self.device_info.get_ai_info()
                self.create_widgets()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets(True)
Exemple #19
0
    def __init__(self, master=None):
        super(ULDO02, self).__init__(master)
        master.protocol("WM_DELETE_WINDOW", self.exit)
        # By default, the example detects all available devices and selects the
        # first device listed.
        # If use_device_detection is set to False, the board_num property needs
        # to match the desired board number configured with Instacal.
        use_device_detection = True
        self.board_num = 0

        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)
            dio_info = self.device_info.get_dio_info()

            # Find the first port that supports output, defaulting to None
            # if one is not found.
            self.port = next((port for port in dio_info.port_info
                              if port.supports_output), None)

            if self.port is not None:
                # If the port is configurable, configure it for output
                if self.port.is_port_configurable:
                    try:
                        ul.d_config_port(self.board_num, self.port.type,
                                         DigitalIODirection.OUT)
                    except ULError as e:
                        show_ul_error(e)

                self.create_widgets()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets(True)
Exemple #20
0
class ULTI02(UIExample):
    def __init__(self, master):
        super(ULTI02, self).__init__(master)
        # By default, the example detects all available devices and selects the
        # first device listed.
        # If use_device_detection is set to False, the board_num property needs
        # to match the desired board number configured with Instacal.
        # BOARD NUMBER IS DEFINED IN TKINTER AT START OF TEST
        use_device_detection = False
        self.running = False
        # Device Detection not used in this test
        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)
            self.ai_info = self.device_info.get_ai_info()
            if self.ai_info.temp_supported:
                self.create_widgets()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets(True)

    # Main update loop that gets repeated every 100ms while the test is running
    def update_values(self):
        try:
            # Get the values from the device (optional parameters omitted)
            # Temp scale set to NOSCALE and conversion will be done via lookup table within this program
            err_code, data_array = ul.t_in_scan(self.board_num, 0, 7,
                                                TempScale.NOSCALE)

            # create array of temperature and resistances to be logged, data_array is raw resistance
            data_example = ""
            data_example_temps = ""
            data_temp_display = numpy.array(data_array)
            data_array = numpy.around(data_array, 3)
            temp_array = interp_resist_to_temp_np1000(data_array)
            for x in range(0, 8):
                data_example += str(data_array[x]) + ';'
                data_example_temps += str(
                    numpy.around(interp_resist_to_temp_np1000(data_array[x]),
                                 2)) + ';'

            # Check err_code for OUTOFRANGE or OPENCONNECTION. All other
            # error codes will raise a ULError and are checked by the except
            # clause.
            # if err_code == ErrorCode.OUTOFRANGE:
            #     self.warning_label["text"] = (
            #         "A thermocouple input is out of range.")
            # elif err_code == ErrorCode.OPENCONNECTION:
            #     self.warning_label["text"] = (
            #         "A thermocouple input has an open connection.")
            # else:
            #     self.warning_label["text"] = ""

            self.display_values(temp_array)

            # creates variables for time format in log
            current_date_and_time = datetime.datetime.now()
            current_date_and_time_string = current_date_and_time.strftime(
                "%Y-%m-%d %H:%M:%S")

            current_time = time.time()

            # start_logging Boolean is used to only log at 00 or 30 seconds of the minute
            # this is to have synched timings between two programs running independantly on the same machine
            sub_time = current_time - self.start_time
            seconds = datetime.datetime.now().strftime("%S")
            if seconds == '30' or seconds == '00':
                start_logging = True
            else:
                start_logging = False
            # Log at 00 or 30 seconds every minute (twice a minute)
            if sub_time >= 10 and start_logging:
                self.start_time = time.time()
                self.last_logged_time = datetime.datetime.now().strftime(
                    "%Y-%m-%d %H:%M:%S")
                # create log of temperature for the specified time
                try:
                    with open(self.filefullname, "a") as myfile:
                        myfile.write(current_date_and_time_string + ';')
                        myfile.write(data_example_temps + data_example + '\n')
                    myfile.close()
                except:
                    pass
            # Call this method again until the stop button is pressed (or an
            # error occurs)

            # This is the display in the command prompt
            message_timing = current_time - self.start_time_timing
            if message_timing <= 1 and self.verify == 1:
                os.system('cls')
                print('Test Running')
                print('Test Name =', self.test_name)
                print('Last logged data:', self.last_logged_time)
                for x in range(0, 8):
                    print(
                        round(
                            interp_resist_to_temp_np1000(data_temp_display[x]),
                            2), '°C', "\t", self.channel_list[x])
                self.verify = 2
            elif message_timing >= 1 and message_timing <= 2 and self.verify == 2:
                os.system('cls')
                print('Test Running.')
                print('Test Name =', self.test_name)
                print('Last logged data:', self.last_logged_time)
                for x in range(0, 8):
                    print(
                        round(
                            interp_resist_to_temp_np1000(data_temp_display[x]),
                            2), '°C', "\t", self.channel_list[x])
                self.verify = 3
            elif message_timing >= 2 and message_timing <= 3 and self.verify == 3:
                os.system('cls')
                print('Test Running..')
                print('Test Name =', self.test_name)
                print('Last logged data:', self.last_logged_time)
                for x in range(0, 8):
                    print(
                        round(
                            interp_resist_to_temp_np1000(data_temp_display[x]),
                            2), '°C', "\t", self.channel_list[x])
                self.verify = 4
            elif message_timing >= 3 and message_timing <= 4 and self.verify == 4:
                os.system('cls')
                print('Test Running...')
                print('Test Name =', self.test_name)
                print('Last logged data:', self.last_logged_time)
                for x in range(0, 8):
                    print(
                        round(
                            interp_resist_to_temp_np1000(data_temp_display[x]),
                            2), '°C', "\t", self.channel_list[x])
                self.verify = 5
            elif message_timing > 4 and self.verify == 5:
                self.start_time_timing = time.time()
                self.verify = 1
            else:
                pass

            # self-updating graph for easy visualisation

            # keep running after 100 ms if self.running is True
            if self.running:
                self.after(100, self.update_values)
        except ULError as e:
            self.stop()
            show_ul_error(e)

    def display_values(self, array):
        low_chan = 0
        high_chan = 7

        for chan_num in range(low_chan, high_chan + 1):
            index = chan_num - low_chan
            self.data_labels[index]["text"] = '{:.3f}'.format(
                array[index]) + "\n"

    def stop(self):
        self.running = False
        self.start_button["command"] = self.start
        self.start_button["text"] = "Start"
        # self.low_channel_entry["state"] = tk.NORMAL
        # self.high_channel_entry["state"] = tk.NORMAL

    def start(self):
        os.system('cls')
        self.running = True
        self.start_button["command"] = self.stop
        self.start_button["text"] = "Stop"
        # self.low_channel_entry["state"] = tk.DISABLED
        # self.high_channel_entry["state"] = tk.DISABLED
        self.test_name_entry["state"] = tk.DISABLED
        self.board_number_entry["state"] = tk.DISABLED
        # self.low_chan = self.get_low_channel_num()
        # self.high_chan = self.get_high_channel_num()
        self.test_name = self.get_test_name()
        self.channel0 = self.get_channel0()
        self.channel1 = self.get_channel1()
        self.channel2 = self.get_channel2()
        self.channel3 = self.get_channel3()
        self.channel4 = self.get_channel4()
        self.channel5 = self.get_channel5()
        self.channel6 = self.get_channel6()
        self.channel7 = self.get_channel7()
        self.channel_list = [
            self.channel0, self.channel1, self.channel2, self.channel3,
            self.channel4, self.channel5, self.channel6, self.channel7
        ]
        self.board_num = self.get_board_num()
        self.recreate_data_frame()
        self.start_time = time.time()
        self.start_time_timing = time.time()
        self.last_logged_time = 'Nothing logged yet'
        self.verify = 1
        self.inc = 0
        self.create_log_file()
        self.update_values()

    def create_log_file(self):
        # creates log_file when starting program
        if not os.path.exists('logs'):
            os.makedirs('logs')
        current_date_and_time = datetime.datetime.now()
        current_date_and_time_filename = current_date_and_time.strftime(
            "%Y_%m_%d-%H%M%S") + '_'
        dir = 'logs\\'
        filename = current_date_and_time_filename
        filemission = self.test_name
        file_ext = '.txt'
        self.filefullname = dir + filename + filemission + file_ext
        file = open(self.filefullname, 'a')

    # def get_low_channel_num(self):
    #     try:
    #         return int(self.low_channel_entry.get())
    #     except ValueError:
    #         return 0

    # def get_high_channel_num(self):
    #     try:
    #         return int(self.high_channel_entry.get())
    #     except ValueError:
    #         return 0

    def get_test_name(self):
        try:
            return self.test_name_entry.get("1.0", 'end-1c')
        except ValueError:
            return 0

    def get_channel0(self):
        try:
            return self.channel0_name_entry.get("1.0", 'end-1c')
        except ValueError:
            return 0

    def get_channel1(self):
        try:
            return self.channel1_name_entry.get("1.0", 'end-1c')
        except ValueError:
            return 0

    def get_channel2(self):
        try:
            return self.channel2_name_entry.get("1.0", 'end-1c')
        except ValueError:
            return 0

    def get_channel3(self):
        try:
            return self.channel3_name_entry.get("1.0", 'end-1c')
        except ValueError:
            return 0

    def get_channel4(self):
        try:
            return self.channel4_name_entry.get("1.0", 'end-1c')
        except ValueError:
            return 0

    def get_channel5(self):
        try:
            return self.channel5_name_entry.get("1.0", 'end-1c')
        except ValueError:
            return 0

    def get_channel6(self):
        try:
            return self.channel6_name_entry.get("1.0", 'end-1c')
        except ValueError:
            return 0

    def get_channel7(self):
        try:
            return self.channel7_name_entry.get("1.0", 'end-1c')
        except ValueError:
            return 0

    def get_board_num(self):
        try:
            return int(self.board_number_entry.get())
        except ValueError:
            return 0

    def validate_channel_entry(self, p):
        if p == '':
            return True
        try:
            value = int(p)
            if value < 0 or value > self.ai_info.num_temp_chans - 1:
                return False
        except ValueError:
            return False

        return True

    def recreate_data_frame(self):
        low_chan = 0
        high_chan = 7
        channels_per_row = 4

        new_data_frame = tk.Frame(self.results_group)

        self.data_labels = []
        row = 0
        column = 0
        # Add the labels for each channel
        for chan_num in range(low_chan, high_chan + 1):
            chan_label = tk.Label(new_data_frame, justify=tk.LEFT, padx=3)
            chan_label["text"] = "Channel " + str(chan_num)
            chan_label.grid(row=row, column=column)

            data_label = tk.Label(new_data_frame, justify=tk.LEFT, padx=3)
            data_label.grid(row=row + 1, column=column)
            self.data_labels.append(data_label)

            column += 1
            if column >= channels_per_row:
                row += 2
                column = 0

        self.data_frame.destroy()
        self.data_frame = new_data_frame
        self.data_frame.pack(side=tk.TOP)

    def create_widgets(self):
        '''Create the tkinter UI'''
        self.device_label = tk.Label(self)
        self.device_label.pack(fill=tk.NONE, anchor=tk.NW)
        self.device_label["text"] = ('Board Number ' + str(self.board_num) +
                                     ": " + self.device_info.product_name +
                                     " (" + self.device_info.unique_id + ")")

        main_frame = tk.Frame(self)
        main_frame.pack(fill=tk.X, anchor=tk.NW)
        channel_vcmd = self.register(self.validate_channel_entry)

        curr_row = 0

        if self.ai_info.num_temp_chans > 1:

            # # Defining low channel entry

            # low_channel_entry_label = tk.Label(main_frame)
            # low_channel_entry_label["text"] = "Low Channel Number:"
            # low_channel_entry_label.grid(
            #     row=curr_row, column=0, sticky=tk.W)

            # self.low_channel_entry = tk.Spinbox(
            #     main_frame, from_=0,
            #     to=max(self.ai_info.num_temp_chans - 1, 0),
            #     validate='key', validatecommand=(channel_vcmd, '%P'))
            # self.low_channel_entry.grid(
            #     row=curr_row, column=1, sticky=tk.W)

            # # Defining high channel entry

            # curr_row += 1
            # high_channel_entry_label = tk.Label(main_frame)
            # high_channel_entry_label["text"] = "High Channel Number:"
            # high_channel_entry_label.grid(
            #     row=curr_row, column=0, sticky=tk.W)

            # self.high_channel_entry = tk.Spinbox(
            #     main_frame, from_=0,
            #     to=max(self.ai_info.num_temp_chans - 1, 0),
            #     validate='key', validatecommand=(channel_vcmd, '%P'))
            # self.high_channel_entry.grid(
            #     row=curr_row, column=1, sticky=tk.W)

            # Defining test name entry

            curr_row += 1
            test_name_entry_label = tk.Label(main_frame)
            test_name_entry_label["text"] = "Test Name"
            test_name_entry_label.grid(row=curr_row, column=0, sticky=tk.W)

            self.test_name_entry = tk.Text(main_frame, height=1, width=30)
            self.test_name_entry.grid(row=curr_row, column=1, sticky=tk.W)

            self.test_name_entry.insert(tk.END, 'Test Name')

            # Defining channel #0 name

            curr_row += 1
            channel0_name_entry_label = tk.Label(main_frame)
            channel0_name_entry_label["text"] = "Channel 0"
            channel0_name_entry_label.grid(row=curr_row, column=0, sticky=tk.W)

            self.channel0_name_entry = tk.Text(main_frame, height=1, width=30)
            self.channel0_name_entry.grid(row=curr_row, column=1, sticky=tk.W)
            self.channel0_name_entry.insert(tk.END, 'Channel 0')

            # Defining channel #1 name

            curr_row += 1
            channel1_name_entry_label = tk.Label(main_frame)
            channel1_name_entry_label["text"] = "Channel 1"
            channel1_name_entry_label.grid(row=curr_row, column=0, sticky=tk.W)

            self.channel1_name_entry = tk.Text(main_frame, height=1, width=30)
            self.channel1_name_entry.grid(row=curr_row, column=1, sticky=tk.W)
            self.channel1_name_entry.insert(tk.END, 'Channel 1')

            # Defining channel #2 name

            curr_row += 1
            channel2_name_entry_label = tk.Label(main_frame)
            channel2_name_entry_label["text"] = "Channel 2"
            channel2_name_entry_label.grid(row=curr_row, column=0, sticky=tk.W)

            self.channel2_name_entry = tk.Text(main_frame, height=1, width=30)
            self.channel2_name_entry.grid(row=curr_row, column=1, sticky=tk.W)
            self.channel2_name_entry.insert(tk.END, 'Channel 2')

            # Defining channel #3 name

            curr_row += 1
            channel3_name_entry_label = tk.Label(main_frame)
            channel3_name_entry_label["text"] = "Channel 3"
            channel3_name_entry_label.grid(row=curr_row, column=0, sticky=tk.W)

            self.channel3_name_entry = tk.Text(main_frame, height=1, width=30)
            self.channel3_name_entry.grid(row=curr_row, column=1, sticky=tk.W)
            self.channel3_name_entry.insert(tk.END, 'Channel 3')

            # Defining channel #4 name

            curr_row += 1
            channel4_name_entry_label = tk.Label(main_frame)
            channel4_name_entry_label["text"] = "Channel 4"
            channel4_name_entry_label.grid(row=curr_row, column=0, sticky=tk.W)

            self.channel4_name_entry = tk.Text(main_frame, height=1, width=30)
            self.channel4_name_entry.grid(row=curr_row, column=1, sticky=tk.W)
            self.channel4_name_entry.insert(tk.END, 'Channel 4')

            # Defining channel #5 name

            curr_row += 1
            channel5_name_entry_label = tk.Label(main_frame)
            channel5_name_entry_label["text"] = "Channel 5"
            channel5_name_entry_label.grid(row=curr_row, column=0, sticky=tk.W)

            self.channel5_name_entry = tk.Text(main_frame, height=1, width=30)
            self.channel5_name_entry.grid(row=curr_row, column=1, sticky=tk.W)
            self.channel5_name_entry.insert(tk.END, 'Channel 5')

            # Defining channel #6 name

            curr_row += 1
            channel6_name_entry_label = tk.Label(main_frame)
            channel6_name_entry_label["text"] = "Channel 6"
            channel6_name_entry_label.grid(row=curr_row, column=0, sticky=tk.W)

            self.channel6_name_entry = tk.Text(main_frame, height=1, width=30)
            self.channel6_name_entry.grid(row=curr_row, column=1, sticky=tk.W)
            self.channel6_name_entry.insert(tk.END, 'Channel 6')

            # Defining channel #7 name

            curr_row += 1
            channel7_name_entry_label = tk.Label(main_frame)
            channel7_name_entry_label["text"] = "Channel 7"
            channel7_name_entry_label.grid(row=curr_row, column=0, sticky=tk.W)

            self.channel7_name_entry = tk.Text(main_frame, height=1, width=30)
            self.channel7_name_entry.grid(row=curr_row, column=1, sticky=tk.W)
            self.channel7_name_entry.insert(tk.END, 'Channel 7')

            # Defining board number entry

            curr_row += 1
            board_number_entry_label = tk.Label(main_frame)
            board_number_entry_label["text"] = "Board number:"
            board_number_entry_label.grid(row=curr_row, column=0, sticky=tk.W)

            self.board_number_entry = tk.Spinbox(main_frame,
                                                 from_=0,
                                                 to=4,
                                                 validate='key',
                                                 validatecommand=(channel_vcmd,
                                                                  '%P'))
            self.board_number_entry.grid(row=curr_row, column=1, sticky=tk.W)

            # Default Values

            # initial_value = min(self.ai_info.num_temp_chans - 1, 7)
            # self.high_channel_entry.delete(0, tk.END)
            # self.high_channel_entry.insert(0, str(initial_value))

        self.results_group = tk.LabelFrame(self, text="Results")
        self.results_group.pack(fill=tk.X, anchor=tk.NW, padx=3, pady=3)

        self.data_frame = tk.Frame(self.results_group)
        self.data_frame.pack(side=tk.TOP)

        self.warning_label = tk.Label(self.results_group, fg="red")
        self.warning_label.pack(side=tk.BOTTOM)

        button_frame = tk.Frame(self)
        button_frame.pack(fill=tk.X, side=tk.RIGHT, anchor=tk.SE)

        button_frame = tk.Frame(self)
        button_frame.pack(fill=tk.X, side=tk.RIGHT, anchor=tk.SE)

        self.start_button = tk.Button(button_frame)
        self.start_button["text"] = "Start"
        self.start_button["command"] = self.start
        self.start_button.grid(row=0, column=0, padx=3, pady=3)

        quit_button = tk.Button(button_frame)
        quit_button["text"] = "Quit"
        quit_button["command"] = self.master.destroy
        quit_button.grid(row=0, column=1, padx=3, pady=3)
Exemple #21
0
class ULAI12(UIExample):
    def __init__(self, master=None):
        super(ULAI12, self).__init__(master)
        # By default, the example detects all available devices and selects the
        # first device listed.
        # If use_device_detection is set to False, the board_num property needs
        # to match the desired board number configured with Instacal.
        use_device_detection = True
        self.board_num = 0

        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)
            self.ai_info = self.device_info.get_ai_info()
            if self.ai_info.is_supported and self.ai_info.supports_gain_queue:
                self.create_widgets()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets(True)

    def start_scan(self):
        low_chan = self.get_low_channel_num()
        high_chan = self.get_high_channel_num()

        if low_chan > high_chan:
            messagebox.showerror(
                "Error",
                "Low Channel Number must be greater than or equal to High "
                "Channel Number")
            self.start_button["state"] = tk.NORMAL
            return

        rate = 0  # Ignored for EXTCLOCK scans
        points_per_channel = 10
        num_channels = high_chan - low_chan + 1
        total_count = points_per_channel * num_channels

        range_ = self.ai_info.supported_ranges[0]

        # Allocate a buffer for the scan
        if self.ai_info.resolution <= 16:
            # Use the win_buf_alloc method for devices with a resolution <=
            # 16
            memhandle = ul.win_buf_alloc(total_count)
        else:
            # Use the win_buf_alloc_32 method for devices with a resolution
            # > 16
            memhandle = ul.win_buf_alloc_32(total_count)

        # Check if the buffer was successfully allocated
        if not memhandle:
            messagebox.showerror("Error", "Failed to allocate memory")
            self.start_button["state"] = tk.NORMAL
            return

        try:
            # Run the scan
            ul.a_in_scan(self.board_num, low_chan, high_chan, total_count,
                         rate, range_, memhandle, ScanOptions.EXTCLOCK)

            # Convert the memhandle to a ctypes array
            # Note: the ctypes array will only be valid until win_buf_free
            # is called.
            # A copy of the buffer can be created using win_buf_to_array
            # or win_buf_to_array_32 before the memory is freed. The copy
            # can be used at any time.
            if self.ai_info.resolution <= 16:
                # Use the memhandle_as_ctypes_array method for devices with
                # a resolution <= 16
                array = cast(memhandle, POINTER(c_ushort))
            else:
                # Use the memhandle_as_ctypes_array_32 method for devices
                # with a resolution > 16
                array = cast(memhandle, POINTER(c_ulong))

            # Display the values
            self.display_values(array, range_, total_count, low_chan,
                                high_chan)
        except ULError as e:
            show_ul_error(e)
        finally:
            # Free the allocated memory
            ul.win_buf_free(memhandle)
            self.start_button["state"] = tk.NORMAL

    def display_values(self, array, range_, total_count, low_chan, high_chan):
        new_data_frame = tk.Frame(self.results_group)

        channel_text = []

        # Add the headers
        for chan_num in range(low_chan, high_chan + 1):
            channel_text.append("Channel " + str(chan_num) + "\n")

        chan_count = high_chan - low_chan + 1

        # Add (up to) the first 10 values for each channel to the text
        chan_num = low_chan
        for data_index in range(0, min(chan_count * 10, total_count)):
            if self.ai_info.resolution <= 16:
                eng_value = ul.to_eng_units(self.board_num, range_,
                                            array[data_index])
            else:
                eng_value = ul.to_eng_units_32(self.board_num, range_,
                                               array[data_index])
            channel_text[chan_num -
                         low_chan] += '{:.3f}'.format(eng_value) + "\n"
            if chan_num == high_chan:
                chan_num = low_chan
            else:
                chan_num += 1

        # Add the labels for each channel
        for chan_num in range(low_chan, high_chan + 1):
            chan_label = tk.Label(new_data_frame, justify=tk.LEFT, padx=3)
            chan_label["text"] = channel_text[chan_num - low_chan]
            chan_label.grid(row=0, column=chan_num - low_chan)

        self.data_frame.destroy()
        self.data_frame = new_data_frame
        self.data_frame.grid()

    def start(self):
        self.start_button["state"] = tk.DISABLED
        self.start_scan()

    def get_low_channel_num(self):
        try:
            return int(self.low_channel_entry.get())
        except ValueError:
            return 0

    def get_high_channel_num(self):
        try:
            return int(self.high_channel_entry.get())
        except ValueError:
            return 0

    def validate_channel_entry(self, p):
        if p == '':
            return True
        try:
            value = int(p)
            if value < 0 or value > self.ai_info.num_chans - 1:
                return False
        except ValueError:
            return False

        return True

    def create_widgets(self):
        '''Create the tkinter UI'''
        self.device_label = tk.Label(self)
        self.device_label.pack(fill=tk.NONE, anchor=tk.NW)
        self.device_label["text"] = ('Board Number ' + str(self.board_num) +
                                     ": " + self.device_info.product_name +
                                     " (" + self.device_info.unique_id + ")")

        main_frame = tk.Frame(self)
        main_frame.pack(fill=tk.X, anchor=tk.NW)

        curr_row = 0
        if self.ai_info.num_chans > 1:
            channel_vcmd = self.register(self.validate_channel_entry)

            low_channel_entry_label = tk.Label(main_frame)
            low_channel_entry_label["text"] = "Low Channel Number:"
            low_channel_entry_label.grid(row=curr_row, column=0, sticky=tk.W)

            self.low_channel_entry = tk.Spinbox(
                main_frame,
                from_=0,
                to=max(self.ai_info.num_chans - 1, 0),
                validate='key',
                validatecommand=(channel_vcmd, '%P'))
            self.low_channel_entry.grid(row=curr_row, column=1, sticky=tk.W)

            curr_row += 1
            high_channel_entry_label = tk.Label(main_frame)
            high_channel_entry_label["text"] = "High Channel Number:"
            high_channel_entry_label.grid(row=curr_row, column=0, sticky=tk.W)

            self.high_channel_entry = tk.Spinbox(
                main_frame,
                from_=0,
                validate='key',
                to=max(self.ai_info.num_chans - 1, 0),
                validatecommand=(channel_vcmd, '%P'))
            self.high_channel_entry.grid(row=curr_row, column=1, sticky=tk.W)
            initial_value = min(self.ai_info.num_chans - 1, 3)
            self.high_channel_entry.delete(0, tk.END)
            self.high_channel_entry.insert(0, str(initial_value))

            curr_row += 1

        self.results_group = tk.LabelFrame(self,
                                           text="Results",
                                           padx=3,
                                           pady=3)
        self.results_group.pack(fill=tk.X, anchor=tk.NW, padx=3, pady=3)

        self.data_frame = tk.Frame(self.results_group)
        self.data_frame.grid()

        curr_row += 1
        warning_label = tk.Label(main_frame,
                                 justify=tk.LEFT,
                                 wraplength=400,
                                 fg="red")
        warning_label["text"] = (
            "Warning: Clicking Start will freeze the UI until the scan "
            "is complete. Ensure that a clock signal is connected to "
            "the external clock pin on your device. Real-world "
            "applications should run the a_in_scan method on a "
            "separate thread or use the BACKGROUND option.")
        warning_label.grid(row=curr_row, columnspan=2, sticky=tk.W)

        button_frame = tk.Frame(self)
        button_frame.pack(fill=tk.X, side=tk.RIGHT, anchor=tk.SE)

        self.start_button = tk.Button(button_frame)
        self.start_button["text"] = "Start"
        self.start_button["command"] = self.start
        self.start_button.grid(row=0, column=0, padx=3, pady=3)

        quit_button = tk.Button(button_frame)
        quit_button["text"] = "Quit"
        quit_button["command"] = self.master.destroy
        quit_button.grid(row=0, column=1, padx=3, pady=3)
Exemple #22
0
class ULAO02(UIExample):
    def __init__(self, master=None):
        super(ULAO02, self).__init__(master)
        # By default, the example detects all available devices and selects the
        # first device listed.
        # If use_device_detection is set to False, the board_num property needs
        # to match the desired board number configured with Instacal.
        use_device_detection = True
        self.board_num = 0

        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)
            self.ao_info = self.device_info.get_ao_info()
            if self.ao_info.is_supported and self.ao_info.supports_scan:
                self.create_widgets()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets(True)

    def send_data(self):
        # Build the data array
        num_chans = min(self.ao_info.num_chans, 4)
        num_points = num_chans
        ao_range = self.ao_info.supported_ranges[0]

        memhandle = ul.win_buf_alloc(num_points)

        # Check if the buffer was successfully allocated
        if not memhandle:
            messagebox.showerror("Error", "Failed to allocate memory")
            self.send_data["state"] = tk.NORMAL
            return

        try:
            data_array = cast(memhandle, POINTER(c_ushort))

            full_scale_count = (2**self.ao_info.resolution) - 1
            value_step = full_scale_count / (num_chans + 1)
            for point_num in range(0, num_points):
                raw_value = int(value_step * (point_num + 1))
                data_array[point_num] = raw_value

                self.raw_data_labels[point_num]["text"] = str(raw_value)
                # ul.to_eng_units cannot be used here, as it uses the analog
                # input resolution. Instead, do the conversion on our own.
                volts = self.ao_to_eng_units(raw_value, ao_range,
                                             self.ao_info.resolution)
                self.volts_labels[point_num]["text"] = ('{:.3f}'.format(volts))

            ul.a_out_scan(self.board_num, 0, num_chans - 1, num_points, 100,
                          ao_range, memhandle, 0)
        except ULError as e:
            show_ul_error(e)
        finally:
            ul.win_buf_free(memhandle)

    def ao_to_eng_units(self, raw_value, ao_range, resolution):
        full_scale_volts = ao_range.range_max - ao_range.range_min
        full_scale_count = (2**resolution) - 1
        return ((full_scale_volts / full_scale_count) * raw_value +
                ao_range.range_min)

    def create_widgets(self):
        '''Create the tkinter UI'''
        self.device_label = tk.Label(self)
        self.device_label.pack(fill=tk.NONE, anchor=tk.NW)
        self.device_label["text"] = ('Board Number ' + str(self.board_num) +
                                     ": " + self.device_info.product_name +
                                     " (" + self.device_info.unique_id + ")")

        main_frame = tk.Frame(self)
        main_frame.pack(fill=tk.X, anchor=tk.NW)

        data_frame = tk.Frame(main_frame)
        data_frame.pack(fill=tk.X, anchor=tk.NW)

        raw_data_label = tk.Label(data_frame)
        raw_data_label["text"] = "Raw Data"
        raw_data_label.grid(row=1, sticky=tk.W)

        volts_label = tk.Label(data_frame)
        volts_label["text"] = "Volts"
        volts_label.grid(row=2, sticky=tk.W)

        self.raw_data_labels = []
        self.volts_labels = []

        for chan_num in range(0, min(self.ao_info.num_chans, 4)):
            name_label = tk.Label(data_frame)
            name_label["text"] = "Channel " + str(chan_num)
            name_label.grid(row=0, column=chan_num + 1, sticky=tk.W)

            raw_data_label = tk.Label(data_frame)
            raw_data_label.grid(row=1, column=chan_num + 1, sticky=tk.W)
            self.raw_data_labels.append(raw_data_label)

            volts_label = tk.Label(data_frame)
            volts_label.grid(row=2, column=chan_num + 1, sticky=tk.W)
            self.volts_labels.append(volts_label)

        button_frame = tk.Frame(self)
        button_frame.pack(fill=tk.X, side=tk.RIGHT, anchor=tk.SE)

        send_data_button = tk.Button(button_frame)
        send_data_button["text"] = "Start"
        send_data_button["command"] = self.send_data
        send_data_button.grid(row=0, column=0, padx=3, pady=3)

        quit_button = tk.Button(button_frame)
        quit_button["text"] = "Quit"
        quit_button["command"] = self.master.destroy
        quit_button.grid(row=0, column=1, padx=3, pady=3)
Exemple #23
0
class ULAIO01(UIExample):
    def __init__(self, master=None):
        super(ULAIO01, self).__init__(master)
        # By default, the example detects all available devices and selects the
        # first device listed.
        # If use_device_detection is set to False, the board_num property needs
        # to match the desired board number configured with Instacal.
        use_device_detection = True
        self.board_num = 0

        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)
            self.ai_info = self.device_info.get_ai_info()
            self.ao_info = self.device_info.get_ao_info()
            example_supported = (self.ai_info.is_supported
                                 and self.ai_info.supports_scan
                                 and self.ao_info.is_supported
                                 and self.ao_info.supports_scan)
            if example_supported:
                self.create_widgets()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets(True)

    def start_input_scan(self):
        self.input_low_chan = self.get_input_low_channel_num()
        self.input_high_chan = self.get_input_high_channel_num()
        self.num_input_chans = self.input_high_chan - self.input_low_chan + 1

        if self.input_low_chan > self.input_high_chan:
            messagebox.showerror(
                "Error",
                "Low Channel Number must be greater than or equal to High "
                "Channel Number")
            self.set_input_ui_idle_state()
            return

        rate = 100
        points_per_channel = 1000
        total_count = points_per_channel * self.num_input_chans
        range_ = self.ai_info.supported_ranges[0]
        scan_options = ScanOptions.BACKGROUND | ScanOptions.CONTINUOUS

        # Allocate a buffer for the scan
        if self.ai_info.resolution <= 16:
            # Use the win_buf_alloc method for devices with a resolution <=
            # 16
            self.input_memhandle = ul.win_buf_alloc(total_count)
        else:
            # Use the win_buf_alloc_32 method for devices with a resolution
            # > 16
            self.input_memhandle = ul.win_buf_alloc_32(total_count)

        if not self.input_memhandle:
            messagebox.showerror("Error", "Failed to allocate memory")
            self.set_input_ui_idle_state()
            return

        # Create the frames that will hold the data
        self.recreate_input_data_frame()

        try:
            # Run the scan
            ul.a_in_scan(self.board_num, self.input_low_chan,
                         self.input_high_chan, total_count, rate, range_,
                         self.input_memhandle, scan_options)
        except ULError as e:
            show_ul_error(e)
            self.set_input_ui_idle_state()
            return

        # Convert the input_memhandle to a ctypes array
        # Note: the ctypes array will no longer be valid after win_buf_free is
        # called. A copy of the buffer can be created using win_buf_to_array
        # or win_buf_to_array_32 before the memory is freed. The copy can
        # be used at any time.
        if self.ai_info.resolution <= 16:
            # Use the memhandle_as_ctypes_array method for devices with a
            # resolution <= 16
            self.ctypes_array = cast(self.input_memhandle, POINTER(c_ushort))
        else:
            # Use the memhandle_as_ctypes_array_32 method for devices with a
            # resolution > 16
            self.ctypes_array = cast(self.input_memhandle, POINTER(c_ulong))

        # Start updating the displayed values
        self.update_input_displayed_values(range_)

    def update_input_displayed_values(self, range_):
        # Get the status from the device
        status, curr_count, curr_index = ul.get_status(self.board_num,
                                                       FunctionType.AIFUNCTION)

        # Display the status info
        self.update_input_status_labels(status, curr_count, curr_index)

        # Display the values
        self.display_input_values(range_, curr_index, curr_count)

        # Call this method again until the stop_input button is pressed
        if status == Status.RUNNING:
            self.after(100, self.update_input_displayed_values, range_)
        else:
            # Free the allocated memory
            ul.win_buf_free(self.input_memhandle)
            self.set_input_ui_idle_state()

    def update_input_status_labels(self, status, curr_count, curr_index):
        if status == Status.IDLE:
            self.input_status_label["text"] = "Idle"
        else:
            self.input_status_label["text"] = "Running"

        self.input_index_label["text"] = str(curr_index)
        self.input_count_label["text"] = str(curr_count)

    def display_input_values(self, range_, curr_index, curr_count):
        per_channel_display_count = 10
        array = self.ctypes_array
        low_chan = self.input_low_chan
        high_chan = self.input_high_chan
        channel_text = []

        # Add the headers
        for chan_num in range(low_chan, high_chan + 1):
            channel_text.append("Channel " + str(chan_num) + "\n")

        # If no data has been gathered, don't add data to the labels
        if curr_count > 1:
            chan_count = high_chan - low_chan + 1

            chan_num = low_chan
            # curr_index points to the start_input of the last completed
            # channel scan that was transferred between the board and the data
            # buffer. Based on this, calculate the first index we want to
            # display using subtraction.
            first_index = max(curr_index - ((per_channel_display_count - 1)
                                            * chan_count), 0)
            # Add (up to) the latest 10 values for each channel to the text
            for data_index in range(
                    first_index,
                    first_index + min(
                        chan_count * per_channel_display_count,
                        curr_count)):

                raw_value = array[data_index]
                if self.ai_info.resolution <= 16:
                    eng_value = ul.to_eng_units(self.board_num, range_,
                                                raw_value)
                else:
                    eng_value = ul.to_eng_units_32(self.board_num, range_,
                                                   raw_value)
                channel_text[chan_num - low_chan] += (
                    '{:.3f}'.format(eng_value) + "\n")
                chan_num = low_chan if chan_num == high_chan else chan_num + 1

        # Update the labels for each channel
        for chan_num in range(low_chan, high_chan + 1):
            chan_index = chan_num - low_chan
            self.chan_labels[chan_index]["text"] = channel_text[chan_index]

    def recreate_input_data_frame(self):
        low_chan = self.input_low_chan
        high_chan = self.input_high_chan

        new_data_frame = tk.Frame(self.input_inner_data_frame)

        self.chan_labels = []
        # Add the labels for each channel
        for chan_num in range(low_chan, high_chan + 1):
            chan_label = tk.Label(new_data_frame, justify=tk.LEFT, padx=3)
            chan_label.grid(row=0, column=chan_num - low_chan)
            self.chan_labels.append(chan_label)

        self.data_frame.destroy()
        self.data_frame = new_data_frame
        self.data_frame.grid()

    def exit(self):
        self.stop_input()
        self.stop_output()
        self.master.destroy()

    def start_output_scan(self):
        # Build the data array
        self.output_low_chan = self.get_output_low_channel_num()
        self.output_high_chan = self.get_output_high_channel_num()
        self.num_output_chans = (
            self.output_high_chan - self.output_low_chan + 1)

        if self.output_low_chan > self.output_high_chan:
            messagebox.showerror(
                "Error",
                "Low Channel Number must be greater than or equal to High "
                "Channel Number")
            self.set_output_ui_idle_state()
            return

        points_per_channel = 1000
        rate = 1000
        num_points = self.num_output_chans * points_per_channel
        scan_options = (ScanOptions.BACKGROUND |
                        ScanOptions.CONTINUOUS | ScanOptions.SCALEDATA)
        ao_range = self.ao_info.supported_ranges[0]

        self.output_memhandle = ul.scaled_win_buf_alloc(num_points)

        # Check if the buffer was successfully allocated
        if not self.output_memhandle:
            messagebox.showerror("Error", "Failed to allocate memory")
            self.output_start_button["state"] = tk.NORMAL
            return

        try:
            data_array = cast(self.output_memhandle, POINTER(c_double))
            frequencies = self.add_output_example_data(
                data_array, ao_range, self.num_output_chans, rate,
                points_per_channel)

            self.recreate_freq_frame()
            self.display_output_signal_info(frequencies)

            ul.a_out_scan(
                self.board_num, self.output_low_chan, self.output_high_chan,
                num_points, rate, ao_range, self.output_memhandle,
                scan_options)

            # Start updating the displayed values
            self.update_output_displayed_values()
        except ULError as e:
            show_ul_error(e)
            self.set_output_ui_idle_state()
            return

    def display_output_signal_info(self, frequencies):
        for channel_num in range(
                self.output_low_chan, self.output_high_chan + 1):
            curr_row = channel_num - self.output_low_chan
            self.freq_labels[curr_row]["text"] = str(
                frequencies[curr_row]) + " Hz"

    def add_output_example_data(self, data_array, ao_range, num_chans,
                                rate, points_per_channel):
        # Calculate frequencies that will work well with the size of the array
        frequencies = []
        for channel_num in range(0, num_chans):
            frequencies.append(
                (channel_num + 1) / (points_per_channel / rate))

        # Calculate an amplitude and y-offset for the signal
        # to fill the analog output range
        amplitude = (ao_range.range_max - ao_range.range_min) / 2
        y_offset = (amplitude + ao_range.range_min) / 2

        # Fill the array with sine wave data at the calculated frequencies.
        # Note that since we are using the SCALEDATA option, the values
        # added to data_array are the actual voltage values that the device
        # will output
        data_index = 0
        for point_num in range(0, points_per_channel):
            for channel_num in range(0, num_chans):
                freq = frequencies[channel_num]
                value = amplitude * math.sin(
                    2 * math.pi * freq * point_num / rate) + y_offset
                data_array[data_index] = value
                data_index += 1

        return frequencies

    def update_output_displayed_values(self):
        # Get the status from the device
        status, curr_count, curr_index = ul.get_status(self.board_num,
                                                       FunctionType.AOFUNCTION)

        # Display the status info
        self.update_output_status_labels(status, curr_count, curr_index)

        # Call this method again until the stop button is pressed
        if status == Status.RUNNING:
            self.after(100, self.update_output_displayed_values)
        else:
            # Free the allocated memory
            ul.win_buf_free(self.output_memhandle)
            self.set_output_ui_idle_state()

    def update_output_status_labels(self, status, curr_count, curr_index):
        if status == Status.IDLE:
            self.output_status_label["text"] = "Idle"
        else:
            self.output_status_label["text"] = "Running"

        self.output_index_label["text"] = str(curr_index)
        self.output_count_label["text"] = str(curr_count)

    def recreate_freq_frame(self):
        low_chan = self.output_low_chan
        high_chan = self.output_high_chan

        new_freq_frame = tk.Frame(self.freq_inner_frame)

        curr_row = 0
        self.freq_labels = []
        for chan_num in range(low_chan, high_chan + 1):
            curr_row += 1
            channel_label = tk.Label(new_freq_frame)
            channel_label["text"] = (
                "Channel " + str(chan_num) + " Frequency:")
            channel_label.grid(row=curr_row, column=0, sticky=tk.W)

            freq_label = tk.Label(new_freq_frame)
            freq_label.grid(row=curr_row, column=1, sticky=tk.W)
            self.freq_labels.append(freq_label)

        self.freq_frame.destroy()
        self.freq_frame = new_freq_frame
        self.freq_frame.grid()

    def stop_output(self):
        ul.stop_background(self.board_num, FunctionType.AOFUNCTION)

    def set_output_ui_idle_state(self):
        self.output_high_channel_entry["state"] = tk.NORMAL
        self.output_low_channel_entry["state"] = tk.NORMAL
        self.output_start_button["command"] = self.start_output
        self.output_start_button["text"] = "Start Analog Output"

    def start_output(self):
        self.output_high_channel_entry["state"] = tk.DISABLED
        self.output_low_channel_entry["state"] = tk.DISABLED
        self.output_start_button["command"] = self.stop_output
        self.output_start_button["text"] = "Stop Analog Output"
        self.start_output_scan()

    def stop_input(self):
        ul.stop_background(self.board_num, FunctionType.AIFUNCTION)

    def set_input_ui_idle_state(self):
        self.input_high_channel_entry["state"] = tk.NORMAL
        self.input_low_channel_entry["state"] = tk.NORMAL
        self.input_start_button["command"] = self.start_input
        self.input_start_button["text"] = "Start Analog Input"

    def start_input(self):
        self.input_high_channel_entry["state"] = tk.DISABLED
        self.input_low_channel_entry["state"] = tk.DISABLED
        self.input_start_button["command"] = self.stop_input
        self.input_start_button["text"] = "Stop Analog Input"
        self.start_input_scan()

    def get_input_low_channel_num(self):
        if self.ai_info.num_chans == 1:
            return 0
        try:
            return int(self.input_low_channel_entry.get())
        except ValueError:
            return 0

    def get_input_high_channel_num(self):
        if self.ai_info.num_chans == 1:
            return 0
        try:
            return int(self.input_high_channel_entry.get())
        except ValueError:
            return 0

    def get_output_low_channel_num(self):
        if self.ao_info.num_chans == 1:
            return 0
        try:
            return int(self.output_low_channel_entry.get())
        except ValueError:
            return 0

    def get_output_high_channel_num(self):
        if self.ao_info.num_chans == 1:
            return 0
        try:
            return int(self.output_high_channel_entry.get())
        except ValueError:
            return 0

    def validate_channel_entry(self, p):
        if p == '':
            return True
        try:
            value = int(p)
            if value < 0 or value > self.ai_info.num_chans - 1:
                return False
        except ValueError:
            return False

        return True

    def create_widgets(self):
        '''Create the tkinter UI'''
        self.device_label = tk.Label(self)
        self.device_label.pack(fill=tk.NONE, anchor=tk.NW)
        self.device_label["text"] = ('Board Number ' + str(self.board_num)
                                     + ": " + self.device_info.product_name
                                     + " (" + self.device_info.unique_id + ")")

        channel_vcmd = self.register(self.validate_channel_entry)

        main_frame = tk.Frame(self)
        main_frame.pack(fill=tk.X, anchor=tk.NW)

        input_groupbox = tk.LabelFrame(main_frame, text="Analog Input")
        input_groupbox.pack(side=tk.LEFT, anchor=tk.NW)

        if self.ai_info.num_chans > 1:
            curr_row = 0

            input_channels_frame = tk.Frame(input_groupbox)
            input_channels_frame.pack(fill=tk.X, anchor=tk.NW)

            input_low_channel_entry_label = tk.Label(
                input_channels_frame)
            input_low_channel_entry_label["text"] = (
                "Low Channel Number:")
            input_low_channel_entry_label.grid(
                row=curr_row, column=0, sticky=tk.W)

            self.input_low_channel_entry = tk.Spinbox(
                input_channels_frame, from_=0,
                to=max(self.ai_info.num_chans - 1, 0),
                validate='key', validatecommand=(channel_vcmd, '%P'))
            self.input_low_channel_entry.grid(
                row=curr_row, column=1, sticky=tk.W)

            curr_row += 1
            input_high_channel_entry_label = tk.Label(
                input_channels_frame)
            input_high_channel_entry_label["text"] = (
                "High Channel Number:")
            input_high_channel_entry_label.grid(
                row=curr_row, column=0, sticky=tk.W)

            self.input_high_channel_entry = tk.Spinbox(
                input_channels_frame, from_=0,
                to=max(self.ai_info.num_chans - 1, 0),
                validate='key', validatecommand=(channel_vcmd, '%P'))
            self.input_high_channel_entry.grid(
                row=curr_row, column=1, sticky=tk.W)
            initial_value = min(self.ai_info.num_chans - 1, 3)
            self.input_high_channel_entry.delete(0, tk.END)
            self.input_high_channel_entry.insert(0, str(initial_value))

            curr_row += 1

        self.input_start_button = tk.Button(input_groupbox)
        self.input_start_button["text"] = "Start Analog Input"
        self.input_start_button["command"] = self.start_input
        self.input_start_button.pack(
            fill=tk.X, anchor=tk.NW, padx=3, pady=3)

        self.input_results_group = tk.LabelFrame(
            input_groupbox, text="Results", padx=3, pady=3)
        self.input_results_group.pack(
            fill=tk.X, anchor=tk.NW, padx=3, pady=3)

        self.input_results_group.grid_columnconfigure(1, weight=1)

        curr_row = 0
        input_status_left_label = tk.Label(self.input_results_group)
        input_status_left_label["text"] = "Status:"
        input_status_left_label.grid(
            row=curr_row, column=0, sticky=tk.W)

        self.input_status_label = tk.Label(self.input_results_group)
        self.input_status_label["text"] = "Idle"
        self.input_status_label.grid(
            row=curr_row, column=1, sticky=tk.W)

        curr_row += 1
        input_index_left_label = tk.Label(self.input_results_group)
        input_index_left_label["text"] = "Index:"
        input_index_left_label.grid(row=curr_row, column=0, sticky=tk.W)

        self.input_index_label = tk.Label(self.input_results_group)
        self.input_index_label["text"] = "-1"
        self.input_index_label.grid(row=curr_row, column=1, sticky=tk.W)

        curr_row += 1
        input_count_left_label = tk.Label(self.input_results_group)
        input_count_left_label["text"] = "Count:"
        input_count_left_label.grid(row=curr_row, column=0, sticky=tk.W)

        self.input_count_label = tk.Label(self.input_results_group)
        self.input_count_label["text"] = "0"
        self.input_count_label.grid(row=curr_row, column=1, sticky=tk.W)

        curr_row += 1
        self.input_inner_data_frame = tk.Frame(self.input_results_group)
        self.input_inner_data_frame.grid(
            row=curr_row, column=0, columnspan=2, sticky=tk.W)

        self.data_frame = tk.Frame(self.input_inner_data_frame)
        self.data_frame.grid()

        output_groupbox = tk.LabelFrame(
            main_frame, text="Analog Output")
        output_groupbox.pack(side=tk.RIGHT, anchor=tk.NW)

        if self.ao_info.num_chans > 1:
            curr_row = 0
            output_channels_frame = tk.Frame(output_groupbox)
            output_channels_frame.pack(fill=tk.X, anchor=tk.NW)

            output_low_channel_entry_label = tk.Label(
                output_channels_frame)
            output_low_channel_entry_label["text"] = (
                "Low Channel Number:")
            output_low_channel_entry_label.grid(
                row=curr_row, column=0, sticky=tk.W)

            self.output_low_channel_entry = tk.Spinbox(
                output_channels_frame, from_=0,
                to=max(self.ao_info.num_chans - 1, 0),
                validate='key', validatecommand=(channel_vcmd, '%P'))
            self.output_low_channel_entry.grid(
                row=curr_row, column=1, sticky=tk.W)

            curr_row += 1
            output_high_channel_entry_label = tk.Label(
                output_channels_frame)
            output_high_channel_entry_label["text"] = (
                "High Channel Number:")
            output_high_channel_entry_label.grid(
                row=curr_row, column=0, sticky=tk.W)

            self.output_high_channel_entry = tk.Spinbox(
                output_channels_frame, from_=0,
                to=max(self.ao_info.num_chans - 1, 0),
                validate='key', validatecommand=(channel_vcmd, '%P'))
            self.output_high_channel_entry.grid(
                row=curr_row, column=1, sticky=tk.W)
            initial_value = min(self.ao_info.num_chans - 1, 3)
            self.output_high_channel_entry.delete(0, tk.END)
            self.output_high_channel_entry.insert(0, str(initial_value))

        self.output_start_button = tk.Button(output_groupbox)
        self.output_start_button["text"] = "Start Analog Output"
        self.output_start_button["command"] = self.start_output
        self.output_start_button.pack(
            fill=tk.X, anchor=tk.NW, padx=3, pady=3)

        output_scan_info_group = tk.LabelFrame(
            output_groupbox, text="Scan Information", padx=3, pady=3)
        output_scan_info_group.pack(
            fill=tk.X, anchor=tk.NW, padx=3, pady=3)

        output_scan_info_group.grid_columnconfigure(1, weight=1)

        curr_row = 0
        output_status_left_label = tk.Label(output_scan_info_group)
        output_status_left_label["text"] = "Status:"
        output_status_left_label.grid(
            row=curr_row, column=0, sticky=tk.W)

        self.output_status_label = tk.Label(output_scan_info_group)
        self.output_status_label["text"] = "Idle"
        self.output_status_label.grid(
            row=curr_row, column=1, sticky=tk.W)

        curr_row += 1
        output_index_left_label = tk.Label(output_scan_info_group)
        output_index_left_label["text"] = "Index:"
        output_index_left_label.grid(
            row=curr_row, column=0, sticky=tk.W)

        self.output_index_label = tk.Label(output_scan_info_group)
        self.output_index_label["text"] = "-1"
        self.output_index_label.grid(
            row=curr_row, column=1, sticky=tk.W)

        curr_row += 1
        output_count_left_label = tk.Label(output_scan_info_group)
        output_count_left_label["text"] = "Count:"
        output_count_left_label.grid(
            row=curr_row, column=0, sticky=tk.W)

        self.output_count_label = tk.Label(output_scan_info_group)
        self.output_count_label["text"] = "0"
        self.output_count_label.grid(
            row=curr_row, column=1, sticky=tk.W)

        curr_row += 1
        self.freq_inner_frame = tk.Frame(output_scan_info_group)
        self.freq_inner_frame.grid(
            row=curr_row, column=0, columnspan=2, sticky=tk.W)

        self.freq_frame = tk.Frame(self.freq_inner_frame)
        self.freq_frame.grid()

        button_frame = tk.Frame(self)
        button_frame.pack(fill=tk.X, side=tk.RIGHT, anchor=tk.SE)

        self.quit_button = tk.Button(button_frame)
        self.quit_button["text"] = "Quit"
        self.quit_button["command"] = self.exit
        self.quit_button.grid(row=0, column=1, padx=3, pady=3)
Exemple #24
0
class ULAI01(UIExample):
    def __init__(self, master):
        super(ULAI01, self).__init__(master)
        # By default, the example detects all available devices and selects the
        # first device listed.
        # If use_device_detection is set to False, the board_num property needs
        # to match the desired board number configured with Instacal.
        use_device_detection = True
        self.board_num = 0

        self.running = False

        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)
            if self.device_info.supports_analog_input:
                self.ai_info = self.device_info.get_ai_info()
                self.create_widgets()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets(True)

    def update_value(self):
        channel = self.get_channel_num()
        ai_range = self.ai_info.supported_ranges[0]

        try:
            # Get a value from the device
            if self.ai_info.resolution <= 16:
                # Use the a_in method for devices with a resolution <= 16
                value = ul.a_in(self.board_num, channel, ai_range)
                # Convert the raw value to engineering units
                eng_units_value = ul.to_eng_units(self.board_num, ai_range,
                                                  value)
            else:
                # Use the a_in_32 method for devices with a resolution > 16
                # (optional parameter omitted)
                value = ul.a_in_32(self.board_num, channel, ai_range)
                # Convert the raw value to engineering units
                eng_units_value = ul.to_eng_units_32(self.board_num, ai_range,
                                                     value)

            # Display the raw value
            self.value_label["text"] = str(value)
            # Display the engineering value
            self.eng_value_label["text"] = '{:.3f}'.format(eng_units_value)

            # Call this method again until the stop button is pressed (or an
            # error occurs)
            if self.running:
                self.after(100, self.update_value)
        except ULError as e:
            self.stop()
            show_ul_error(e)

    def stop(self):
        self.running = False
        self.start_button["command"] = self.start
        self.start_button["text"] = "Start"

    def start(self):
        self.running = True
        self.start_button["command"] = self.stop
        self.start_button["text"] = "Stop"
        self.update_value()

    def get_channel_num(self):
        if self.ai_info.num_chans == 1:
            return 0
        try:
            return int(self.channel_entry.get())
        except ValueError:
            return 0

    def validate_channel_entry(self, p):
        if p == '':
            return True
        try:
            value = int(p)
            if value < 0 or value > self.ai_info.num_chans - 1:
                return False
        except ValueError:
            return False

        return True

    def create_widgets(self):
        '''Create the tkinter UI'''
        self.device_label = tk.Label(self)
        self.device_label.pack(fill=tk.NONE, anchor=tk.NW)
        self.device_label["text"] = ('Board Number ' + str(self.board_num)
                                     + ": " + self.device_info.product_name
                                     + " (" + self.device_info.unique_id + ")")

        main_frame = tk.Frame(self)
        main_frame.pack(fill=tk.X, anchor=tk.NW)

        curr_row = 0
        if self.ai_info.num_chans > 1:
            channel_vcmd = self.register(self.validate_channel_entry)

            channel_entry_label = tk.Label(main_frame)
            channel_entry_label["text"] = "Channel Number:"
            channel_entry_label.grid(
                row=curr_row, column=0, sticky=tk.W)

            self.channel_entry = tk.Spinbox(
                main_frame, from_=0,
                to=max(self.ai_info.num_chans - 1, 0),
                validate='key', validatecommand=(channel_vcmd, '%P'))
            self.channel_entry.grid(
                row=curr_row, column=1, sticky=tk.W)

            curr_row += 1

        raw_value_left_label = tk.Label(main_frame)
        raw_value_left_label["text"] = "Value read from selected channel:"
        raw_value_left_label.grid(row=curr_row, column=0, sticky=tk.W)

        self.value_label = tk.Label(main_frame)
        self.value_label.grid(row=curr_row, column=1, sticky=tk.W)

        curr_row += 1
        eng_value_left_label = tk.Label(main_frame)
        eng_value_left_label["text"] = "Value converted to voltage:"
        eng_value_left_label.grid(row=curr_row, column=0, sticky=tk.W)

        self.eng_value_label = tk.Label(main_frame)
        self.eng_value_label.grid(row=curr_row, column=1, sticky=tk.W)

        button_frame = tk.Frame(self)
        button_frame.pack(fill=tk.X, side=tk.RIGHT, anchor=tk.SE)

        self.start_button = tk.Button(button_frame)
        self.start_button["text"] = "Start"
        self.start_button["command"] = self.start
        self.start_button.grid(row=0, column=0, padx=3, pady=3)

        quit_button = tk.Button(button_frame)
        quit_button["text"] = "Quit"
        quit_button["command"] = self.master.destroy
        quit_button.grid(row=0, column=1, padx=3, pady=3)
Exemple #25
0
class TimerOutStart01(UIExample):
    def __init__(self, master=None):
        super(TimerOutStart01, self).__init__(master)
        master.protocol("WM_DELETE_WINDOW", self.exit)
        # By default, the example detects all available devices and selects the
        # first device listed.
        # If use_device_detection is set to False, the board_num property needs
        # to match the desired board number configured with Instacal.
        use_device_detection = True
        self.board_num = 0

        self.first_chan_num = -1
        self.last_chan_num = -1

        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)
            counter_info = self.device_info.get_ctr_info()

            # Find the first pulse counter
            first_chan = next((channel for channel in counter_info.chan_info
                               if channel.type == CounterChannelType.CTRTMR),
                              None)
            if first_chan is not None:
                last_chan = next(
                    (channel for channel in reversed(counter_info.chan_info)
                     if channel.type == CounterChannelType.CTRTMR), None)
                self.first_chan_num = first_chan.channel_num
                self.last_chan_num = last_chan.channel_num
                self.create_widgets()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets(True)

    def update_output(self):
        try:
            timer_num = self.get_channel_num()
            frequency = self.get_frequency()

            actual_freq = ul.timer_out_start(self.board_num, timer_num,
                                             frequency)

            self.update_actual_values(actual_freq)
        except ULError as e:
            show_ul_error(e)

    def exit(self):
        # Stop all the timers at exit
        if self.first_chan_num != -1:
            for chan_num in range(self.first_chan_num, self.last_chan_num + 1):
                try:
                    ul.timer_out_stop(self.board_num, chan_num)
                except ULError as e:
                    show_ul_error(e)
        self.master.destroy()

    def update_actual_values(self, actual_freq):
        self.actual_freq_label["text"] = str(actual_freq)

    def get_frequency(self):
        try:
            return float(self.freq_entry.get())
        except ValueError:
            return 100000

    def get_channel_num(self):
        if self.last_chan_num == self.first_chan_num:
            return self.last_chan_num
        try:
            return int(self.channel_entry.get())
        except ValueError:
            return 0

    def validate_channel_entry(self, p):
        if p == '':
            return True
        try:
            value = int(p)
            if value < self.first_chan_num or value > self.last_chan_num:
                return False
        except ValueError:
            return False

        return True

    def create_widgets(self):
        '''Create the tkinter UI'''
        self.device_label = tk.Label(self)
        self.device_label.pack(fill=tk.NONE, anchor=tk.NW)
        self.device_label["text"] = ('Board Number ' + str(self.board_num) +
                                     ": " + self.device_info.product_name +
                                     " (" + self.device_info.unique_id + ")")

        main_frame = tk.Frame(self)
        main_frame.pack(fill=tk.X, anchor=tk.NW)

        channel_vcmd = self.register(self.validate_channel_entry)
        float_vcmd = self.register(validate_float_entry)

        curr_row = 0
        if self.last_chan_num != self.first_chan_num:
            channel_entry_label = tk.Label(main_frame)
            channel_entry_label["text"] = "Channel Number:"
            channel_entry_label.grid(row=curr_row, column=0, sticky=tk.W)

            self.channel_entry = tk.Spinbox(main_frame,
                                            from_=self.first_chan_num,
                                            to=self.last_chan_num,
                                            validate='key',
                                            validatecommand=(channel_vcmd,
                                                             '%P'))
            self.channel_entry.grid(row=curr_row, column=1, sticky=tk.W)

        curr_row += 1
        freq_label = tk.Label(main_frame)
        freq_label["text"] = "Frequency:"
        freq_label.grid(row=curr_row, column=0, sticky=tk.W)

        self.freq_entry = tk.Entry(main_frame,
                                   validate='key',
                                   validatecommand=(float_vcmd, '%P'))
        self.freq_entry.grid(row=curr_row, column=1, sticky=tk.W)
        self.freq_entry.insert(0, "100000")

        curr_row += 1
        update_button = tk.Button(main_frame)
        update_button["text"] = "Update"
        update_button["command"] = self.update_output
        update_button.grid(row=curr_row,
                           column=0,
                           columnspan=2,
                           padx=3,
                           pady=3)

        curr_row += 1
        actual_freq_left_label = tk.Label(main_frame)
        actual_freq_left_label["text"] = "Actual Frequency:"
        actual_freq_left_label.grid(row=curr_row, column=0, sticky=tk.W)

        self.actual_freq_label = tk.Label(main_frame)
        self.actual_freq_label.grid(row=curr_row, column=1, sticky=tk.W)

        button_frame = tk.Frame(self)
        button_frame.pack(fill=tk.X, side=tk.RIGHT, anchor=tk.SE)

        quit_button = tk.Button(button_frame)
        quit_button["text"] = "Quit"
        quit_button["command"] = self.exit
        quit_button.grid(row=0, column=1, padx=3, pady=3)
Exemple #26
0
class DaqSetSetpoints01(UIExample):
    def __init__(self, master=None):
        super(DaqSetSetpoints01, self).__init__(master)
        # By default, the example detects all available devices and selects the
        # first device listed.
        # If use_device_detection is set to False, the board_num property needs
        # to match the desired board number configured with Instacal.
        use_device_detection = True
        self.board_num = 0

        self.chan_list = []
        self.chan_type_list = []
        self.gain_list = []
        self.num_chans = 4

        self.setpoint_flags_list = []
        self.setpoint_output_list = []
        self.limit_a_list = []
        self.limit_b_list = []
        self.output_1_list = []
        self.output_2_list = []
        self.output_mask_1_list = []
        self.output_mask_2_list = []
        self.setpoint_count = 3

        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)

            daqi_info = self.device_info.get_daqi_info()
            if (self.device_info.supports_daq_input
                    and daqi_info.supports_setpoints):
                self.init_scan_channel_info()
                self.init_setpoints()
                self.create_widgets()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets(True)

    def init_scan_channel_info(self):
        # Add analog input channels
        self.chan_list.append(0)
        self.chan_type_list.append(ChannelType.ANALOG +
                                   ChannelType.SETPOINT_ENABLE)
        self.gain_list.append(ULRange.BIP10VOLTS)

        self.chan_list.append(1)
        self.chan_type_list.append(ChannelType.ANALOG +
                                   ChannelType.SETPOINT_ENABLE)
        self.gain_list.append(ULRange.BIP10VOLTS)

        # Add a digital input channel
        self.chan_list.append(DigitalPortType.FIRSTPORTA)
        self.chan_type_list.append(ChannelType.DIGITAL8 +
                                   ChannelType.SETPOINT_ENABLE)
        self.gain_list.append(ULRange.NOTUSED)

        # Add a setpoint status channel
        self.chan_list.append(0)
        self.chan_type_list.append(ChannelType.SETPOINTSTATUS)
        self.gain_list.append(ULRange.NOTUSED)

    def init_setpoints(self):
        # Setpoint configurations for ChanArray[0] (CH0)
        self.setpoint_flags_list.append(SetpointFlag.LESSTHAN_LIMITA +
                                        SetpointFlag.UPDATEON_TRUEANDFALSE)
        # Setpoint result outputs a value to Analog Out 0
        self.setpoint_output_list.append(SetpointOutput.DAC0)
        # If CH0 less than 3.0 volts apply output1, else apply output2
        self.limit_a_list.append(3)
        self.limit_b_list.append(0)  # Ignored when LessThanLimitA flag is used
        self.output_1_list.append(5)  # Output 5.0 volts on Analog Out 0
        self.output_2_list.append(-5)  # Output -5.0 volts on Analog Out 0
        self.output_mask_1_list.append(0)  # Ignored for DAC0 output type
        self.output_mask_2_list.append(0)  # Ignored for DAC0 output type

        # Setpoint configurations for ChanArray[1] (CH1)
        self.setpoint_flags_list.append(SetpointFlag.GREATERTHAN_LIMITB +
                                        SetpointFlag.UPDATEON_TRUEANDFALSE)
        # Setpoint result outputs a value to digital port C
        self.setpoint_output_list.append(SetpointOutput.FIRSTPORTC)
        # Ignored when GreaterThanLimitB flag is used
        self.limit_a_list.append(0)
        # If CH1 greater than 2.0 volts apply output1
        self.limit_b_list.append(2)
        # Output a bit pattern of 01010101 to digital port C
        self.output_1_list.append(0x55)
        # Output a bit pattern of 10101010 to digital port C
        self.output_2_list.append(0xAA)
        # Output the value of 'out1' on low nibble only
        self.output_mask_1_list.append(0x0F)
        # Output the value of 'out2' on low nibble only
        self.output_mask_2_list.append(0x0F)

        # Setpoint configurations for ChanArray[2] (FIRSTPORTA)
        self.setpoint_flags_list.append(SetpointFlag.EQUAL_LIMITA
                                        | SetpointFlag.UPDATEON_TRUEONLY)
        # Setpoint result outputs a value to Timer 0
        self.setpoint_output_list.append(SetpointOutput.TMR0)
        # If FirstPortA equal 00001111 bit pattern apply output1
        self.limit_a_list.append(0x0F)
        self.limit_b_list.append(2)  # Ignored when EqualLimitA flag is used
        self.output_1_list.append(100)  # Output a 100Hz square wave on Timer 0
        # Ignored when SF_UPDATEON_TRUEONLY flag is used
        self.output_2_list.append(0)
        self.output_mask_1_list.append(0)  # Ignored for 'TMR0' output type
        self.output_mask_2_list.append(0)  # Ignored for 'TMR0' output type

    def start_scan(self):
        rate = 100
        points_per_channel = 100
        total_count = points_per_channel * self.num_chans
        scan_options = ScanOptions.BACKGROUND | ScanOptions.CONTINUOUS

        # Allocate a buffer for the scan
        self.memhandle = ul.win_buf_alloc(total_count)

        # Check if the buffer was successfully allocated
        if not self.memhandle:
            messagebox.showerror("Error", "Failed to allocate memory")
            self.start_button["state"] = tk.NORMAL
            return

        try:
            # Configure the setpoints
            ul.daq_set_setpoints(self.board_num, self.limit_a_list,
                                 self.limit_b_list, self.setpoint_flags_list,
                                 self.setpoint_output_list, self.output_1_list,
                                 self.output_2_list, self.output_mask_1_list,
                                 self.output_mask_2_list, self.setpoint_count)

            # Run the scan
            ul.daq_in_scan(self.board_num, self.chan_list, self.chan_type_list,
                           self.gain_list, self.num_chans, rate, 0,
                           total_count, self.memhandle, scan_options)

            # Cast the memhandle to a ctypes pointer
            # Note: the ctypes array will only be valid until win_buf_free
            # is called.
            # A copy of the buffer can be created using win_buf_to_array
            # before the memory is freed. The copy can be used at any time.
            self.array = cast(self.memhandle, POINTER(c_ushort))
        except ULError as e:
            # Free the allocated memory
            ul.win_buf_free(self.memhandle)
            show_ul_error(e)
            return

        # Start updating the displayed values
        self.update_displayed_values()

    def update_displayed_values(self):
        # Get the status from the device
        status, curr_count, curr_index = ul.get_status(
            self.board_num, FunctionType.DAQIFUNCTION)

        # Display the status info
        self.update_status_labels(status, curr_count, curr_index)

        # Display the values
        self.display_values(curr_index, curr_count)

        # Call this method again until the stop button is pressed
        if status == Status.RUNNING:
            self.after(100, self.update_displayed_values)
        else:
            # Free the allocated memory
            ul.win_buf_free(self.memhandle)
            self.set_ui_idle_state()

    def update_status_labels(self, status, curr_count, curr_index):
        if status == Status.IDLE:
            self.setpoint_status_label["text"] = "Idle"
        else:
            self.setpoint_status_label["text"] = "Running"

        self.index_label["text"] = str(curr_index)
        self.count_label["text"] = str(curr_count)

    def display_values(self, curr_index, curr_count):
        array = self.array

        # If no data has been gathered, don't add data to the labels
        if curr_count > 1:
            # Convert the CH0 value to volts and display it
            chan_0_eng_value = ul.to_eng_units(self.board_num,
                                               self.gain_list[0],
                                               array[curr_index])
            self.chan_0_label["text"] = '{:.3f}'.format(
                chan_0_eng_value) + " Volts"

            # Convert the CH1 value to volts and display it
            chan_1_eng_value = ul.to_eng_units(self.board_num,
                                               self.gain_list[0],
                                               array[curr_index + 1])
            self.chan_1_label["text"] = '{:.3f}'.format(
                chan_1_eng_value) + " Volts"

            # Display the digital port value as hex
            self.digital_label["text"] = '0x' + \
                '{:0<2X}'.format(array[curr_index + 2])

            # Display the setpoint status as hex
            self.setpoint_status_label["text"] = '0x' + \
                '{:0<4X}'.format(array[curr_index + 3])

    def stop(self):
        ul.stop_background(self.board_num, FunctionType.DAQIFUNCTION)

    def set_ui_idle_state(self):
        self.start_button["command"] = self.start
        self.start_button["text"] = "Start"

    def start(self):
        self.start_button["command"] = self.stop
        self.start_button["text"] = "Stop"
        self.start_scan()

    def create_widgets(self):
        '''Create the tkinter UI'''
        self.device_label = tk.Label(self)
        self.device_label.pack(fill=tk.NONE, anchor=tk.NW)
        self.device_label["text"] = ('Board Number ' + str(self.board_num) +
                                     ": " + self.device_info.product_name +
                                     " (" + self.device_info.unique_id + ")")

        main_frame = tk.Frame(self)
        main_frame.pack(fill=tk.X, anchor=tk.NW)

        curr_row = 0
        chan_0_left_label = tk.Label(main_frame, justify=tk.LEFT, padx=3)
        chan_0_left_label["text"] = "Channel 0:"
        chan_0_left_label.grid(row=curr_row, column=0, sticky=tk.W)

        self.chan_0_label = tk.Label(main_frame, justify=tk.LEFT, padx=3)
        self.chan_0_label.grid(row=curr_row, column=1, sticky=tk.W)

        curr_row += 1
        chan_1_left_label = tk.Label(main_frame, justify=tk.LEFT, padx=3)
        chan_1_left_label["text"] = "Channel 1:"
        chan_1_left_label.grid(row=curr_row, column=0, sticky=tk.W)

        self.chan_1_label = tk.Label(main_frame, justify=tk.LEFT, padx=3)
        self.chan_1_label.grid(row=curr_row, column=1, sticky=tk.W)

        curr_row += 1
        digital_left_label = tk.Label(main_frame, justify=tk.LEFT, padx=3)
        digital_left_label["text"] = "FIRSTPORTA:"
        digital_left_label.grid(row=curr_row, column=0, sticky=tk.W)

        self.digital_label = tk.Label(main_frame, justify=tk.LEFT, padx=3)
        self.digital_label.grid(row=curr_row, column=1, sticky=tk.W)

        curr_row += 1
        setpoint_status_left_label = tk.Label(main_frame,
                                              justify=tk.LEFT,
                                              padx=3)
        setpoint_status_left_label["text"] = "Status:"
        setpoint_status_left_label.grid(row=curr_row, column=0, sticky=tk.W)

        self.setpoint_status_label = tk.Label(main_frame,
                                              justify=tk.LEFT,
                                              padx=3)
        self.setpoint_status_label["text"] = "Idle"
        self.setpoint_status_label.grid(row=curr_row, column=1, sticky=tk.W)

        curr_row += 1
        index_left_label = tk.Label(main_frame, justify=tk.LEFT, padx=3)
        index_left_label["text"] = "Index:"
        index_left_label.grid(row=curr_row, column=0, sticky=tk.W)

        self.index_label = tk.Label(main_frame, justify=tk.LEFT, padx=3)
        self.index_label["text"] = "-1"
        self.index_label.grid(row=curr_row, column=1, sticky=tk.W)

        curr_row += 1
        count_left_label = tk.Label(main_frame, justify=tk.LEFT, padx=3)
        count_left_label["text"] = "Count:"
        count_left_label.grid(row=curr_row, column=0, sticky=tk.W)

        self.count_label = tk.Label(main_frame, justify=tk.LEFT, padx=3)
        self.count_label["text"] = "0"
        self.count_label.grid(row=curr_row, column=1, sticky=tk.W)

        button_frame = tk.Frame(self)
        button_frame.pack(fill=tk.X, side=tk.RIGHT, anchor=tk.SE)

        self.start_button = tk.Button(button_frame)
        self.start_button["text"] = "Start"
        self.start_button["command"] = self.start
        self.start_button.grid(row=0, column=0, padx=3, pady=3)

        quit_button = tk.Button(button_frame)
        quit_button["text"] = "Quit"
        quit_button["command"] = self.master.destroy
        quit_button.grid(row=0, column=1, padx=3, pady=3)
Exemple #27
0
class ULAI03(UIExample):
    def __init__(self, master=None):
        super(ULAI03, self).__init__(master)
        # By default, the example detects all available devices and selects the
        # first device listed.
        # If use_device_detection is set to False, the board_num property needs
        # to match the desired board number configured with Instacal.
        use_device_detection = True
        self.board_num = 0

        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)
            self.ai_info = self.device_info.get_ai_info()
            if self.ai_info.is_supported and self.ai_info.supports_scan:
                self.create_widgets()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets()

    def start_scan(self):
        self.low_chan = self.get_low_channel_num()
        self.high_chan = self.get_high_channel_num()
        self.num_chans = self.high_chan - self.low_chan + 1
        if self.low_chan > self.high_chan:
            messagebox.showerror(
                "Error",
                "Low Channel Number must be greater than or equal to High "
                "Channel Number")
            self.set_ui_idle_state()
            return

        rate = 100
        points_per_channel = 1000
        total_count = points_per_channel * self.num_chans
        ai_range = self.ai_info.supported_ranges[0]

        # Allocate a buffer for the scan
        if self.ai_info.resolution <= 16:
            # Use the win_buf_alloc method for devices with a resolution <=
            # 16
            self.memhandle = ul.win_buf_alloc(total_count)
            # Convert the memhandle to a ctypes array
            # Use the memhandle_as_ctypes_array method for devices with a
            # resolution <= 16
            self.ctypes_array = cast(self.memhandle, POINTER(c_ushort))
        else:
            # Use the win_buf_alloc_32 method for devices with a resolution
            # > 16
            self.memhandle = ul.win_buf_alloc_32(total_count)
            # Use the memhandle_as_ctypes_array_32 method for devices with a
            # resolution > 16
            self.ctypes_array = cast(self.memhandle, POINTER(c_ulong))

        # Note: the ctypes array will no longer be valid after
        # win_buf_free is called.
        # A copy of the buffer can be created using win_buf_to_array
        # or win_buf_to_array_32 before the memory is freed. The copy
        # can be used at any time.

        # Check if the buffer was successfully allocated
        if not self.memhandle:
            messagebox.showerror("Error", "Failed to allocate memory")
            self.set_ui_idle_state()
            return

        # Create the frames that will hold the data
        self.recreate_data_frame()

        try:
            # Start the scan
            ul.a_in_scan(self.board_num, self.low_chan, self.high_chan,
                         total_count, rate, ai_range, self.memhandle,
                         ScanOptions.BACKGROUND)
        except ULError as e:
            show_ul_error(e)
            self.set_ui_idle_state()
            return

        # Start updating the displayed values
        self.update_displayed_values()

    def update_displayed_values(self):
        # Get the status from the device
        status, curr_count, curr_index = ul.get_status(self.board_num,
                                                       FunctionType.AIFUNCTION)

        # Display the status info
        self.update_status_labels(status, curr_count, curr_index)

        # Display the values
        self.display_values(curr_index, curr_count)

        # Call this method again until the stop button is pressed
        if status == Status.RUNNING:
            self.after(100, self.update_displayed_values)
        else:
            # Free the allocated memory
            ul.win_buf_free(self.memhandle)
            # Stop the background operation (this is required even if the
            # scan completes successfully)
            ul.stop_background(self.board_num, FunctionType.AIFUNCTION)
            self.set_ui_idle_state()

    def update_status_labels(self, status, curr_count, curr_index):
        if status == Status.IDLE:
            self.status_label["text"] = "Idle"
        else:
            self.status_label["text"] = "Running"

        self.index_label["text"] = str(curr_index)
        self.count_label["text"] = str(curr_count)

    def display_values(self, curr_index, curr_count):
        per_channel_display_count = 10
        array = self.ctypes_array
        low_chan = self.low_chan
        high_chan = self.high_chan
        channel_text = []

        # Add the headers
        for chan_num in range(low_chan, high_chan + 1):
            channel_text.append("Channel " + str(chan_num) + "\n")

        # If no data has been gathered, don't add data to the labels
        if curr_count > 1:
            chan_count = high_chan - low_chan + 1

            chan_num = low_chan
            # curr_index points to the start of the last completed channel
            # scan that was transferred between the board and the data
            # buffer. Based on this, calculate the first index we want to
            # display using subtraction.
            first_index = max(curr_index - ((per_channel_display_count - 1)
                                            * chan_count), 0)
            last_index = first_index + min(chan_count
                                           * per_channel_display_count,
                                           curr_count)
            # Add (up to) the latest 10 values for each channel to the text
            for data_index in range(first_index, last_index):
                channel_text[chan_num - low_chan] += (str(array[data_index])
                                                      + "\n")
                chan_num = low_chan if chan_num == high_chan else chan_num + 1

        # Update the labels for each channel
        for chan_num in range(low_chan, high_chan + 1):
            chan_index = chan_num - low_chan
            self.chan_labels[chan_index]["text"] = channel_text[chan_index]

    def recreate_data_frame(self):
        low_chan = self.low_chan
        high_chan = self.high_chan

        new_data_frame = tk.Frame(self.inner_data_frame)

        self.chan_labels = []
        # Add the labels for each channel
        for chan_num in range(low_chan, high_chan + 1):
            chan_label = tk.Label(new_data_frame, justify=tk.LEFT, padx=3)
            chan_label.grid(row=0, column=chan_num - low_chan)
            self.chan_labels.append(chan_label)

        self.data_frame.destroy()
        self.data_frame = new_data_frame
        self.data_frame.grid()

    def stop(self):
        ul.stop_background(self.board_num, FunctionType.AIFUNCTION)

    def set_ui_idle_state(self):
        self.high_channel_entry["state"] = tk.NORMAL
        self.low_channel_entry["state"] = tk.NORMAL
        self.start_button["command"] = self.start
        self.start_button["text"] = "Start"

    def start(self):
        self.high_channel_entry["state"] = tk.DISABLED
        self.low_channel_entry["state"] = tk.DISABLED
        self.start_button["command"] = self.stop
        self.start_button["text"] = "Stop"
        self.start_scan()

    def get_low_channel_num(self):
        if self.ai_info.num_chans == 1:
            return 0
        try:
            return int(self.low_channel_entry.get())
        except ValueError:
            return 0

    def get_high_channel_num(self):
        if self.ai_info.num_chans == 1:
            return 0
        try:
            return int(self.high_channel_entry.get())
        except ValueError:
            return 0

    def validate_channel_entry(self, p):
        if p == '':
            return True
        try:
            value = int(p)
            if value < 0 or value > self.ai_info.num_chans - 1:
                return False
        except ValueError:
            return False

        return True

    def create_widgets(self):
        '''Create the tkinter UI'''
        self.device_label = tk.Label(self)
        self.device_label.pack(fill=tk.NONE, anchor=tk.NW)
        self.device_label["text"] = ('Board Number ' + str(self.board_num)
                                     + ": " + self.device_info.product_name
                                     + " (" + self.device_info.unique_id + ")")

        main_frame = tk.Frame(self)
        main_frame.pack(fill=tk.X, anchor=tk.NW)

        curr_row = 0
        if self.ai_info.num_chans > 1:
            channel_vcmd = self.register(self.validate_channel_entry)

            low_channel_entry_label = tk.Label(main_frame)
            low_channel_entry_label["text"] = "Low Channel Number:"
            low_channel_entry_label.grid(
                row=curr_row, column=0, sticky=tk.W)

            self.low_channel_entry = tk.Spinbox(
                main_frame, from_=0,
                to=max(self.ai_info.num_chans - 1, 0),
                validate='key', validatecommand=(channel_vcmd, '%P'))
            self.low_channel_entry.grid(
                row=curr_row, column=1, sticky=tk.W)

            curr_row += 1
            high_channel_entry_label = tk.Label(main_frame)
            high_channel_entry_label["text"] = "High Channel Number:"
            high_channel_entry_label.grid(
                row=curr_row, column=0, sticky=tk.W)

            self.high_channel_entry = tk.Spinbox(
                main_frame, from_=0, validate='key',
                to=max(self.ai_info.num_chans - 1, 0),
                validatecommand=(channel_vcmd, '%P'))
            self.high_channel_entry.grid(
                row=curr_row, column=1, sticky=tk.W)
            initial_value = min(self.ai_info.num_chans - 1, 3)
            self.high_channel_entry.delete(0, tk.END)
            self.high_channel_entry.insert(0, str(initial_value))

            curr_row += 1

        self.results_group = tk.LabelFrame(
            self, text="Results", padx=3, pady=3)
        self.results_group.pack(fill=tk.X, anchor=tk.NW, padx=3, pady=3)

        self.results_group.grid_columnconfigure(1, weight=1)

        curr_row = 0
        status_left_label = tk.Label(self.results_group)
        status_left_label["text"] = "Status:"
        status_left_label.grid(row=curr_row, column=0, sticky=tk.W)

        self.status_label = tk.Label(self.results_group)
        self.status_label["text"] = "Idle"
        self.status_label.grid(row=curr_row, column=1, sticky=tk.W)

        curr_row += 1
        index_left_label = tk.Label(self.results_group)
        index_left_label["text"] = "Index:"
        index_left_label.grid(row=curr_row, column=0, sticky=tk.W)

        self.index_label = tk.Label(self.results_group)
        self.index_label["text"] = "-1"
        self.index_label.grid(row=curr_row, column=1, sticky=tk.W)

        curr_row += 1
        count_left_label = tk.Label(self.results_group)
        count_left_label["text"] = "Count:"
        count_left_label.grid(row=curr_row, column=0, sticky=tk.W)

        self.count_label = tk.Label(self.results_group)
        self.count_label["text"] = "0"
        self.count_label.grid(row=curr_row, column=1, sticky=tk.W)

        curr_row += 1
        self.inner_data_frame = tk.Frame(self.results_group)
        self.inner_data_frame.grid(
            row=curr_row, column=0, columnspan=2, sticky=tk.W)

        self.data_frame = tk.Frame(self.inner_data_frame)
        self.data_frame.grid()

        button_frame = tk.Frame(self)
        button_frame.pack(fill=tk.X, side=tk.RIGHT, anchor=tk.SE)

        self.start_button = tk.Button(button_frame)
        self.start_button["text"] = "Start"
        self.start_button["command"] = self.start
        self.start_button.grid(row=0, column=0, padx=3, pady=3)

        self.quit_button = tk.Button(button_frame)
        self.quit_button["text"] = "Quit"
        self.quit_button["command"] = self.master.destroy
        self.quit_button.grid(row=0, column=1, padx=3, pady=3)
Exemple #28
0
class ULCT07(UIExample):
    def __init__(self, master=None):
        super(ULCT07, self).__init__(master)
        # By default, the example detects all available devices and selects the
        # first device listed.
        # If use_device_detection is set to False, the board_num property needs
        # to match the desired board number configured with Instacal.
        use_device_detection = True
        self.board_num = 0

        self.running = False

        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)
            self.ctr_info = self.device_info.get_ctr_info()
            if self.ctr_info.is_supported:
                self.create_widgets()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets(True)

    def update_value(self):
        channel = self.get_channel_num()

        try:
            # Get a value from the device
            value = ul.c_in_32(self.board_num, channel)

            # Display the value
            self.value_label["text"] = str(value)

            # Call this method again until the stop button is pressed (or an
            # error occurs)
            if self.running:
                self.after(100, self.update_value)
        except ULError as e:
            self.stop()
            show_ul_error(e)

    def stop(self):
        self.running = False
        self.start_button["command"] = self.start
        self.start_button["text"] = "Start"

    def start(self):
        self.running = True
        self.start_button["command"] = self.stop
        self.start_button["text"] = "Stop"

        try:
            # Clear the counter
            ul.c_clear(self.board_num, self.get_channel_num())
            # Start updating the counter values
            self.update_value()
        except ULError as e:
            self.stop()
            show_ul_error(e)

    def get_channel_num(self):
        if self.ctr_info.num_chans == 1:
            return self.ctr_info.chan_info[0].channel_num
        try:
            return int(self.channel_entry.get())
        except ValueError:
            return 0

    def validate_channel_entry(self, p):
        if p == '':
            return True
        try:
            value = int(p)
            if value < 0 or value > self.ctr_info.num_chans - 1:
                return False
        except ValueError:
            return False

        return True

    def create_widgets(self):
        '''Create the tkinter UI'''
        self.device_label = tk.Label(self)
        self.device_label.pack(fill=tk.NONE, anchor=tk.NW)
        self.device_label["text"] = ('Board Number ' + str(self.board_num) +
                                     ": " + self.device_info.product_name +
                                     " (" + self.device_info.unique_id + ")")

        main_frame = tk.Frame(self)
        main_frame.pack(fill=tk.X, anchor=tk.NW)

        channel_vcmd = self.register(self.validate_channel_entry)

        curr_row = 0
        if self.ctr_info.num_chans > 1:
            channel_entry_label = tk.Label(main_frame)
            channel_entry_label["text"] = "Channel Number:"
            channel_entry_label.grid(row=curr_row, column=0, sticky=tk.W)

            chan_info_list = self.ctr_info.chan_info
            first_chan = chan_info_list[0].channel_num
            # last_chan = chan_info_list[len(chan_info_list) - 1].channel_num
            last_chan = first_chan
            for chan_info in chan_info_list:
                if chan_info.channel_num >= last_chan:
                    last_chan = chan_info.channel_num
                else:
                    break
            self.channel_entry = tk.Spinbox(main_frame,
                                            from_=first_chan,
                                            to=last_chan,
                                            validate='key',
                                            validatecommand=(channel_vcmd,
                                                             '%P'))
            self.channel_entry.grid(row=curr_row, column=1, sticky=tk.W)

            curr_row += 1

        value_left_label = tk.Label(main_frame)
        value_left_label["text"] = "Value read from selected channel:"
        value_left_label.grid(row=curr_row, column=0, sticky=tk.W)

        self.value_label = tk.Label(main_frame)
        self.value_label.grid(row=curr_row, column=1, sticky=tk.W)

        button_frame = tk.Frame(self)
        button_frame.pack(fill=tk.X, side=tk.RIGHT, anchor=tk.SE)

        self.start_button = tk.Button(button_frame)
        self.start_button["text"] = "Start"
        self.start_button["command"] = self.start
        self.start_button.grid(row=0, column=0, padx=3, pady=3)

        quit_button = tk.Button(button_frame)
        quit_button["text"] = "Quit"
        quit_button["command"] = self.master.destroy
        quit_button.grid(row=0, column=1, padx=3, pady=3)
Exemple #29
0
class CInScan01(UIExample):
    def __init__(self, master=None):
        super(CInScan01, self).__init__(master)
        # By default, the example detects all available devices and selects the
        # first device listed.
        # If use_device_detection is set to False, the board_num property needs
        # to match the desired board number configured with Instacal.
        use_device_detection = True
        self.board_num = 0

        self.min_chan_num = -1
        self.max_chan_num = -1

        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)
            counter_info = self.device_info.get_ctr_info()

            min_chan = next((channel for channel in counter_info.chan_info
                             if channel.type == CounterChannelType.CTRSCAN
                             or channel.type == CounterChannelType.CTRQUAD),
                            None)
            if min_chan is not None:
                self.min_chan_num = min_chan.channel_num

            max_chan = next(
                (channel for channel in reversed(counter_info.chan_info)
                 if channel.type == CounterChannelType.CTRSCAN
                 or channel.type == CounterChannelType.CTRQUAD), None)
            if max_chan is not None:
                self.max_chan_num = max_chan.channel_num

            if self.min_chan_num != -1 and self.max_chan_num != -1:
                self.create_widgets()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets(True)

    def start_scan(self):
        low_chan = self.get_low_channel_num()
        high_chan = self.get_high_channel_num()

        if low_chan > high_chan:
            messagebox.showerror(
                "Error", "Low Channel Number must be greater than or equal "
                "to High Channel Number")
            self.start_button["state"] = tk.NORMAL
            return

        rate = 100
        points_per_channel = 10
        num_channels = high_chan - low_chan + 1
        total_count = points_per_channel * num_channels

        # Allocate a buffer for the scan
        memhandle = ul.win_buf_alloc_32(total_count)

        # Check if the buffer was successfully allocated
        if not memhandle:
            messagebox.showerror("Error", "Failed to allocate memory")
            self.start_button["state"] = tk.NORMAL
            return

        try:
            # Run the scan
            ul.c_in_scan(self.board_num, low_chan, high_chan, total_count,
                         rate, memhandle, 0)

            # Convert the memhandle to a ctypes array
            # Note: the ctypes array will only be valid until win_buf_free
            # is called.
            # A copy of the buffer can be created using win_buf_to_array_32
            # before the memory is freed. The copy can be used at any time.
            array = cast(memhandle, POINTER(c_ulong))

            # Display the values
            self.display_values(array, total_count, low_chan, high_chan)
        except ULError as e:
            show_ul_error(e)
        finally:
            # Free the allocated memory
            ul.win_buf_free(memhandle)
            self.start_button["state"] = tk.NORMAL

    def display_values(self, array, total_count, low_chan, high_chan):
        new_data_frame = tk.Frame(self.results_group)

        channel_text = []

        # Add the headers
        for chan_num in range(low_chan, high_chan + 1):
            channel_text.append("Channel " + str(chan_num) + "\n")

        chan_count = high_chan - low_chan + 1

        # Add (up to) the first 10 values for each channel to the text
        chan_num = low_chan
        for data_index in range(0, min(chan_count * 10, total_count)):
            channel_text[chan_num - low_chan] += str(array[data_index]) + "\n"
            if chan_num == high_chan:
                chan_num = low_chan
            else:
                chan_num += 1

        # Add the labels for each channel
        for chan_num in range(low_chan, high_chan + 1):
            chan_label = tk.Label(new_data_frame, justify=tk.LEFT, padx=3)
            chan_label["text"] = channel_text[chan_num - low_chan]
            chan_label.grid(row=0, column=chan_num - low_chan)

        self.data_frame.destroy()
        self.data_frame = new_data_frame
        self.data_frame.grid()

    def start(self):
        self.start_button["state"] = tk.DISABLED
        self.start_scan()

    def get_low_channel_num(self):
        try:
            return int(self.low_channel_entry.get())
        except ValueError:
            return 0

    def get_high_channel_num(self):
        try:
            return int(self.high_channel_entry.get())
        except ValueError:
            return 0

    def validate_channel_entry(self, p):
        if p == '':
            return True
        try:
            value = int(p)
            if value < self.min_chan_num or value > self.max_chan_num:
                return False
        except ValueError:
            return False

        return True

    def create_widgets(self):
        '''Create the tkinter UI'''
        self.device_label = tk.Label(self)
        self.device_label.pack(fill=tk.NONE, anchor=tk.NW)
        self.device_label["text"] = ('Board Number ' + str(self.board_num) +
                                     ": " + self.device_info.product_name +
                                     " (" + self.device_info.unique_id + ")")

        main_frame = tk.Frame(self)
        main_frame.pack(fill=tk.X, anchor=tk.NW)

        channel_vcmd = self.register(self.validate_channel_entry)

        curr_row = 0
        low_channel_entry_label = tk.Label(main_frame)
        low_channel_entry_label["text"] = "Low Channel Number:"
        low_channel_entry_label.grid(row=curr_row, column=0, sticky=tk.W)

        self.low_channel_entry = tk.Spinbox(main_frame,
                                            from_=self.min_chan_num,
                                            to=self.max_chan_num,
                                            validate='key',
                                            validatecommand=(channel_vcmd,
                                                             '%P'))
        self.low_channel_entry.grid(row=curr_row, column=1, sticky=tk.W)

        curr_row += 1
        high_channel_entry_label = tk.Label(main_frame)
        high_channel_entry_label["text"] = "High Channel Number:"
        high_channel_entry_label.grid(row=curr_row, column=0, sticky=tk.W)

        self.high_channel_entry = tk.Spinbox(main_frame,
                                             from_=self.min_chan_num,
                                             to=self.max_chan_num,
                                             validate='key',
                                             validatecommand=(channel_vcmd,
                                                              '%P'))
        self.high_channel_entry.grid(row=curr_row, column=1, sticky=tk.W)
        initial_value = self.max_chan_num
        self.high_channel_entry.delete(0, tk.END)
        self.high_channel_entry.insert(0, str(initial_value))

        self.results_group = tk.LabelFrame(self,
                                           text="Results",
                                           padx=3,
                                           pady=3)
        self.results_group.pack(fill=tk.X, anchor=tk.NW, padx=3, pady=3)

        self.data_frame = tk.Frame(self.results_group)
        self.data_frame.grid()

        button_frame = tk.Frame(self)
        button_frame.pack(fill=tk.X, side=tk.RIGHT, anchor=tk.SE)

        self.start_button = tk.Button(button_frame)
        self.start_button["text"] = "Start"
        self.start_button["command"] = self.start
        self.start_button.grid(row=0, column=0, padx=3, pady=3)

        quit_button = tk.Button(button_frame)
        quit_button["text"] = "Quit"
        quit_button["command"] = self.master.destroy
        quit_button.grid(row=0, column=1, padx=3, pady=3)
Exemple #30
0
class ULDO02(UIExample):
    def __init__(self, master=None):
        super(ULDO02, self).__init__(master)
        master.protocol("WM_DELETE_WINDOW", self.exit)
        # By default, the example detects all available devices and selects the
        # first device listed.
        # If use_device_detection is set to False, the board_num property needs
        # to match the desired board number configured with Instacal.
        use_device_detection = True
        self.board_num = 0

        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)
            dio_info = self.device_info.get_dio_info()

            # Find the first port that supports output, defaulting to None
            # if one is not found.
            self.port = next((port for port in dio_info.port_info
                              if port.supports_output), None)

            if self.port is not None:
                # If the port is configurable, configure it for output
                if self.port.is_port_configurable:
                    try:
                        ul.d_config_port(self.board_num, self.port.type,
                                         DigitalIODirection.OUT)
                    except ULError as e:
                        show_ul_error(e)

                self.create_widgets()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets(True)

    def exit(self):
        # Set the port to 0 at exit
        try:
            ul.d_out(self.board_num, self.port.type, 0)
        except ULError as e:
            show_ul_error(e)
        self.master.destroy()

    def bit_checkbutton_changed(self, bit_num):
        try:
            # Get the value from the checkbutton
            bit_value = self.bit_checkbutton_vars[bit_num].get()
            # Output the value to the board
            ul.d_bit_out(self.board_num, self.port.type, bit_num, bit_value)
        except ULError as e:
            show_ul_error(e)

    def create_widgets(self):
        '''Create the tkinter UI'''
        self.device_label = tk.Label(self)
        self.device_label.pack(fill=tk.NONE, anchor=tk.NW)
        self.device_label["text"] = ('Board Number ' + str(self.board_num)
                                     + ": " + self.device_info.product_name
                                     + " (" + self.device_info.unique_id + ")")

        main_frame = tk.Frame(self)
        main_frame.pack(fill=tk.X, anchor=tk.NW)

        curr_row = 0
        bit_values_frame = tk.Frame(main_frame)
        bit_values_frame.grid(row=curr_row, column=0, padx=3, pady=3)

        label = tk.Label(bit_values_frame, text="Bit Number:")
        label.grid(row=0, column=0, sticky=tk.W)

        label = tk.Label(bit_values_frame, text="State:")
        label.grid(row=1, column=0, sticky=tk.W)

        # Create Checkbutton controls for each bit
        self.bit_checkbutton_vars = []
        max_bit = min(self.port.num_bits, 8)
        for bit_num in range(0, max_bit):
            bit_label = tk.Label(bit_values_frame, text=str(bit_num))
            bit_label.grid(row=0, column=bit_num + 1)

            var = IntVar(value=-1)
            bit_checkbutton = tk.Checkbutton(
                bit_values_frame, tristatevalue=-1, variable=var,
                borderwidth=0,
                command=lambda n=bit_num:
                self.bit_checkbutton_changed(n))
            bit_checkbutton.grid(row=1, column=bit_num + 1, padx=(5, 0))
            self.bit_checkbutton_vars.append(var)

        button_frame = tk.Frame(self)
        button_frame.pack(fill=tk.X, side=tk.RIGHT, anchor=tk.SE)

        quit_button = tk.Button(button_frame)
        quit_button["text"] = "Quit"
        quit_button["command"] = self.exit
        quit_button.grid(row=0, column=0, padx=3, pady=3)