08-31-2016 09:38 PM
I'm having a problem programmatically creating Custom Scales for Analog Input with DAQmx. Here's the background. We're trying to develop a small triaxial sensor for monitoring muscle twitches (it's a Student Project, I'm an "advisor"). We have a Triaxial Accelerometer that puts out voltages proportional to the X, Y, and Z components of acceleration. The Accelerometer runs off a 5v supply, with each channel having a bias (offset) of 1.5v and a gain of 0.3v/g, with about a 10% variability in these parameters (i.e. gain ranges from 0.27 to 0.33 v/g).
We can easily read the three channels of acceleration with an NI USB-6009. In the original "Proof of Concept", we were easily able to measure muscle twitches, but noted that the channels were definitely uncalibrated.
I devised a Calibration Procedure that was quick, robust, and reproducible, requiring measuring the X, Y, Z voltages when the accelerometer was held in six orientation without moving -- the entire process takes 15 seconds. But then, I decided to "get clever" (always a bad sign).
I've never used Custom Scales in DAQmx, but thought "Why not use the Calibration values for the X, Y, and Z axes to programmatically set Custom Scales for the three Axes so everything is in units of "g" and centered around 0g". I had defined a "Triax" Task in my Project -- if I manually entered the Scale Factors deduced from my Calibration, the axes all read between +1g and -1g (depending on orientation) when the sensor was motionless.
But I cannot figure out how to take the Calibration data and programmatically assign each channel its own Custom Scale.
Here's some code. This first Routine finds the Triax Task stored in the Project, and makes sure the the correct USB-6009 is connected. Within the Project Task, I've named the three Physical Channels ai0, ai1, and ai2 to X, Y, and Z, and set the voltage range from 0 to 5 v -- this code basically resets the scaling for these three channels. It seems to work fine.
The reason that I do this is that I want to record these three channels using the standard Volts scaling, as I'll use these voltages to run the Calibration procedure I developed to get the three Bias and Gain settings needed for the Custom Scale.
Here is what I tried to do to create a Custom Scale for the X, Y, and Z channels (the Scales are named X_Scale, Y_Scale, and Z_Scale). I tried a number of things, this is just one of them, but I've not had success getting anything to work (to say nothing of avoiding DAQmx errors). Incidentally, if I enter the Scale Factors "manually", my Accelerometer readings are, indeed, properly scaled between -1g and +1g.
Some of this code may look overly complicated -- trust me, I tried to make it simpler, but there are all kinds of "hidden gotcha's" in some of these functions that "made me do it" this way. But, of course, it doesn't work.
Insights and suggestions are most welcome! I'll continue to work on it, of course (but, fortunately, I didn't bring the device home with me, so I get a little break ...).
Bob "Puzzled" Schor
Solved! Go to Solution.
09-01-2016 09:32 AM
Are you getting "Channel already in use..." type errors?
If not what is the error code/message?
Ben
09-01-2016 10:31 AM
I'll get back to you on that, Ben. It's a little complicated because there are different behaviors if the Project is set up different ways (all of which seem to be "legal", but either just don't work or generate mysterious and illogical errors ...).
Bob Schor
09-01-2016 12:01 PM
09-01-2016 01:36 PM - edited 09-01-2016 01:39 PM
First let me check my understanding. You'd like to have a task where the channel list has 6 elements. The first 3 are the accelerometer X,Y,Z components in unscaled form, the second 3 are the same X,Y,Z components in scaled form. Is that part right? Do the two snippets run back to back, or does other stuff happen in between? The task isn't running when the second snippet runs, is it?
The main thing I see & question is that I don't see the correspondence between the physical channel names you assign to the task in the first snippet and the [X,Y,Z] virtual names you use to identify them one at a time in the second snippet. Either assign the X,Y,Z names in the first snippet or else down in the second snippet query the task to retrieve the channel names outside your loop and auto-index over them.
-Kevin P
P.S. Double dang! That's twice in a row I queued up a thread earlier in the day, failed to refresh before answering, and then gave a redundant answer. (See here.)
09-01-2016 02:00 PM
Sorry for the confusion. Naturally, I'm "making trouble/work for myself", as I could simply "do the conversion myself and to Hades with Custom Scales", but I enjoy exploring the Dark Corners of LabVIEW and DAQmx.
Here's the situation. I've got a LabVIEW Project with a Task called Triax, looking at ai0, ai1, and ai2 (of a USB-6009, at present). While defining the Task, I changed the internal names of the Channels from Voltage_0 to X, Voltage_1 to Y, and Voltage_2 to Z. Most DAQmx functions seem to require the Physical name, which is "Dev1/ai0", but never mind.
I'd like to (learn to) use Custom Scaling so that my X, Y, and Z "numbers" represent acceleration in g's, but before I can do that, I need to calibrate the Accelerometer. For that, I want to get readings without scaling. I can then use those readings to compute the three Custom Scales (which I would call X_Scale, Y_Scale, and Z_Scale) -- these are linear scales whose default (from the manufacturer) form is Accel = 3.333 V/g * Volts -5V -- the actual numbers differ by about 10% from these (nominal) values.
So my idea is to take data without scales, use these data to define three Custom Scales, then apply these Custom Scales to the same three X, Y, and Z channels. I can do this "manually" -- I can run my program, record the acceleration from the (stationary) Accelerometer in six (static) orientations, compute the Custom Scales, go back into the Task and set up Custom Scaling, then do the rest of the study using those Custom Scales (and getting my DAQmx values in units of Gravity, "g"). But I can't figure out how to do this programmatically.
I'll post a bit more code shortly, along with specific error messages.
Bob Schor
09-01-2016 02:03 PM - edited 09-01-2016 02:06 PM
Still sounds like you are trying to add teh same channels to an existing task.
Now if that guy that is always asking for people to post some code... as 2015 ...
Ben
09-01-2016 02:07 PM
@ben64 wrote:I don't know if this will help but in the first snippet you are assigning physical channels to DAQmx Create Virtual Channels.vi but the "name to assign" input is left unconnected. Shouldn't you wire "X,Y,Z" to this input?
As I explain in my previous Post, the Task is defined in the Project, and when I set up the Task, I "renamed" the three Inputs from the default "Voltage_0" to "X" (and similar for Y and Z). Not specifying them appears to be OK in this instance, as nothing untoward happens.
I just went back and read the Help for this function, and I'm now more confused. It says that if you leave it blank (which I did), it uses the Physical names. It also says you can specify multiple channels by using a Comma-separated List, but if I use "X,Y,Z", it throws Error -200489:
DAQmx Create Channel (AI-Voltage-Basic).vi:1780006<append>
<B>Channel Name: </B>X
<B>Task Name: </B>Triaxial
Bob Schor
09-01-2016 02:14 PM
@Ben wrote:Still sounds like you are trying to add teh same channels to an existing task.
Hmm. Maybe I'm trying to "do the impossible". Oh, of course (the light just might have dawned). I was about to say "I'm not trying to add channels to an existing task, I'm trying to change the channels of an existing task. Maybe you can't do that. Maybe what I need to do is the following:
OK, back to the drawing board (actually, back to the Block Diagrams). Hope this is the Root of the Problem ...
Bob Schor
09-01-2016 02:14 PM
And while I am waiting for an update I will rant a bit and tell a sea story.
It was many and many a year ago in a city by the lake that I delvered an large applcation and used the built-in scaling a virtual channels provided by MAX (not DAQmx mind you). Many years latter the customer finally got around to upgrading the machine fro LV 6i to something that used DAQmx.
That is when I was hired to come in and help because the 120 channels all with their own custom scaling completly frustrated him and was a daughnting tasks. Of course there were no tools to make the jump from LV 6i so Ben ahd to figure out the process of getting all of the channel and scaling info out of MAX into DAQmx form. It ws not easy task.
Done with the G-Story and now my view...
When we take what looks to be the easy route an duse some of the NI provided functionality, we are making a bet that it will all work the way we want, and NI will support it going into the future.
While the investigation to learn how to use the DAQmx scaling may be an interesting achedemic question, I will often urge my customers to do the scaling explicitly in LV. This allows us to see the values both in scaled and unscaled form and will also make tasks like "Adsting the calibration live" trivial.
Done with my two cents,
Ben