Counter/Timer

cancel
Showing results for 
Search instead for 
Did you mean: 

using asynchronous timer for data flow control

Hi all,

  I am using system sleep to control the data flow (some digital lines and analog output). The pseudo code is something like this

 

Sleep(150);
// the following sections are exectuted in parallel
  #pragma omp parallel sections
  {
    #pragma omp section
    {
      DAQmxWriteDigitalLines(...); // output TTL to one digitla line
    }
    #pragma omp section
    {
      DAQmxWriteDigitalLines(...); // output TTL to another digitla line     
    }
    #pragma omp section
    {
      Sleep(2); // sleep 2ms
    }
  }

// the following sections are exectuted in parallel
  #pragma omp parallel sections
  {
    #pragma omp section
    {
      DAQmxWriteDigitalLines(...); // output TTL to one digitla line
    }
    #pragma omp section
    {
      DAQmxWriteAnalogScalarF64(...); // analog output to one channel
    }
    #pragma omp section
    {
      Sleep(1); // delay 1ms
    }
  }

// the following sections are exectuted in parallel
  #pragma omp parallel sections
  {
    #pragma omp section
    {
      DAQmxWriteDigitalLines(...); // output TTL to one digitla line
    }
    #pragma omp section
    {
      DAQmxWriteAnalogScalarF64(...); // analog output to one channel
    }   
#pragma omp section
    {
      DAQmxWriteAnalogScalarF64(...); // analog output to another channel
    }
    #pragma omp section
    {
      Sleep(11); // delay 11ms
    }
  }

// ... other stuffs

 

 

I am running windows XP and I know it is not possible to get realtime control but  I want a as precise timing as possible. Above code is not perfect but it works 95% of times. I just read an article about using the asynchronous timer to control the time delay. I try that idea with the following code frame

 


int CVICALLBACK ATCallback(int reserved, int timerId, int event, void *callbackData, int eventData1, int eventData2) { if (event==EVENT_TIMER_TICK) { int *nextdelay = (int *)callbackData; SuspendAsyncTimerCallbacks(); if (timerId>=0) { double time; if (*nextdelay==0) time=2.0; else if (*nextdelay==1) time=1.0; else time=12.0; SetAsyncTimerAttribute(timerId, ASYNC_ATTR_INTERVAL, time); if (*nextdelay==0) { #pragma omp parallel sections { #pragma omp section { DAQmxWriteDigitalLines(...); // output TTL to one digitla line } #pragma omp section { DAQmxWriteDigitalLines(...); // output TTL to another digitla line } } *nextdelay++; } else if (*nextdelay==2) { #pragma omp parallel sections { #pragma omp section { DAQmxWriteDigitalLines(...); // output TTL to one digitla line } #pragma omp section { DAQmxWriteAnalogScalarF64(...); // analog output to one channel } } *nextdelay++; } else if (*nextdelay==3) { #pragma omp parallel sections { #pragma omp section { DAQmxWriteDigitalLines(...); // output TTL to one digitla line } #pragma omp section { DAQmxWriteAnalogScalarF64(...); // analog output to one channel } #pragma omp section { DAQmxWriteAnalogScalarF64(...); // analog output to another channel } } *nextdelay++; } } ResumeAsyncTimerCallbacks(); } return 0; } void main(void) { int n = 0; int timeid; timeid = NewAsyncTimer(120.0/1000.0, 3, 1, ATCallback, &n); }

But it doesn't work. There is no compilation and runtime error but the timing just not right. I wonder do I have to suspend the timer in the callback function when I reset the delay for next call? If I do so, I am worry if it will apply too much delay (since I suspend and resume the timer in the delay) so it will cause even worse timing. But if I don't suspend the timer before I reset the time, what happen if the code running in the callback function not finished before the next callback arrive. It is quite confusing how to use asynchronous timer in this case. Thanks.

 

 

0 Kudos
Message 1 of 4
(5,748 Views)

Why not write the data to an output buffer and clock it out using a hardware sample clock?  What DAQ hardware are you using?

 

 

Best Regards,

John Passiak
0 Kudos
Message 2 of 4
(5,726 Views)

@John_P1 wrote:

Why not write the data to an output buffer and clock it out using a hardware sample clock?  What DAQ hardware are you using?

 

 

Best Regards,


Hi John, I am using 6711. I also thought to use clock but I have to synchronize at least 3 digital lines and 2 analog channels. As my understanding, to output a digital TTL based on a clock, I need to use counter instead. And using counter means we gotta output a pulse (rising and falling edge), right? Almost all counters pin are used and I don't know if it is possible to clock the output of the a signl TTL via digital line.

0 Kudos
Message 3 of 4
(5,723 Views)

Yeah, unfortunately the 6711 doesn't have clocked digital I/O.  There are only two counters anyway so even if you could use them to generate your signals you wouldn't have enough (*maybe* something with the 4 AO channels and a counter depending on what your output signals need to look like?  The AO channels can output "digital" as well if you write 0V or 5V only).

 

A PCI DAQ card which does support clocked digital I/O and has 2 analog outputs is the 6221 (or if you could use PCIe the 6321 is a more updated version with two extra counters and some additional functionality).

 

If there isn't a way to implement clocked outputs afterall, one thing you could do to make your code a little more efficient is to consolidate the writes.  You can put your digital lines into a single task and write them at ocne, and you can put your analog channels into a single task and write them at once as well.

 

I'm not sure about the callback issue, you might find some more help in the CVI forum.  I don't think it's going to solve your underlying problem though as ultimately the execution timing of your software calls is at the mercy of your OS.

 

 

Best Regards,

John Passiak
0 Kudos
Message 4 of 4
(5,706 Views)