Jane_neurophys
2008-08-14 19:10:12 UTC
Hello,I am using an M Series board, PCI-6259, to detect changes in multiple digital input lines, store each change and also store a time stamp for each. I am using a C program and DAQmx function calls. I would like to use this to record the times of events associated with neurophysiological data. I created 3 tasks. The first one configures change detection for the digital input lines, and exports the signal that is generated upon each change, to RTSI2. The second task uses counter 0 to create digital pulses at a frequency of 20 MHz, using DAQmxCreateCOPulseChanFreq. The third task uses counter 1 to count the edges that come from the pulses of counter 0, using DAQmxCreateCICountEdgesChan. It uses the signal from RTSI2 as its sample clock, so that it records the number of edges so far from counter 0 each time there is a change detected on one of the digital i/o lines. Here is part of the C code: DAQmxErrChk (DAQmxCreateTask("tasknumb1",&taskHandle));
DAQmxErrChk (DAQmxCreateDIChan(taskHandle,"Dev2/port0","",DAQmx_Val_ChanForAllLines));
DAQmxErrChk (DAQmxCfgChangeDetectionTiming(taskHandle,"Dev2/port0","Dev2/port0",DAQmx_Val_FiniteSamps ,40));
DAQmxErrChk (DAQmxExportSignal (taskHandle, DAQmx_Val_ChangeDetectionEvent , "RTSI2"));
DAQmxErrChk (DAQmxCreateTask("tasknumb2",&taskHandle2));
DAQmxErrChk (DAQmxCreateCOPulseChanFreq(taskHandle2,"Dev2/ctr0","",DAQmx_Val_Hz,DAQmx_Val_Low,0.0,20000000.00,0.5));
DAQmxErrChk (DAQmxCfgImplicitTiming(taskHandle2,DAQmx_Val_ContSamps,5000));
DAQmxErrChk (DAQmxCreateTask("tasknumb3",&taskHandle3));
DAQmxErrChk (DAQmxCreateCICountEdgesChan(taskHandle3,"Dev2/ctr1","",DAQmx_Val_Rising,0,DAQmx_Val_CountUp));
DAQmxErrChk (DAQmxSetCICountEdgesTerm(taskHandle3,"Dev2/ctr1","/dev2/Ctr0InternalOutput"));
DAQmxErrChk (DAQmxCfgSampClkTiming(taskHandle3,"RTSI2",50000.0,DAQmx_Val_Rising,DAQmx_Val_FiniteSamps,40));I provided changing states to 2 of the digital inputs -- line 0 and line 3, using external signal generators. Here, a 32-bit digital read of the change detection task buffer will result ina value of 1 if line 0 were in a high TTL state, and a value of 8 if line 3 were in a high state, and a value of 9 if lines 0 and 3 were both in a high state. I used a fairly slow input signal on the digital input lines -- a 250 Hz square wave, so there were 4 msec between rising edges, and it had a duty cycle of .25. (1 msec high, 3 msec low) It seems to work fine to detect changes of state and timestamp them, provided the changes occur at different times on the 2 input lines. However, as a test, I connected the same input signal to lines 0 and 3 (just using a BNC 'T' connection), and expected changes with both linesgoing high and low simultaneously. (That is, the task buffer would contain 0, 9, 0, 9, etc.) It does this, but fairly often it records a separate change of state for each line. (ie, values of 1 or 8) However, the input on counter 1 only seems to get a single sample clock pulse in these instances, because it only stores a single value for its edge counting input. Here is an example of some input data. First, a buffer of times, in seconds: 0.002935
0.0039380.006933
0.007937
0.010932
0.011935
0.014930
0.015934
0.0189290.019933
0.022928
..0.031929
0.034924
0.035927
0.038922 And the corresponding events read from the change detection buffer: buffer[0] = 9
[1]
DAQmxErrChk (DAQmxCreateDIChan(taskHandle,"Dev2/port0","",DAQmx_Val_ChanForAllLines));
DAQmxErrChk (DAQmxCfgChangeDetectionTiming(taskHandle,"Dev2/port0","Dev2/port0",DAQmx_Val_FiniteSamps ,40));
DAQmxErrChk (DAQmxExportSignal (taskHandle, DAQmx_Val_ChangeDetectionEvent , "RTSI2"));
DAQmxErrChk (DAQmxCreateTask("tasknumb2",&taskHandle2));
DAQmxErrChk (DAQmxCreateCOPulseChanFreq(taskHandle2,"Dev2/ctr0","",DAQmx_Val_Hz,DAQmx_Val_Low,0.0,20000000.00,0.5));
DAQmxErrChk (DAQmxCfgImplicitTiming(taskHandle2,DAQmx_Val_ContSamps,5000));
DAQmxErrChk (DAQmxCreateTask("tasknumb3",&taskHandle3));
DAQmxErrChk (DAQmxCreateCICountEdgesChan(taskHandle3,"Dev2/ctr1","",DAQmx_Val_Rising,0,DAQmx_Val_CountUp));
DAQmxErrChk (DAQmxSetCICountEdgesTerm(taskHandle3,"Dev2/ctr1","/dev2/Ctr0InternalOutput"));
DAQmxErrChk (DAQmxCfgSampClkTiming(taskHandle3,"RTSI2",50000.0,DAQmx_Val_Rising,DAQmx_Val_FiniteSamps,40));I provided changing states to 2 of the digital inputs -- line 0 and line 3, using external signal generators. Here, a 32-bit digital read of the change detection task buffer will result ina value of 1 if line 0 were in a high TTL state, and a value of 8 if line 3 were in a high state, and a value of 9 if lines 0 and 3 were both in a high state. I used a fairly slow input signal on the digital input lines -- a 250 Hz square wave, so there were 4 msec between rising edges, and it had a duty cycle of .25. (1 msec high, 3 msec low) It seems to work fine to detect changes of state and timestamp them, provided the changes occur at different times on the 2 input lines. However, as a test, I connected the same input signal to lines 0 and 3 (just using a BNC 'T' connection), and expected changes with both linesgoing high and low simultaneously. (That is, the task buffer would contain 0, 9, 0, 9, etc.) It does this, but fairly often it records a separate change of state for each line. (ie, values of 1 or 8) However, the input on counter 1 only seems to get a single sample clock pulse in these instances, because it only stores a single value for its edge counting input. Here is an example of some input data. First, a buffer of times, in seconds: 0.002935
0.0039380.006933
0.007937
0.010932
0.011935
0.014930
0.015934
0.0189290.019933
0.022928
..0.031929
0.034924
0.035927
0.038922 And the corresponding events read from the change detection buffer: buffer[0] = 9
[1]