09-06-2006 12:23 PM
Task.AIChannels.CreateVoltageChannel(ChannelLabel,
"Voltage", AITerminalConfiguration.Differential, -ADRange, ADRange, AIScale)The problem occurs when the ChannelLabel is the same as the auto-generated one made by the Assistant. (Example: Dev1/ai1 right now). In addition, the range and MAX scale will change. (For the same physical sensor I have four scales plus I want the option of looking directly at the voltage. ) My UI presents user with choices for ADRange, MAX scale name, and physical channel to use.
Can I change the channel label, max, min voltages, scale being used on an existing task? If not then how do I have to start from scratch to create everything and abandon using the DAQ Assistant? (Not very pleasant, it seems)
09-07-2006 03:31 PM
Hi Steve,
It sounds like you are getting the exception because you are re-creating an entire channel instead of modifying the properties of the existing channel. If you add the line of code "Task.AIChannels.CreateVoltageChannel(ChannelLabel, "Voltage", AITerminalConfiguration.Differential, -ADRange, ADRange, AIScale)" to the DaqTask.User.vb OnTaskCreated subroutine, this is a duplication of code. This channel was already created elsewhere in your code by means of the DAQ Assistant. You are getting an exception that refers to the ChannelLabel because Visual Studio thinks you are tyring to create another task from the same physical channel.
If you are trying to modify the properties of an existing task, say for example the maximum value (set to 10V), you would need to add the following code to the DaqTask.User.vb OnTaskCreated subroutine:
Task.AIChannels.All.Maximum = 10
A similar line of code can be used to modify parameters such as the range, scale, etc. Take a look at the properties of AIChannels in the NI-DAQ .NET Framework document for the syntax for these properties.
Please let us know if you need any additional assistance...
Regards,
Nicholas B, Applications Engineer, National Instruments
09-07-2006 05:04 PM
Nicholas,
After I posted this I had found how to do this using essentially the same approach. The only difference is that I don't change the properties of all tasks, but a specific one. The code in OnTaskCreated inside DAQTask.user.vb is:
Dim TaskAIChannel As NationalInstruments.DAQmx.AIChannelTaskAIChannel = Task.AIChannels.Item(0)
TaskAIChannel.RangeHigh = ADRange
TaskAIChannel.RangeLow = -ADRange
TaskAIChannel.CustomScaleName = AIScale
TaskAIChannel.VoltageUnits = AIVoltageUnits.FromCustomScale
Then I ran into a problem because the OnTaskCreated is called only once. If I acquire with one set of parameters, examine the data, then decide parameters need to be changed, I had to restart the UI. Not pretty.
So then I had to snake my way thru the code generated by the DAQ Assistant to find that Task was inherited (DAQTask class) and there were a lot of other things going on that were hard to follow. The code isn't very user friendly. For my acquisition, there are 17 methods and 2 events generated to execute 6 lines of task related code! For example, see AcqVoltageSamples_IntClk.2005.
My present feeling is that I can use the DAQAssistant to help me find out the relevant calls, settings and run limited functional testing. Otherwise I need to do it the old fashioned way.
I think that NI should show users examples that do exactly the same things that are in the DAQ examples folder with DAQ Assistant generated code. The examples, such as AcqVoltageSamples_IntClk.2005 would contain modified DAQTask.user.vb + UI calls. Then I would not have had to spend so much time on this simple issue.
09-08-2006 12:05 PM
Hi Steve,
I am glad to hear you're up-and-running, and I apologize for the inconvenience. I will surely communicate your ideas with our Web Support and Developer Zone (examples) teams.
Have a great weekend...
Regards,
Nicholas B, National Instruments
09-14-2006 09:16 AM
Hi Steve
I'm sorry you were having problems with the DAQ Assistant. Let me try and clear things up by walking through the process of generating and customizing the code.
Visual Studio 2005 seems to want to hide more stuff from VB users for some reason, which might make things more challenging for you. This post might end up becoming garrulous, but I’m trying to be thorough so bear with me.
You have already figured out how to generate code via the DAQ Assistant from the looks of it. You can bring up the DAQ Assistant via the Project >> New dialog (if you choose to create a new DAQ Application project). You can also add the DAQ Assistant to existing project by opening up the solution explorer (Ctrl+Alt+L), right-clicking on the project and selecting "Add New Item", The DAQ Assistant will be available as one of the Measurement Studio items. The DAQ Assistant will allow you to customize the task to your need (ranges, custom scales, timing and such). You can make small changes that would not significantly change the behavior of the task. This is step 1.
To generate code that actually runs the task, you would use the DaqComponent control that is installed on the toolbar. The control will use an existing project task and generate example code based on the task you select. Once you generate example code, you cannot go back and make major changes to the task without breaking the code. By major changes, I mean changing the task from finite to continuous, analog input to analog output or digital output. In these cases, you would need to go do fix ups in the example code yourself, but it’s usually best to delete the generated code and the daqcomponent and have it generate new example code for the new task behavior. You can make small changes without breaking the generated code, like choosing a different scales, channels, ranges, adding triggers and so on.
The DaqComponent will generate code into 2 files: DaqTask.vb and DaqTask.User.vb. I’ll explain how to access them and their significance below. I am assuming the name of the mxb file is DaqTask for this example. Hence the name of the files.
It looks like you did make it this far without too many problems. I want to talk about some of the options available for extending and further customizing the generated code. New to VS2005 is a feature called partial classes. You can read more about the feature here if you are not familiar with it.
http://msdn2.microsoft.com/en-us/library/yfzd5350.aspx
The file of interest is the daqtask.user.vb. This is the partial class that you update and modify without fear of loosing the changes due to code regeneration. In your case, this would be place where you can expose properties and methods that would allow you to customize your task based on your application. This is what makes partial classes so nifty.
I have attached an example of how you might set this up. In the example, I generated code via the DAQ Assistant. I took your idea about changing the ranges and added some static (Shared in VB) methods to help dynamically determine the input ranges supported by the device via the DaqSystem class. These methods are shared because they don’t depend of the task to be created in order to be used. These are basically just reading the system properties. I used these to populate a listview control that lets the user pick and choose the ranges required. I also exposed the Task object being used by the Daq component incase there were any other operations you wanted to perform on the task besides just changing the ranges. I prefer to expose only the operations I was going to perform and not the lower level object itself to not break encapsulation. For changing the ranges, I created a SetTaskRange method.
I hope this clarifies how to use the code generated by the DAQ Assistant. We preferred not to expose the Task object to avoid breaking encapsulation. Generating every single method/property belonging to the Task object and its subjects would end up re-creating another DAQ API entirely. We left the decision of customizing the DaqComponent to the user who better understands the application being designed. Partial classes are the key VS2005 feature that allowed us to separate out the esoteric auto-generated code and the user code.
So to re-iterate the use of the DAQ Assistant code, here is the high-level breakdown of the steps
1- Generate configuration code via DAQ Assistant. This is just configuration code and is not runnable.
2- Use the DaqComponent to generate code to load and run the configuration code generated by the DAQ Assistant
3- Expose methods/properties or customize the behavior of the DaqComponent in the .User.vb/cs file.
You had also asked why we do not use the DAQ Assistant in the shipping DAQ examples. The primary reason for this is that the DAQ .NET shipping examples demonstrate the use of the just API, without the use of any code generation and such. The DAQ .NET libraries are available to customers for free with the DAQ driver and do not require Measurement Studio. The DAQ Assistant is only available via Measurement Studio. Using the DAQ Assistant to create the shipping examples would have meant that anyone wanting to use DAQ with .NET would be required to purchase Measurement Studio if they wanted to use the examples. This would have also defeated the purpose of explaining how the DAQ API (which is ultimately what the DAQ Assistant is using) works. Tools like the DAQ Assistant were created to make developers more productive and applications better organized by auto-generating Task-specific code and providing structure to that code via common design patterns (encapsulation, et. al.). But I do think the idea of including a few DAQ Assistant examples is worth considering.
I realize the shortcomings of the documentation and I will pass this feedback on to the developers.
I hope this helps. Please let me know if you have any questions.
09-14-2006 05:43 PM
Bilal,
Thank you for spending the time to provide details. I had already figured out the hard way a lot of what you explained. That's one of the reasons I wanted better documentation: to help others. I've spent more project money (labor dollars) on this simple cutomization than the cost of MS + VS2005+ a PXI DAQ system. This is why I would have really liked to see an MS training course. I'm not a professional programmer.
I did find an easy way to customize my application: modify the DAQTask.user.vb code to do what I need and keep disposing of the task when acquisition is completed. This approach does have a performance hit because the process of making a new task takes some time. (If that is a problem then I would have the acquistion pause instead or set up the task behind the scenes.) Then the next time around a new task is implicitly created (as explained in the task state-model documentation).
Now I have this simple way and your more advanced way to do things. I agree totally w.r.t only exposing the proerties that are needed to preserve the benefits of encapsulation.
Steve
09-15-2006 03:05 PM
09-15-2006 03:23 PM
Bilal,
I completely agree with you. I was just trying to make some progress so that I could move on to the next stage. I wanted a working application. I figure that anything relating to the task creation itself (not the timing) will need to trigger creating a new task.
I know that the present code will be improved as I get better. I'll swipe your code and graft it into mine In fact right now the problem I'm having is related to graceful shut down. However, that will be the subject of a different thread.
Have a nice weekend
Steve
04-29-2010 08:16 PM
Bilal,
You mentioned in this thread that you don't need to dispose unless you are changing a major property. Well, I need to change the PhysicalName if my AIChannels. Do you have an example of Disposing a task, then creating with new PhysicalNames assigned to my channels?
Also, when I did try to change the PhysicalName (without disposing so it never really worked), I get the exception that the Task needs to be committed or started before this property can be changed. I don't really understand this since it seemd that once the task is committed you cannot change the PhysicalName anyway.
Thanks for any advice.
Darren