Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Synchronous events - DAQmxRegisterEveryNSamplesEvent

Hello,

I am writing a data acquisition application using an 18-bit PCI-6281 A/D board, on Windows XP using Borland C++ Builder 6.

The documentation for DAQmxRegisterEveryNSamplesEvent says that if the DAQmx_Val_SynchronousEventCallbacks flag is used, then the event callbacks will occur in the thread that registered the event, if messages are being processed. The "message processing" mention in the documentation seems rather vague to me, since it doesn't describe which Windows messages should be processed. So far I have been unable to find any further documentation or code examples that show how to use synchronous events.

My question is, how can I set up the "message processing" to use synchronous events? Any help would be appreciated.

Thanks very much,
Markus Svilans.
0 Kudos
Message 1 of 15
(3,918 Views)
Hello Markus,

The wording in the Help Manual does seem a little confusing.  The DAQmxRegisterEveryNSamplesEvent creates an interrupt or "message" whenever the N samples are written to the buffer.  DAQmx_Val_SynchronousEventCallbacks synchronizes the interrupt with a call to the callback function.  If you don't set this flag, the callback function will be called by default.  So just setting this flag will process the interrupts synchronously.

Are you having trouble with your callback functions or are you just clarifying?

Regards,
Micaela N
National Instruments
0 Kudos
Message 2 of 15
(3,878 Views)
Hi Micaela,

Forgive me but the wording of your message is also a bit confusing to me. 🙂 I am not sure what you mean about synchronous versus non-synchronous callback execution. Can you please clarify for me?

Can you tell me what I need to do to have the callback execute in a thread of my choosing?

The reason I am asking is that having the callback execute in a different thread (i.e. not the DAQmx thread, but my own data processing thread) would help me integrate the DAQmx hardware with an existing data streaming framework I am using.

Thanks very much,
Markus.

0 Kudos
Message 3 of 15
(3,878 Views)
Hi Markus,

You say you want the callback to happen in your own data processing thread.
 
I need to know, when will this data processing thread be ready to handle new data?  If you want this data processing thread to finish processing whatever it was doing previously and _wait_ for new data to available, then you should just use the regular DAQmx Read function when the thread is ready for new data; not DAQmx events.  This is by far the simplest approach.
 
However, if this thread needs to handle jobs from multiple sources, and you cannot predict what type of job you will need to handle next, then you should use a queue of "jobs".  You can use DAQmx events (either asynchronous or synchronous), and inside the callback, you should add a job to your queue of work so that your thread can then handle the request when it finishes its current task.
 
Neither asynchronous nor synchronous events will call you back on your data processing thread.  One of the two mechanisms calls back on a thread created inside the DAQmx driver.  The other mechanism calls back using the application's main user interface thread.
 
Hope this helps,
Jonathan
 
0 Kudos
Message 4 of 15
(3,856 Views)
Hello Markus,

Actually, I spoke with some of our developers and my understanding of that option was not correct, here's what was explained to me:

Basically, the only thing needed to receive the synchronous messages on a Windows machine is to be processing messages. A message pump is embedded in VC's MFC library and definitely in BC's own vision library.  Therefore, there you to have your UI up and running which will guarantee that Windows messages are being processed and he will receive the callbacks you are registered for.
There are no ANSI C examples for the C API that use synchronous callbacks. Unfortunately, there can't be any because then they wouldn't be ANSI C, they'd have to be VC or BC examples with UI.
 If you are not using this type of environment (that has message processing), you would need to implement your own.  There is no specific message the you needs process. By "processing messages" it is meant that the you needs to be "peeking" all Windows messages, aka running a message pump.  You can continuously process messages by calling something like the following function:

 BOOL PeekMessage(
     LPMSG lpMsg,
     HWND hWnd,
     UINT wMsgFilterMin,
     UINT wMsgFilterMax,
     UINT wRemoveMsg
 );"

 Basically, if you have your thread handling messages, you should only need to call the RegisterEveryNSample Event.  You do not need to process specific messages.

Regards,
Micaela N
National Instruments
0 Kudos
Message 5 of 15
(3,853 Views)
What kind of message does the DAQmxEvent generate?  Is it a thread message?  If so then could I use MsgWaitForMultipleObjects to get the message and decode with Peekmessage?

John

0 Kudos
Message 6 of 15
(3,540 Views)

For example:

 

switch

( MsgWaitForMultipleObjects (1, &pMyEvent, FALSE, INFINITE, QS_ALLEVENTS ) ){

case WAIT_OBJ_DATA_MY_EVENT_HAS_ARRIVED:

/************************************************/

::ResetEvent (myEvent);

Process My Event

/************************************************/

break;

case WAIT_OBJ_WINDOWS_MSG:

while ( PeekMessage ( &msg, NULL, 0, 0, PM_REMOVE ) ){

if ( msg.message == WM_NI_DAQ EVENT??

Process DAQmx Event

break;

}

DispatchMessage (&msg);

}

break;

 

John

0 Kudos
Message 7 of 15
(3,539 Views)
Hi John,

I saw that you created a new thread found here with the same question.  We try to keep questions limited to one thread to make it easier for our customers to search our forums for answers.  We would appreciate it if you would keep your questions and updates regarding this issue to the new thread to avoid confusion.

Thanks,
Paul C.
0 Kudos
Message 8 of 15
(3,519 Views)
Sorry - please see the thread posting above if you wish to reply.
0 Kudos
Message 9 of 15
(3,510 Views)
I am having trouble with callback functions because of this error messages I have logged (it happens when we try to STOP or CLEAR a AI running task):
 
[PG39MCSV 3.0.9 LOG: ] WARN(-200979) [TaskControl MXResetAI]: When you use synchronous events, you can clear, stop, abort, unreserve, or start a task only from the thread in which you registered synchronous events.. (09-jun-2008 21:47:24)
 
The problem is that we use several threads that can start/stop a AI task.
Our software used Traditional and E series boards for almost 10 years but now it is being a nightmare to make it work with Nidaqmx and M boards.
Is there a way to make things easier? This limitation can create big problems to software using several threads.

Also... is this declaration correct?

#define DAQmx_Val_SynchronousEventCallbacks (1<<0) // Synchronous callbacks

I ask because it gives an error in:

ret := DAQmxRegisterEveryNSamplesEvent(taskai,DAQmx_Val_Acquired_Into_Buffer,NSCANS,DAQmx_Val_SynchronousEventCallbacks,x,nil);

It just does not work. The function above accepts only a zero for DAQmx_Val_SynchronousEventCallbacks. Is this right!?

Thanks for help,

Lavio

 

0 Kudos
Message 10 of 15
(3,194 Views)