Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Managing multiple ascychronous DIO bits

I mistakenly posted this in the VB6 area, I'm developing this app in VB.NET

I'm designing a large automation system that requires nearly 100 DIO bits. For this I've purchased two NI6515 cards.
Many, but not all, of the output bits go to air cylinders that have sensors indicating which end the piston is at, and other parts of the system need to know what state the cylinders are in after a OUTPUT is called.

My hope in using the NI products was that the "ChangeDetect" system could manage these events. After looking in more detail into the way this works, there are some serious limitations on how the system can be used. Let me try to expalin how I currently plan on implementing this and hope to get some feedback as to a better/different way of operating.

All the input lines for each device need to be in one task, because, I found out from error 50103, two tasks can not be running at the same time on the same card.
For that task, I will configure one big "ChangeDetect" that includes all the bits that will be monitoring cylinders.
I will start one "Reader" that will call a "OnDataReady" when ANY bit in the "ChangeDetect" system changes state.
I will pass an object of my own design to through the IAsyncResult to the "OnDataReady" function.
When "OnDataReady" is called, I will use the contents of the IAsyncResult object to determine which bit changed, and perform the appropriate action for that bit.
I will then restart a "Reader" to catch the next bit change.

I hope that is clear. Please let me know if this is a crazy scheme or if there is an easier way.
0 Kudos
Message 1 of 12
(5,109 Views)
Hello Chuck,

Your application looks really interesting, and I don't think your scheme is crazy, it makes sense to me. As you mentioned, unfortunately we cannot run two tasks of the same type (two tasks for Digital input for example) at the same time, you can only have one after another.

Please let me know if you have any additional questions.

Thanks,

LA
0 Kudos
Message 2 of 12
(5,090 Views)
Thanks LA,
I'm moving forward here, but I only have one 6515 card at the present time so there are some things I can't test.
My current question is: If I have two cards, each with 4 input ports (32 bits) can both these pieces of hardware be run by the same input Task???? In other words (code that is) is this a valid line?

DITask.DIChannels.CreateChannel("Dev1/port0:3,Dev2/port0:3", "Input", ChannelLineGrouping.OneChannelForAllLines)
0 Kudos
Message 3 of 12
(5,059 Views)
Hello Chuck,

Unfortunately 2 boards can't run by the same input task, you will have to create a separate task for each board. So, the line should actually look like this:

DITask.DIChannels.CreateChannel("Dev1/port0:3", "Input", ChannelLineGrouping.OneChannelForAllLines)
DITask.DIChannels.CreateChannel("Dev2/port0:3", "Input", ChannelLineGrouping.OneChannelForAllLines)

Hope this helps,

LA
0 Kudos
Message 4 of 12
(5,039 Views)
Getting better all the time ...

Having two tasks is not a problem, this code is written into a component so I will just instantiate two components, each one attached to the separate boards.

Next question: I now have the system automatically collecting every digital input change, and there is constantly a "reader" running. This becomes a problem when I want to shut the system down. With the "reader" running, the task will not die! In particular, it will not die until there is a dig input state change, because that stops the reader long enough for it to die. The only way I can figure to make this thing "killable" is to have a "heartbeat" signal coming from one line of digout, to one line of dig in that causes a state change every second or so.

Is there a back-door way to kill a task while a reader is running so I don't have to cause these artificial inputs?????
0 Kudos
Message 5 of 12
(5,028 Views)
After looking at your message again, I think the code needs a bit more editing...

DITask1.DIChannels.CreateChannel("Dev1/port0:3", "Input", ChannelLineGrouping.OneChannelForAllLines)
DITask2.DIChannels.CreateChannel("Dev2/port0:3", "Input", ChannelLineGrouping.OneChannelForAllLines)


Separate TASKS
0 Kudos
Message 6 of 12
(5,028 Views)
Chuck:

I'm not sure I understand the problem. You're calling a BeginRead function, right?

Calling Stop() on the tasks should cause the reads to stop, even if they are waiting for data to become available. After which you can dispose the Tasks without any problem. Are you currently stopping or disposing the tasks? Or are you calling Stop and not seeing this behavior?

-- Chris W
.NET DAQmx Team
National Instruments
0 Kudos
Message 7 of 12
(4,994 Views)
Hey Chris,

I have a "BeginRead" running constantly because we are collecting all of the inputs now though one big "ChangeDetect" system.
It appears that as long as the BeginRead is running, a "DITask.Stop()" simply hangs execution at that line until a input state change allows the system to be stopped. My developer working on this (my Boss, he he he) has found in the documentation something that says this is how it works by design. I was hoping to fine some sort of "back door" of other "feature" that would allow us to stop the task and without having to rely on an input transition to break the "BeginRead".

If you are saying there is a way to do this I'd be very interested to find out how. Currently we have a "heartbeat" that cycles a DigIN every second to make sure the system can shut down. We are actually having circuit boards made soon that will have a couple of bits tied together to generate the "heartbeat"
0 Kudos
Message 8 of 12
(4,990 Views)
Chuck:

I'm sorry, Chuck. I was thinking of aborting the task rather than stopping it. Yes, you're right: by design, stopping the task will wait for pending asynchronous operations. Aborting the task does not. You can abort by calling the Task.Control method and passing TaskAction.Abort.

Hope that works better for you,

--Chris
0 Kudos
Message 9 of 12
(4,967 Views)
Well Chris,

That does not seem to work. In the "Dispose" method of our class we put the line:

DITask.Control(TaskAction.Abort)

As the first in the routine and got an error. The following error occurred while it was executing the one and only abort statement we have:

An unhandled exception of type NI ... yadda yadda yadda
Additional Information: The specified operation cannot be performed because a task is in the process of being aborted or a device is in the process of being removed from the system. Wait until the abort operation is complete and attempt to perform the operation again.

I do not know why it thinks that the task is ALREADY being aborted when this is the only abort line in the code.
We also tried:

DITask.Control(TRaskAction.Stop)

But that hung at that line indefinitely without ever getting to the "Abort" line that followed.

Any other suggestions???????
0 Kudos
Message 10 of 12
(4,958 Views)