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)
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)
class DaqInScan02(UIExample): 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) def init_scan_channel_info(self): num_channels = 0 daqi_info = self.device_info.get_daqi_info() supported_channel_types = daqi_info.supported_channel_types # Add analog input channels if available if ChannelType.ANALOG in supported_channel_types: ai_info = self.device_info.get_ai_info() self.resolution = ai_info.resolution self.chan_list.append(0) self.chan_type_list.append(ChannelType.ANALOG) self.gain_list.append(ai_info.supported_ranges[0]) num_channels += 1 if ai_info.num_chans > 1: self.chan_list.append(ai_info.num_chans - 1) self.chan_type_list.append(ChannelType.ANALOG) self.gain_list.append(ai_info.supported_ranges[0]) num_channels += 1 # Add a digital input channel if available if self.device_info.supports_digital_io: chan_type = None if ChannelType.DIGITAL16 in supported_channel_types: chan_type = ChannelType.DIGITAL16 elif ChannelType.DIGITAL8 in supported_channel_types: chan_type = ChannelType.DIGITAL8 elif ChannelType.DIGITAL in supported_channel_types: chan_type = ChannelType.DIGITAL if chan_type is not None: 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) num_channels += 1 # Configure all digital ports for input for port in dio_info.port_info: if port.is_port_configurable: ul.d_config_port(self.board_num, port.type, DigitalIODirection.IN) if self.device_info.supports_counters: chan_type = None if ChannelType.CTR16 in supported_channel_types: chan_type = ChannelType.CTR16 elif ChannelType.CTRBANK0 in supported_channel_types: chan_type = ChannelType.CTRBANK0 elif ChannelType.CTR in supported_channel_types: chan_type = ChannelType.CTR if chan_type is not None: self.chan_list.append(0) self.chan_type_list.append(chan_type) self.gain_list.append(ULRange.NOTUSED) num_channels += 1 self.num_chans = num_channels 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 if self.resolution <= 16: self.memhandle = ul.win_buf_alloc(total_count) else: self.memhandle = ul.win_buf_alloc_32(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: # 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 # or win_buf_to_array_32 before the memory is freed. The copy can # be used at any time. if self.resolution <= 16: # Use the memhandle_as_ctypes_array method for devices with a # resolution <= 16 self.array = cast(self.memhandle, POINTER(c_ushort)) else: # Use the memhandle_as_ctypes_array_32 method for devices with a # resolution > 16 self.array = cast(self.memhandle, POINTER(c_ulong)) 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.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.array chan_count = self.num_chans channel_text = [] # Add a string to the array for each channel for _ in range(0, self.num_chans): channel_text.append("") # If no data has been gathered, don't add data to the labels if curr_count > 1: # 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) chan_num = 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)): channel_text[chan_num] += str(array[data_index]) + "\n" if chan_num == self.num_chans - 1: chan_num = 0 else: chan_num += 1 # Update the labels for each channel for chan_num in range(0, self.num_chans): self.data_labels[chan_num]["text"] = channel_text[chan_num] 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) 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) 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.data_frame = tk.Frame(self.results_group) self.data_frame.grid(row=curr_row, column=0, columnspan=2, sticky=tk.W) chan_header_label = tk.Label( self.data_frame, justify=tk.LEFT, padx=3) chan_header_label["text"] = "Channel:" chan_header_label.grid(row=0, column=0) type_header_label = tk.Label( self.data_frame, justify=tk.LEFT, padx=3) type_header_label["text"] = "Type:" type_header_label.grid(row=1, column=0) range_header_label = tk.Label( self.data_frame, justify=tk.LEFT, padx=3) range_header_label["text"] = "Range:" range_header_label.grid(row=2, column=0) self.data_labels = [] for chan_num in range(0, self.num_chans): column = chan_num + 1 chan_label = tk.Label(self.data_frame, justify=tk.LEFT, padx=3) chan_num_item = self.chan_list[chan_num] if isinstance(chan_num_item, Enum): chan_label["text"] = self.chan_list[chan_num].name else: chan_label["text"] = str(self.chan_list[chan_num]) chan_label.grid(row=0, column=column) type_label = tk.Label(self.data_frame, justify=tk.LEFT, padx=3) type_label["text"] = self.chan_type_list[chan_num].name type_label.grid(row=1, column=column) range_label = tk.Label( self.data_frame, justify=tk.LEFT, padx=3) range_label["text"] = self.gain_list[chan_num].name range_label.grid(row=2, column=column) data_label = tk.Label(self.data_frame, justify=tk.LEFT, padx=3) data_label.grid(row=3, column=column) self.data_labels.append(data_label) 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)
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)
class ULDI03(UIExample): 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) def start_scan(self): rate = 100 count = 1000 # Allocate a buffer for the scan self.memhandle = ul.win_buf_alloc(count) # Check if the buffer was successfully allocated if not self.memhandle: messagebox.showerror("Error", "Failed to allocate memory") self.set_ui_idle_state() return try: # Configure the port (if necessary) if self.port.is_port_configurable: ul.d_config_port(self.board_num, self.port.type, DigitalIODirection.IN) # Run the scan ul.d_in_scan(self.board_num, self.port.type, count, rate, self.memhandle, ScanOptions.BACKGROUND) except ULError as e: show_ul_error(e) self.set_ui_idle_state() return # 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. self.ctypes_array = cast(self.memhandle, POINTER(c_ushort)) # 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.DIFUNCTION) # 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 (or an error # occurs) 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.DIFUNCTION) 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): display_count = 10 array = self.ctypes_array data_text = "" # If no data has been gathered, don't add data to the labels if curr_count > 1: # curr_index points to the start of the last completed data point # 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 - display_count - 1, 0) # Add (up to) the latest 10 values for each channel to the text for data_index in range( first_index, first_index + min(display_count, curr_count)): data_text += hex(array[data_index]) + "\n" self.data_label["text"] = data_text def stop(self): ul.stop_background(self.board_num, FunctionType.DIFUNCTION) 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) 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_label = tk.Label(self.inner_data_frame) self.data_label.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)
class ULDI01(UIExample): def __init__(self, master=None): super(ULDI01, 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) 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), None) if self.port is not None: self.create_widgets() else: self.create_unsupported_widgets() except ULError: self.create_unsupported_widgets() def update_value(self): try: # Get a value from the device value = ul.d_in(self.board_num, self.port.type) # Display the bit values for bit_num in range(0, min(self.port.num_bits, 8)): if (value & (1 << bit_num)) != 0: self.bit_value_labels[bit_num]["text"] = "1" else: self.bit_value_labels[bit_num]["text"] = "0" # Display the raw 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: if self.port.is_port_configurable: ul.d_config_port( self.board_num, self.port.type, DigitalIODirection.IN) except ULError as e: self.stop() show_ul_error(e) return self.update_value() 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, sticky=tk.W) bit_num_left_label = tk.Label(bit_values_frame) bit_num_left_label["text"] = "Bit Number:" bit_num_left_label.grid(row=0, column=0, sticky=tk.W) bit_values_left_label = tk.Label(bit_values_frame) bit_values_left_label["text"] = "Value:" bit_values_left_label.grid(row=1, column=0, sticky=tk.W) self.bit_value_labels = [] for bit_num in range(0, min(self.port.num_bits, 8)): bit_num_label = tk.Label(bit_values_frame) bit_num_label["text"] = str(bit_num) bit_num_label.grid(row=0, column=bit_num + 1, sticky=tk.W) # Create an underlined font and assign it to the label font_underlined = Font(bit_num_label, bit_num_label["font"]) font_underlined["underline"] = True bit_num_label["font"] = font_underlined value_label = tk.Label(bit_values_frame) self.bit_value_labels.append(value_label) value_label.grid(row=1, column=bit_num + 1, sticky=tk.W) curr_row += 1 value_left_label = tk.Label(main_frame) value_left_label["text"] = self.port.type.name + " value read:" 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)
class DaqInScan01(UIExample): def __init__(self, master=None): super(DaqInScan01, 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) def init_scan_channel_info(self): num_channels = 0 daqi_info = self.device_info.get_daqi_info() supported_channel_types = daqi_info.supported_channel_types # Add analog input channels if available if ChannelType.ANALOG in supported_channel_types: ai_info = self.device_info.get_ai_info() self.resolution = ai_info.resolution self.chan_list.append(0) self.chan_type_list.append(ChannelType.ANALOG) self.gain_list.append(ai_info.supported_ranges[0]) num_channels += 1 ai_info = self.device_info.get_ai_info() if ai_info.num_chans > 1: self.chan_list.append(ai_info.num_chans - 1) self.chan_type_list.append(ChannelType.ANALOG) self.gain_list.append(ai_info.supported_ranges[0]) num_channels += 1 # Add a digital input channel if available if self.device_info.supports_digital_io: chan_type = None if ChannelType.DIGITAL16 in supported_channel_types: chan_type = ChannelType.DIGITAL16 elif ChannelType.DIGITAL8 in supported_channel_types: chan_type = ChannelType.DIGITAL8 elif ChannelType.DIGITAL in supported_channel_types: chan_type = ChannelType.DIGITAL if chan_type is not None: 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) num_channels += 1 # Configure all digital ports for input for port in dio_info.port_info: if port.is_port_configurable: ul.d_config_port(self.board_num, port.type, DigitalIODirection.IN) if self.device_info.supports_counters: chan_type = None if ChannelType.CTR16 in supported_channel_types: chan_type = ChannelType.CTR16 elif ChannelType.CTRBANK0 in supported_channel_types: chan_type = ChannelType.CTRBANK0 elif ChannelType.CTR in supported_channel_types: chan_type = ChannelType.CTR if chan_type is not None: self.chan_list.append(0) self.chan_type_list.append(chan_type) self.gain_list.append(ULRange.NOTUSED) num_channels += 1 self.num_chans = num_channels def start_scan(self): rate = 100 points_per_channel = 10 total_count = points_per_channel * self.num_chans # Allocate a buffer for the scan if self.resolution <= 16: memhandle = ul.win_buf_alloc(total_count) else: 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.daq_in_scan(self.board_num, self.chan_list, self.chan_type_list, self.gain_list, self.num_chans, rate, 0, total_count, memhandle, 0) # 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 # or win_buf_to_array_32 before the memory is freed. The copy can # be used at any time. if self.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, total_count) 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): channel_text = [] # Add a string to the array for each channel for _ in range(0, self.num_chans): channel_text.append("") # Add (up to) the first 10 values for each channel to the text chan_num = 0 for data_index in range(0, min(self.num_chans * 10, total_count)): channel_text[chan_num] += str(array[data_index]) + "\n" if chan_num == self.num_chans - 1: chan_num = 0 else: chan_num += 1 # Update the labels for each channel for chan_num in range(0, self.num_chans): self.data_labels[chan_num]["text"] = channel_text[chan_num] def start(self): self.start_button["state"] = tk.DISABLED 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) 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() chan_header_label = tk.Label(self.data_frame, justify=tk.LEFT, padx=3) chan_header_label["text"] = "Channel:" chan_header_label.grid(row=0, column=0) type_header_label = tk.Label(self.data_frame, justify=tk.LEFT, padx=3) type_header_label["text"] = "Type:" type_header_label.grid(row=1, column=0) range_header_label = tk.Label(self.data_frame, justify=tk.LEFT, padx=3) range_header_label["text"] = "Range:" range_header_label.grid(row=2, column=0) self.data_labels = [] for chan_num in range(0, self.num_chans): column = chan_num + 1 chan_label = tk.Label(self.data_frame, justify=tk.LEFT, padx=3) chan_num_item = self.chan_list[chan_num] if isinstance(chan_num_item, Enum): chan_label["text"] = self.chan_list[chan_num].name else: chan_label["text"] = str(self.chan_list[chan_num]) chan_label.grid(row=0, column=column) type_label = tk.Label(self.data_frame, justify=tk.LEFT, padx=3) type_label["text"] = self.chan_type_list[chan_num].name type_label.grid(row=1, column=column) range_label = tk.Label(self.data_frame, justify=tk.LEFT, padx=3) range_label["text"] = self.gain_list[chan_num].name range_label.grid(row=2, column=column) data_label = tk.Label(self.data_frame, justify=tk.LEFT, padx=3) data_label.grid(row=3, column=column) self.data_labels.append(data_label) 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)
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)
class ULDO01(UIExample): def __init__(self, master=None): super(ULDO01, 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 get_data_value(self): try: return int(self.data_value_entry.get()) except ValueError: return 0 def data_value_changed(self, *args): try: # Get the data value data_value = self.get_data_value() # Send the value to the device ul.d_out(self.board_num, self.port.type, data_value) except ULError as e: show_ul_error(e) 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 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) positive_int_vcmd = self.register(validate_positive_int_entry) curr_row = 0 value_label = tk.Label(main_frame) value_label["text"] = "Value:" value_label.grid(row=curr_row, column=0, sticky=tk.W) self.data_value_variable = StringVar() self.data_value_entry = tk.Spinbox( main_frame, from_=0, to=255, textvariable=self.data_value_variable, validate="key", validatecommand=(positive_int_vcmd, "%P")) self.data_value_entry.grid(row=curr_row, column=1, sticky=tk.W) self.data_value_variable.trace("w", self.data_value_changed) 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)
class ULDI06(UIExample): def __init__(self, master=None): super(ULDI06, 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) 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 and port.is_bit_configurable)), None) if self.port is not None: self.create_widgets() else: self.create_unsupported_widgets() except ULError: self.create_unsupported_widgets(True) def update_value(self): try: # Get a value from the device value = ul.d_bit_in(self.board_num, self.port.type, self.port.first_bit) # 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: ul.d_config_bit(self.board_num, self.port.type, self.port.first_bit, DigitalIODirection.IN) except ULError as e: self.stop() show_ul_error(e) return self.update_value() 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 raw_value_left_label = tk.Label(main_frame) raw_value_left_label["text"] = (self.port.type.name + " bit " + str(self.port.first_bit) + " value read:") 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) 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)