09-17-2008 02:04 PM
Hello NewBe,
Here are a couple thoughts from reading through your posts. If you would like to retain your previous architecture of continually calling a function that checks if there are enough items in the buffer to perform a read, you could make use of the function DAQmxGetReadAvailSampPerChan, which will return to you the number of available samples in a particular channel. You could check the return of this until it matched some value you thought to be enough samples, and then perform the read.
I will admit that I am having a little bit of trouble picturing the architecture of your application, and so apologize if I'm a little off base with my next suggestion. If you would like to make use of the DAQmxRegisterEveryNSamplesEvent function, you could create a struct of the data that you will need to modify within the callback function, and pass this struct by reference to the callback function via the void *callbackData parameter. If this doesn't seem helpful, could you perhaps post some pseudo code, or even the actual code, of the class you are trying to implement this within?
I also thought that I would mention that if you had Measurement Studio, you would have access to a fully object oriented DAQmx API, with examples written specifically for MFC applications.
NickB
National Instruments09-17-2008 06:44 PM
Hi,
Thanks for your response. I had your second thought implemented pretty much the way you were suggesting, but with a little twist to it, in the call back function, I would dispatch to a member function in which I do my reading and processing just for the fact so I can have access to other data members of my class..... I haven't got it to work quite right yet.
By the way, I downloaded a trial version of Measurmeant Studio for VC++, I didn't get any meanigful examples with it though....
I will take a look at your first thought and see if it is a better idea to implement that one.
Thanks
09-17-2008 07:18 PM
Sorry, I meant to give you some idea about the code:
In summary I have an analog Task of 8 chs, and 2 counter tasks, one counter for very tooth of a revolution, and the other counter task for Once per Revolution.
class CCommunication
{
.......
int variable(s); //I have many variables declared here - like 50 of them
int *m_Buffer; // I need this buffer to carry the data after I read NI data and process it, I wanna stuff it in this buffer to use it for the rest of the project
int GetNIDAQData(int *Buffer); //This function is where I read the NI data
......
DAQmxReadBinary16( ...)
DAQmxReadCounterU32(...)..
.....
};
// implementation in .CPP
.......
while(1)
{
.....
int ReturnStringSize = GetNIDAQData(m_Buffer); //function call to come back with Buffer and string size from underneath
.......
//After I filled the m_Buffer from reading NI from the function below, I will pass it on to the rest of the project
......more processing
.......Garph data...
.......etc.....
}
int CCommunication::GetNIDAQData(int *Buffer)
{
if(Buffer is Ready to be Read)
{
DAQmxReadBinary(... 8 chs...)
DAQmxReadCounterU32( .....)
DAQmxReadCounterU32( .....)
........
Process data ....
...........
Buffer[0] = Time;
Buffer[1] = RPM;
Buffer[2] = Max Time;
Buffer[3] = Degrees.
Buffer[4 = AnalogCh1Value;
Buffer[5] = AnalogCh2Value;
....etc .......
}
else
return 0;
}
Q1) In the RegisterEverySamplesEvent function, Do I specify (#of SamplesPerChannel) or Total# of Samples....I currently do SampsPerChannel.
Q2) I am specifying SetInputBufferSize() even though its continuous acquisition, because it fails when the #of samples sepecified to issue the trigger varies and becomes a non-multiple of the buffer size or vice versa (-20777)...Does this make sense?
like I said, I will give your thought #1 a go as well.
09-18-2008 04:06 AM
I apologize for hijacking this thread with my previous question.
A solution to my problem (one that works) is to register a single callback function and to read data from the 4 tasks in that function. This technique is effectively illustrated in the NIDAQmx example "Synchronization\Multi-Device\Continuous AI\ContinuousAI.c".
Francis
09-25-2008 03:55 PM
Hello All,
I wanted to update everyone on the solution to NewBe's issue:
- First, call back function has to be declared as static data member to
match C signature.
- pass the call back function as a reference object
ClassName::&CallbackfunctionName.
- pass "this" pointer for call back argument.
- In the call back function, Dispatch to another data member function
using the access object of call back data which was passed by "this"
pointer.
- In dispched function, you will be able to read NI buffers and have access
to rest of data members.
Thanks to all who participated!
03-25-2015 01:01 PM
Hi, are you able to show this explanation with an example please? I have a problem with using one of the NI callback functions as a member function of a class.
03-26-2015 12:54 PM
Dear pa1409,
In the event that you don't hear back from this post soon, I would recommend starting a new post, since it's been many years since the creation of the post.