def setup_change_detect_callback(lines, callback, timer, names=None): # Since the user may have specified a range of lines (e.g., # 'Dev1/port0/line0:1') or listed each line individually (e.g., # 'Dev1/port0/line0, Dev1/port0/line1'), we need to extract the individual # lines in the task. This allows the callback helper to report the name of # the line on which the event was detected. lines = channel_list(lines, 'digital') if names is not None: if len(names) != len(lines): raise ValueError('Number of names must match number of lines') else: names = lines task = create_task() line_string = ','.join(lines) mx.DAQmxCreateDIChan(task, line_string, '', mx.DAQmx_Val_ChanForAllLines) # Get the current state of the lines so that we know what happened during # the first change detection event. mx.DAQmxStartTask(task) initial_state = read_digital_lines(task, 1) mx.DAQmxStopTask(task) # If we're using change detection timing on the digital lines, there's no # point in reading them in as a hardware-timed buffered task. Given the # event times, we can always reconstruct the state of the line at any given # time. mx.DAQmxCfgChangeDetectionTiming(task, line_string, line_string, mx.DAQmx_Val_ContSamps, 200) mx.DAQmxCfgInputBuffer(task, 0) cb = ChangeDetectionCallbackHelper(names, callback, initial_state, timer) cb_ptr = mx.DAQmxSignalEventCallbackPtr(cb) mx.DAQmxRegisterSignalEvent(task, mx.DAQmx_Val_ChangeDetectionEvent, 0, cb_ptr, None) task._cb_ptr = cb_ptr mx.DAQmxTaskControl(task, mx.DAQmx_Val_Task_Commit) return task