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_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_props.available_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.start_button["state"] = tk.NORMAL return try: data_array = self.memhandle_as_ctypes_array_scaled( self.output_memhandle) 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: self.show_ul_error(e) self.set_ui_idle_state() return
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 apply_and_listen(waveform_1d, nzeros_front, nzeros_back, in_channel_start=0, in_channel_end=0, out_channel_start=0, out_channel_end=0, rate=1000000, board_number=0, ul_range=ULRange.BIP10VOLTS, quiet=False, **kwargs): """ Apply a waveform and listen to collect data. Simultaneous output and collection of data. args: waveform_1d (numpy.array): Serialized waveform nzeros_front (int): Number of zeros padding front of waveform nzeros_back (int): Number of zeros padding back of waveform in_channel_start (int= 0): Specify which start channel to use when listening and collecting incoming waveform. in_channel_end (int= 0): Specify which end channel to use when listening and collecting incoming waveform. out_channel_start (int= 0): Specify which start channel to use when outputting the waveform. out_channel_end (int = 0): Specify which end channel to use when outputting waveform. rate (int = 1000000): Rate for daq board_number (int = 0): ul_range (ULRange): Range for daq quiet (bool): Specify verbosity returns: (memhandle_in, memhandle_out, data_array_in, data_array_out, count_in, time) waveform_1d should be serialized into 1d for all channels output comes on channels continuous from out_channel_start to out_channel_end return: memhandle_in, memhandle_out, data_array_in, data_array_out, count_in """ count_out = len(waveform_1d) nchannel_out = out_channel_end - out_channel_start + 1 nchannel_in = in_channel_end - in_channel_start + 1 rate = int(rate / nchannel_in) len_data_without_zeros = (len(waveform_1d) - nzeros_front - nzeros_back) period_of_wf = (int(len_data_without_zeros / nchannel_out) / rate) if not quiet: print('period:', period_of_wf * 1e6, 'us') trigger_rate = int((count_out - nzeros_front - nzeros_back) / nchannel_out) # Allocate the buffer and cast it to an unsigned short memhandle_out = ul.win_buf_alloc(count_out) data_array_out = ctypes.cast(memhandle_out, ctypes.POINTER( ctypes.c_ushort)) #data_array now points to the correct memory # Calculate and store the waveform in Windows buffer for i, y in enumerate(waveform_1d): data_array_out[i] = int(y) count_in = int(nchannel_in * count_out / (nchannel_out)) memhandle_in = ul.win_buf_alloc(count_in) data_array_in = ctypes.cast(memhandle_in, ctypes.POINTER(ctypes.c_ushort)) options = (None, ) # Output the waveform #import pdb; pdb.set_trace() ul.a_in_scan(board_number, in_channel_start, in_channel_end, count_in, rate, ul_range, memhandle_in, ScanOptions.EXTTRIGGER | ScanOptions.BACKGROUND) ul.a_out_scan(board_number, out_channel_start, out_channel_end, count_out, rate, ul_range, memhandle_out, ScanOptions.EXTTRIGGER | ScanOptions.BACKGROUND) ul.pulse_out_start(0, 0, rate, 0.5) while ul.get_status( 0, FunctionType.AOFUNCTION).status != 0: #poor mans foreground continue ul.pulse_out_stop(0, 0) ul.stop_background(0, FunctionType.AOFUNCTION) ul.stop_background(0, FunctionType.AIFUNCTION) timestep = period_of_wf / len_data_without_zeros time = [] for i in range(int(count_out / nchannel_out)): shiftedi = i - nzeros_front time.append(shiftedi * timestep) time = np.array(time) return memhandle_in, memhandle_out, data_array_in, data_array_out, count_in, time
def run_example(): board_num = 0 if use_device_detection: ul.ignore_instacal() if not util.config_first_detected_device(board_num): print("Could not find device.") return ao_props = AnalogOutputProps(board_num) if ao_props.num_chans < 1: util.print_unsupported_example(board_num) return low_chan = 0 high_chan = min(3, ao_props.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_props.available_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 = util.memhandle_as_ctypes_array(memhandle) # Check if the buffer was successfully allocated if not memhandle: print("Failed to allocate memory.") return 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 " + str(ch_num) + " Output Signal Frequency: " + str(frequencies[ch_num - low_chan])) try: # 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 time.sleep(0.5) status, _, _ = ul.get_status(board_num, FunctionType.AOFUNCTION) print("") print("Scan completed successfully.") except ULError as e: util.print_ul_error(e) finally: # Free the buffer in a finally block to prevent errors from causing # a memory leak. ul.win_buf_free(memhandle) if use_device_detection: ul.release_daq_device(board_num)
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)