Exemplo n.º 1
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)
Exemplo n.º 2
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)
Exemplo n.º 3
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)
Exemplo n.º 4
0
class VOut01(UIExample):
    def __init__(self, master=None):
        super(VOut01, 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_v_out:
                self.create_widgets()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets(True)

    def update_value(self):
        channel = self.get_channel_num()
        ao_range = self.ao_info.supported_ranges[0]
        data_value = self.get_data_value()

        try:
            # Send the value to the device (optional parameter omitted)
            ul.v_out(self.board_num, channel, ao_range, data_value)
        except ULError as e:
            show_ul_error(e)

    def get_data_value(self):
        try:
            return float(self.data_value_entry.get())
        except ValueError:
            return 0

    def get_channel_num(self):
        if self.ao_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.ao_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)
        float_vcmd = self.register(validate_float_entry)

        curr_row = 0
        if self.ao_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)

            self.channel_entry = tk.Spinbox(
                main_frame, from_=0, to=max(self.ao_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

        data_value_label = tk.Label(main_frame)
        data_value_label["text"] = "Value (V):"
        data_value_label.grid(row=curr_row, column=0, sticky=tk.W)

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

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

        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.master.destroy
        quit_button.grid(row=0, column=0, padx=3, pady=3)
Exemplo n.º 5
0
class DaqOutScan01(UIExample):
    def __init__(self, master=None):
        super(DaqOutScan01, 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_chans = 2
        self.chan_list = []
        self.chan_type_list = []
        self.gain_list = []

        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)
            if self.device_info.supports_daq_output:
                self.ao_info = self.device_info.get_ao_info()
                self.init_scan_channel_info()
                self.create_widgets()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets(True)

    def init_scan_channel_info(self):
        daqo_info = self.device_info.get_daqo_info()
        supported_channel_types = daqo_info.supported_channel_types

        # Add an analog output channel
        self.chan_list.append(0)
        self.chan_type_list.append(ChannelType.ANALOG)
        self.gain_list.append(self.ao_info.supported_ranges[0])

        # Add a digital output channel
        if ChannelType.DIGITAL16 in supported_channel_types:
            chan_type = ChannelType.DIGITAL16
        elif ChannelType.DIGITAL8 in supported_channel_types:
            chan_type = ChannelType.DIGITAL8
        else:
            chan_type = ChannelType.DIGITAL

        dio_info = self.device_info.get_dio_info()
        port_info = dio_info.port_info[0]
        self.chan_list.append(port_info.type)
        self.chan_type_list.append(chan_type)
        self.gain_list.append(ULRange.NOTUSED)

        # Configure all digital ports for output
        for port in dio_info.port_info:
            if port.is_port_configurable:
                ul.d_config_port(self.board_num, port.type,
                                 DigitalIODirection.OUT)

    def start_scan(self):
        # Build the data array
        points_per_channel = 1000
        rate = 1000
        num_points = self.num_chans * points_per_channel
        scan_options = ScanOptions.BACKGROUND | ScanOptions.CONTINUOUS
        ao_range = self.ao_info.supported_ranges[0]

        self.memhandle = ul.win_buf_alloc(num_points)
        # 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:
            data_array = cast(self.memhandle, POINTER(c_ushort))
            freq = self.add_example_data(data_array, ao_range, rate,
                                         points_per_channel)
            self.freq_label["text"] = str(freq) + "Hz"

            ul.daq_out_scan(self.board_num, self.chan_list,
                            self.chan_type_list, self.gain_list,
                            self.num_chans, rate, num_points, self.memhandle,
                            scan_options)

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

    def add_example_data(self, data_array, ao_range, rate, points_per_channel):
        # Calculate a frequency that will work well with the size of the array
        freq = rate / points_per_channel

        # 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 for the analog channel, and square
        # wave data for all bits on the digital port.
        data_index = 0
        for point_num in range(0, points_per_channel):
            # Generate a value in volts for output from the analog channel
            value_volts = amplitude * math.sin(
                2 * math.pi * freq * point_num / rate) + y_offset
            # Convert the volts to counts
            value_count = ul.from_eng_units(self.board_num, ao_range,
                                            value_volts)
            data_array[data_index] = value_count
            data_index += 1

            # Generate a value for output from the digital port
            if point_num < points_per_channel / 2:
                data_array[data_index] = 0
            else:
                data_array[data_index] = 0xFFFF
            data_index += 1

        return freq

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

        # Display the status info
        self.update_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_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.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 stop(self):
        ul.stop_background(self.board_num, FunctionType.DAQOFUNCTION)

    def exit(self):
        self.stop()
        self.master.destroy()

    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)

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

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

        self.status_label = tk.Label(results_frame)
        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(results_frame)
        index_left_label["text"] = "Index:"
        index_left_label.grid(row=curr_row, column=0, sticky=tk.W)

        self.index_label = tk.Label(results_frame)
        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(results_frame)
        count_left_label["text"] = "Count:"
        count_left_label.grid(row=curr_row, column=0, sticky=tk.W)

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

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

        self.freq_label = tk.Label(results_frame)
        self.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)

        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.exit
        quit_button.grid(row=0, column=1, padx=3, pady=3)
Exemplo n.º 6
0
class ULAO04(UIExample):
    def __init__(self, master=None):
        super(ULAO04, 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 start_scan(self):
        # Build the data array
        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

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

        self.memhandle = ul.scaled_win_buf_alloc(num_points)

        # 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:
            data_array = cast(self.memhandle, POINTER(c_double))
            frequencies = self.add_example_data(data_array, ao_range,
                                                self.num_chans, rate,
                                                points_per_channel)

            self.recreate_freq_frame()
            self.display_signal_info(frequencies)

            ul.a_out_scan(self.board_num, self.low_chan, self.high_chan,
                          num_points, rate, ao_range, self.memhandle,
                          scan_options)

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

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

    def add_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_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_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_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.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 recreate_freq_frame(self):
        low_chan = self.low_chan
        high_chan = self.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(self):
        ul.stop_background(self.board_num, FunctionType.AOFUNCTION)

    def exit(self):
        self.stop()
        self.master.destroy()

    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.ao_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.ao_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.ao_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.ao_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.ao_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,
                to=max(self.ao_info.num_chans - 1, 0),
                validate='key',
                validatecommand=(channel_vcmd, '%P'))
            self.high_channel_entry.grid(row=curr_row, column=1, sticky=tk.W)
            initial_value = min(self.ao_info.num_chans - 1, 3)
            self.high_channel_entry.delete(0, tk.END)
            self.high_channel_entry.insert(0, str(initial_value))

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

        scan_info_group.grid_columnconfigure(1, weight=1)

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

        self.status_label = tk.Label(scan_info_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(scan_info_group)
        index_left_label["text"] = "Index:"
        index_left_label.grid(row=curr_row, column=0, sticky=tk.W)

        self.index_label = tk.Label(scan_info_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(scan_info_group)
        count_left_label["text"] = "Count:"
        count_left_label.grid(row=curr_row, column=0, sticky=tk.W)

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

        curr_row += 1
        self.freq_inner_frame = tk.Frame(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.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.exit
        quit_button.grid(row=0, column=1, padx=3, pady=3)
Exemplo n.º 7
0
class ULGT03(UIExample):
    def __init__(self, master):
        super(ULGT03, self).__init__(master)
        self.board_num = 0

        self.max_board_num = ul.get_config(InfoType.GLOBALINFO, 0, 0,
                                           GlobalInfo.NUMBOARDS)
        self.create_widgets()
        self.update_board_info()

    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

    def get_ad_info(self):
        result = ''
        if self.device_info.supports_analog_input:
            ai_info = self.device_info.get_ai_info()
            result = ("Number of A/D channels: " + str(ai_info.num_chans) +
                      "\n")
        return result

    def get_temperature_info(self):
        result = ''
        if self.device_info.supports_temp_input:
            ai_info = self.device_info.get_ai_info()
            result = ("Number of Temperature channels: " +
                      str(ai_info.num_temp_chans) + "\n")
        return result

    def get_da_info(self):
        result = ''
        if self.device_info.supports_analog_output:
            ao_info = self.device_info.get_ao_info()
            result = ("Number of D/A channels: " + str(ao_info.num_chans) +
                      "\n")
        return result

    def get_digital_info(self):
        result = ''
        if self.device_info.supports_digital_io:
            dio_info = self.device_info.get_dio_info()
            for port_num in range(len(dio_info.port_info)):
                result += ("Digital Port #" + str(port_num) + ": " +
                           str(dio_info.port_info[port_num].num_bits) +
                           " bits\n")
        return result

    def get_counter_info(self):
        result = ''
        if self.device_info.supports_counters:
            ctr_info = self.device_info.get_ctr_info()
            result = ("Number of counter devices: " + str(ctr_info.num_chans) +
                      "\n")
        return result

    def get_expansion_info(self):
        result = ''
        if self.device_info.num_expansions > 0:
            for exp_info in self.device_info.exp_info:
                result += ("A/D channel " + str(exp_info.mux_ad_chan) +
                           " connected to EXP (device ID=" +
                           str(exp_info.board_type) + ").\n")
        return result

    def board_num_changed(self, *args):
        try:
            self.board_num = int(self.board_num_variable.get())
            self.update_board_info()
        except ValueError:
            self.board_num = 0

    def create_widgets(self):
        '''Create the tkinter UI'''
        main_frame = tk.Frame(self)
        main_frame.pack(fill=tk.X, anchor=tk.NW)

        positive_int_vcmd = self.register(validate_positive_int_entry)

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

        self.board_num_variable = StringVar()
        board_num_entry = tk.Spinbox(main_frame,
                                     from_=0,
                                     to=self.max_board_num,
                                     textvariable=self.board_num_variable,
                                     validate="key",
                                     validatecommand=(positive_int_vcmd, "%P"))
        board_num_entry.grid(row=0, column=1, sticky=tk.W)
        self.board_num_variable.trace("w", self.board_num_changed)

        info_groupbox = tk.LabelFrame(self, text="Board Information")
        info_groupbox.pack(fill=tk.X, anchor=tk.NW, padx=3, pady=3)

        self.info_label = tk.Label(info_groupbox,
                                   justify=tk.LEFT,
                                   wraplength=400)
        self.info_label.grid()

        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.master.destroy
        quit_button.grid(row=0, column=0, padx=3, pady=3)
Exemplo n.º 8
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
    memhandle = None

    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()

        low_chan = 0
        high_chan = min(3, ao_info.num_chans - 1)
        num_chans = high_chan - low_chan + 1

        rate = 100
        points_per_channel = 1000
        total_count = points_per_channel * num_chans

        ao_range = ao_info.supported_ranges[0]

        # Allocate a buffer for the scan
        memhandle = ul.win_buf_alloc(total_count)
        # Convert the 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
        # before the memory is freed. The copy can be used at any time.
        ctypes_array = cast(memhandle, POINTER(c_ushort))

        # Check if the buffer was successfully allocated
        if not memhandle:
            raise Exception('Error: Failed to allocate memory')

        frequencies = add_example_data(board_num, ctypes_array, ao_range,
                                       num_chans, rate, points_per_channel)

        for ch_num in range(low_chan, high_chan + 1):
            print('Channel', ch_num, 'Output Signal Frequency:',
                  frequencies[ch_num - low_chan])

        # Start the scan
        ul.a_out_scan(board_num, low_chan, high_chan, total_count, rate,
                      ao_range, memhandle, ScanOptions.BACKGROUND)

        # Wait for the scan to complete
        print('Waiting for output scan to complete...', end='')
        status = Status.RUNNING
        while status != Status.IDLE:
            print('.', end='')

            # Slow down the status check so as not to flood the CPU
            sleep(0.5)

            status, _, _ = ul.get_status(board_num, FunctionType.AOFUNCTION)
        print('')

        print('Scan completed successfully')
    except Exception as e:
        print('\n', e)
    finally:
        if memhandle:
            # Free the buffer in a finally block to prevent a memory leak.
            ul.win_buf_free(memhandle)
        if use_device_detection:
            ul.release_daq_device(board_num)
Exemplo n.º 9
0
class MCCDAQ(dev.Device):
    __registered_board_nums = []
    __memhandles = []

    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))

    def channel(self, channel_idx):
        return self.channels[channel_idx]

#   def analog_out(self, channel_generators: dict, sample_range: range):
#       channels    = channel_generators.keys
#       generators  = channel_generators.values
#       low_chan    = min(channels)
#       high_chan   = max(channels)
#       num_chans   = high_chan - low_chan + 1
#       num_samples = min(self.buffer_size,
#                         num_chans * len(sample_range))
#       # Generate D/A data:
#       data_index  = 0
#       for t in sample_range[:points_per_channel]:
#           for channel_idx in channels:
#               self.cdata[data_index] = generators[channel_idx]
#
#       # Send data to D/A:
#       ul.a_out_scan(board_num  = self.board_num,
#                     low_chan   = low_chan,
#                     high_chan  = high_chan,
#                     num_points = num_samples,
#                     rate       = self.sampling.frequency,
#                     ul_range   = self.ao_range,
#                     memhandle  = self.memhandle,
#                     options    = ( enums.ScanOptions.BACKGROUND |
#                                    enums.ScanOptions.CONTINUOUS |
#                                    enums.ScanOptions.RETRIGMODE )

    @classmethod
    def discover(cls):
        device_enumeration: list

        board_num = 0
        board_index = 0
        for dev_handle in ul.get_daq_device_inventory(InterfaceType.ANY):
            board_num = board_index
            board_index = board_index + 1
            device_enumeration.append(
                MCCDAQ(board_num=board_num,
                       dev_handle=dev_handle,
                       sampling=params.Sampling(frequency=100,
                                                sample_range={0, 255})))

        return device_enumeration