Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Where are nidaqmx low level functions?

> This would save people who are forced to migrate to NIDAQmx from having to reinvent the wheel, and would provide a quick way of getting up and running (though I realize it may not be the most run-time efficient way). I believe this would also assuage users who, like me, feel frustrated about having to jump through this particular hoop.
 
 
Yes, that sounds a good idea.
I think the buffer address should be known by the user on some way.
It is very frustrating to be forced by "new" boards and drivers not compatible with old drivers which so many NI users had a lot of work on.
If the buffer was known, many things would be easier.
 
And about the unascaled binary reads, I also think it would be very useful if such functions could return fixed data, not "scaled" data as the customer scales can do to return different meanings (volts, current, temperature...), but linearized or "corrected" by the internal polynomial after auto calibration. The unfixed data as it returns is a bit non sense, not useful without more and more programming work. It makes non sense a new driver imposing much more programming work than the old one.
 
Lavio
 
 
0 Kudos
Message 51 of 62
(1,762 Views)

Thanks Neil for the main.cpp example.
Now things are more clear.

I think the current unscaled binary read functions that return binary numbers (i16) should return "fixed" linearized binary numbers. Or new functions, to keep compatibility with these "raw data non linear" functions already documented. They are not much useful as they are, imposing to the programmers more and more work.

I noticed the example reads binary, fixes them using a polynomial (very good idea to kill offset, drifts and non linearity in one shot) but return floats, what should not be the goal.
When you scale data, to convert it to volts, current, temperature or any other unit, then it shoud return floats after the additional scalling. But binaries (i16 numbers) should be fixed and return binaries (i16 as well) "linearized" to keep compatibility with the Traditional drivers and API.

Lavio

0 Kudos
Message 52 of 62
(1,758 Views)

Because we do not have a series M board (only series E right now) I was not able to test the "fixing" or "scaling" routines and then one last question....a doubt that, after thinking about what NI is doing, raised more clear now.

Using the polynomial returned by the NI functions, does it ONLY "fix" offsets and non linearities or does it ALSO SCALE the binary numbers, returning voltage for example (if the channel was set to read voltage) ??

I need to be sure about this. Probably it is the last thing about this issue, to finalize it (this, because as I wrote, we do not have a M board to test right now and the one we had was delivered to a client).

Thanks, Lavio

 

0 Kudos
Message 53 of 62
(1,726 Views)
Lavio,

As noted in my example the scaling coefficients scale from binary to volts.  It does not apply any additonal custom scales or additional modification.  From the help file:

Device Scaling Coefficients:

Indicates the coefficients of a polynomial equation that NI-DAQmx uses to scale values from the native format of the device to volts. Each element of the array corresponds to a term of the equation. For example, if index two of the array is 4, the third term of the equation is 4x^2. Scaling coefficients do not account for any custom scales or sensors contained by the channel.

The reason that DAQmx does things different in this case is because M-Series does not use the same calibration technique that E-Series does.  It has more to do with the change in hardware (E-Series to M-Series) than the change in software (Traditional NI-DAQ to NI-DAQmx).  The actual binary output of an E-Series is already "calibrated" and no additional calibration is necessary.  Thus to have the same functionality for M-Series the software would actually have to change rather than stay the same.  As I mentioned earlier, by having software calibration with M-Series we can achieve much greater accuracy which is a feature more often requested than that the board doesn't ever change.

Traditional NI-DAQ's inability to adapt to deal with these new hardware architectures is one of the very reasons that we decided to develop NI-DAQmx.  With DAQmx you can scale the data from E-Series and M-Series using the same code.  If we were to implement the same with Traditional DAQ it would have required calling additional functions, or at the very least modifications to customer code, anyway, since the data in the buffer (that is DMAed directly from the board uncalibrated to memory) would be incorrect until scaled into some intermediate buffer.

Having DAQmx return post calibrated binary data is not a completely bad idea, but it is a feature that has not been requested very often.  One reason is customers reading binary data are almost always trying to maximize bandwidth.  Specifically, customers streaming many channels of simultaneous input  to disk would like to get at the data in the most efficient way possible without incurring any scaling penalty.  After the large amount of data is acquired and saved they can later retrieve and scale the data when timing is not so important.

If you feel strongly that this is a feature that should be added to NI-DAQmx feel free to file a product suggestion here:

http://digital.ni.com/applications/psc.nsf/default?OpenForm

I will leave the example of making a intermediate buffer to the community.  I think it is more of a C question than a DAQmx question.

Regards,

Neil S.


Message Edited by Neil S. on 05-08-2008 01:22 PM
0 Kudos
Message 54 of 62
(1,686 Views)
"If you feel strongly that this is a feature that should be added to NI-DAQmx feel free to file a product suggestion here:

http://digital.ni.com/applications/psc.nsf/default?OpenForm"

I would like to file the suggestion. However, NIDAQmx isn't listed under "Select a Product", so I was wondering which product name is least likely to result in my suggestion going into the bit bucket?

"I will leave the example of making a intermediate buffer to the community."

As a matter of interest, how large *is* the community of NIDAQmx programmers? Anyone know?

Finally, could someone tell me what DAQmxSetReadReadAllAvailSamp does and how to use it?

Thanks!
0 Kudos
Message 55 of 62
(1,645 Views)
I'm surprised that NI-DAQmx can't be chosen as a product.  I will have to look into why that is.  Either way, you can file it under an M-Series board such as PCI-6229.  I get assigned the hardware and software product suggestions for Multifunction DAQ.  The DAQmx team reviews these suggestions several times a year when making roadmaps for future releases.

The C Function Help explains the purpose of DAQmxSetReadReadAllAvailSamp:

Specifies whether subsequent read operations read all samples currently available in the buffer or wait for the buffer to become full before reading. NI-DAQmx uses this setting for finite acquisitions and only when the number of samples to read is -1. For continuous acquisitions when the number of samples to read is -1, a read operation always reads all samples currently available in the buffer.

The default setting of this property is False.  This means when you create a finite acquisition and call read with number of samples to read as -1 DAQmx will wait until all finite samples are acquired into the PC buffer before returning rather than returning the samples that are available at the time that the Read is called.

Neil S.



Message Edited by Neil S. on 05-13-2008 08:42 AM
0 Kudos
Message 56 of 62
(1,638 Views)
> As noted in my example the scaling coefficients scale from binary to volts.  It does not apply any additonal custom scales or additional modification.  From the help file:
 
Ok, thanks for this last information. I just needed to be sure, because in fact the function name is about scaling coefficients.
 
 
> Having DAQmx return post calibrated binary data is not a completely bad idea, but it is a feature that has not been requested very often.  One reason is customers reading binary data are almost always trying to maximize bandwidth. 
 
 
As I wrote above, we wantto use the binary reads inside callbacks because it is much more efficient. However... the mess about this stuff is between linearization and scalling.
 
In the E series boards, the binary numbers were already "linearized". In other words, to "scale" it to volts we just had to calculate voltage using a linear proportion between the min and max input ranges.
As I understood, the M series do BOTH things via software using the float reads (applying the coefficients) but does NOT return linear numbers using the binary reads. To linearize AND scale them we need the coefficients. Notice that the binary reads in E-series using Traditional were linear and in NidaqMx are not. This creates a compatibility issue that confuses things.
 
 
My suggestions are:
1- make the address input AI buffer available; this is a must.
2- make better documentation about how to use these coefficents and scaling, as also to avoid the mess between linearization and scaling.
3- make binary read functions linear but not scaled; this is not a must, but then make it clear in documentation that you need the coefficients and how to use them.
4- improve the callback performance; the Traditional runs callbacks 3 to 4 times faster; just make a simple counter task using a callback to increment a global number and you will see that using Traditional it can run at 20KHz and above easily while above 5 KHz Nidamx starts to freeze the machine (an average Athlon AMD running at 2 GHz) sometimes.
 
 
Lavio
 
 
 


Message Edited by Merlin-3 on 05-13-2008 11:58 AM
0 Kudos
Message 57 of 62
(1,626 Views)
Ok... let's try to get some explanation again.
 
We use a callback called as I already wrote in other messages in this thread. The callback function is named FIRE().
On this example, inside the call back if the condition is SHOULD NOT BE RUNNING, we DO NOT READ THE DATA.
THen we logged all error conditions plus some main function calls and got:

... user clicks the start button in out system
ScanOn(1) (14:14:42) ---> function to start the acquisition

MXCriarAITask (14:14:42) ----> it creates the AI task
MXStartInput (14:14:42) ----> it creates and starts our main program to get data using callback and display the data... ok until now
...... here the aquisition is running fine and the data being displayed.......
.... after the aquisition automaticaly ends.....
ScanOff(1) (14:14:52) ----> function to stop de aquisition
MXResetAI (14:14:52) -----> function that STOPs and CLEARs all tasks using the cleartask function... <------------------
Fire with Status<>running ------->>>> oops... more callbacks after we stopped
Fire with Status<>running
Fire with Status<>running
Fire with Status<>running
.... it repeats endlessly...
Fire with Status<>running
AtivarThread(1) (14:15:48) <---- noitce the time; here, the user clicks to start again a second aquisition
ScanOn(1) (14:15:48)
Fire com Status<>running
Fire com Status<>running <------ the old callbacks are still firing, they never stop if we do not read the data??
MXResetAI (14:15:48)
MXCriarAITask (14:15:48)
Fire com Status<>running

[PG39MCSV 3.0.7 NAT: ] DAQmxError(-50103) [IniciarVarredura, StartTask AI]: The specified resource is reserved. The operation could not be completed as specified. (06-Jun-2008 14:15).

Fire com Status<>running
Fire com Status<>running
... it repeats for ever...

 

0 Kudos
Message 58 of 62
(1,497 Views)
Ok... let's try to get some explanation again.
 
We use a callback called as I already wrote in other messages in this thread. The callback function is named FIRE().
On this example, inside the call back if the condition is SHOULD NOT BE RUNNING, we DO NOT READ THE DATA.
THen we logged all error conditions plus some main function calls and got:

... user clicks the start button in out system
ScanOn(1) (14:14:42) ---> function to start the acquisition

MXCriarAITask (14:14:42) ----> it creates the AI task
MXStartInput (14:14:42) ----> it creates and starts our main program to get data using callback and display the data... ok until now
...... here the aquisition is running fine and the data being displayed.......
.... after the aquisition automaticaly ends.....
ScanOff(1) (14:14:52) ----> function to stop de aquisition
MXResetAI (14:14:52) -----> function that STOPs and CLEARs all tasks using the cleartask function... <------------------
Fire with Status<>running ------->>>> oops... more callbacks after we stopped
Fire with Status<>running
Fire with Status<>running
Fire with Status<>running
.... it repeats endlessly...
Fire with Status<>running
AtivarThread(1) (14:15:48) <---- noitce the time; here, the user clicks to start again a second aquisition
ScanOn(1) (14:15:48)
Fire com Status<>running
Fire com Status<>running <------ the old callbacks are still firing, they never stop if we do not read the data??
MXResetAI (14:15:48) <----
MXCriarAITask (14:15:48)
Fire com Status<>running

[PG39MCSV 3.0.7 NAT: ] DAQmxError(-50103) [IniciarVarredura, StartTask AI]: The specified resource is reserved. The operation could not be completed as specified. (06-Jun-2008 14:15).

Fire com Status<>running
Fire com Status<>running
... it repeats for ever...

 

0 Kudos
Message 59 of 62
(1,497 Views)
Let's try to get some explanations please ...
 
We use a callback and did some logs and noticed a illogical thing, not mentioned in the docs:
 
Even after a CLEARTASK() call, there are callbacks firing. Windows late messages? Ok, maybe.
 
But.. if we DO NOT READ THE DATA inside the callback, it keeps fitring for ever.
 
It would be logical to suppose that a cleartask() must stop all tasks and UNRESERVE all resources, including any pendent data in the output buffer to stop any callback firing.
But we logged it and it does not stop.
Then, if we recreate the task and try to start again the same task firing crazy callbacks endlessly, it returns an error: "resource reserved, cannot do it" when calling the starttask() function (not when recreating it, but when starting it).
 
You can tell me I suppose: read the data to empty the buffer even if not necessary and it will stop to fire callbacks.
Ok. But shouldn't a cleartask() stop the callbacks as well??
 
Lavio
 
0 Kudos
Message 60 of 62
(1,497 Views)