I am using LabWindows/CVI 2010 with a USB-6343. I have ten digital inputs connected to port 0 lines 12 - 21. I would like to read these digital inputs when any of them have changed and notify a thread the inputs have changed. I have been trying to use DAQmxCfgChangeDetectionTiming with a DAQmxRegisterSignalEvent that registers a change detection callback. From the callback, I call DAQmxReadDigitalLines to read the inputs and then post a message to the thread.
I just want to read the inputs at the time of the change. I have tried using FiniteSamps and ContSamps. When I read the samples, the DAQmxReadDigitalLines often times out without acquiring all of the samples. I have also tried DAQmxRegisterEveryNSamplesEvent, without the callback for the change detection event, but the every_n_samples callback doesn't seem to be called every time the inputs change.
Here is my code with error handling removed to shorten the post so it may not compile. NUMBER_OF_INPUTS is 10 and NUMBER_OF_SAMPLES_PER_INPUT is 5.
DAQmxCreateTask("", &inputs_task_handle) == 0);
DAQmxCreateDIChan(inputs_task_handle, input_lines, input_names, DAQmx_Val_ChanPerLine);
for (i = 0U; i < NUMBER_OF_INPUTS); ++i) {
DAQmxSetChanAttribute(inputs_task_handle, input_config_table[i].name, DAQmx_DI_InvertLines, 0);
DAQmxSetDIDigFltrEnable(inputs_task_handle, input_config_table[i].name, FALSE);
DAQmxSetDIDigFltrMinPulseWidth(inputs_task_handle, input_config_table[i].name, 0.00512);
DAQmxSetDIDigFltrEnable(inputs_task_handle, input_config_table[i].name, TRUE);
}
DAQmxCfgChangeDetectionTiming(inputs_task_handle, input_lines, input_lines, DAQmx_Val_FiniteSamps, NUMBER_OF_SAMPLES_PER_INPUT);
DAQmxRegisterEveryNSamplesEvent(inputs_task_handle, DAQmx_Val_Acquired_Into_Buffer, NUMBER_OF_SAMPLES_PER_INPUT, 0, input_number_of_samples_callback, NULL) ;
//DAQmxRegisterSignalEvent(inputs_task_handle, DAQmx_Val_ChangeDetectionEvent, 0U, input_change_callback, NULL);
DAQmxSetRefTrigPretrigSamples(inputs_task_handle, NUMBER_OF_SAMPLES_PER_INPUT - 1);
DAQmxStartTask(inputs_task_handle);
bool Perform_Read_Of_BRU_Discrete_Inputs(uInt8 * const d) //lint !e960
{
bool ret = true;
int32 samples_per_chan_read;
int32 bytes_per_sample;
uInt32 available_samples;
if (0 == inputs_task_handle) {
ret = false;
} else {
(void) DAQmxGetReadAvailSampPerChan(inputs_task_handle, &available_samples);
if (DAQmxReadDigitalLines(inputs_task_handle, NUMBER_OF_SAMPLES_PER_INPUT, 1.0, DAQmx_Val_GroupByScanNumber,
d, NUMBER_OF_SAMPLES_PER_INPUT * NUMBER_OF_INPUTS, &samples_per_chan_read, &bytes_per_sample, NULL) < 0) {
ret = (samples_per_chan_read == NUMBER_OF_SAMPLES_PER_INPUT) ? true : false;
}
}
return ret;
}
#if 0
static int32 CVICALLBACK input_change_callback(TaskHandle taskHandle, int32 signalID, void *callbackData) {
uInt8 temp_digital_inputs[NUMBER_OF_SAMPLES_PER_INPUT][NUMBER_OF_INPUTS];
if (Perform_Read_Of_BRU_Discrete_Inputs((uInt8 *) temp_digital_inputs)) {
memcpy(digital_inputs, temp_digital_inputs[NUMBER_OF_SAMPLES_PER_INPUT - 1], NUMBER_OF_INPUTS);
assert(BRU_Discrete_Input_Has_Changed());
}
return 0;
} //lint !e715 !e818
#endif
static int32 CVICALLBACK input_number_of_samples_callback(TaskHandle taskHandle, int32 event_type, uInt32 num_of_samples, void *callbackData) {
uInt8 temp_digital_inputs[NUMBER_OF_SAMPLES_PER_INPUT][NUMBER_OF_INPUTS];
if (Perform_Read_Of_BRU_Discrete_Inputs((uInt8 *) temp_digital_inputs)) {
memcpy(digital_inputs, temp_digital_inputs[NUMBER_OF_SAMPLES_PER_INPUT - 1], NUMBER_OF_INPUTS);
assert(BRU_Discrete_Input_Has_Changed());
}
return 0;
} //lint !e715 !e818