LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Asynchronous Independent VI call with DAQmx issue

Solved!
Go to solution

Greetings,

 

I intend to connect 2 or more of these USB cDAQ-9171 devices, which host a single acquisition module (e.g. NI 9211, NI 9227), in a single laptop. The idea is to have differently configured acquisitions in different devices running at the same time in the same computer.

 

I have made a vi that creates a single DAQmx task and configures everything and starts the acquisition. It uses events for the boolean controls (continuous acquisition, channel select, start/stop channel/s logging) that create a new task, configures channels, timing, etc. and starts reading. So for every setting the user changes, the task is stopped and recreated with the new configuration, and restarted.

 

My idea is to call this vi as an asyncronous independent vi (call-and-forget) and spawn multiple independent instances, according to the number of DAQ devices I have connected to my computer. And have them aquiring different things at the same time.

 

The vi is configured as "Preallocated clone reentrant execution" in the options, and I can spawn different clones (with a number appended in the title bar of the window) using asynchronous call nodes from a small vi I made just to spawn them.
.

So I have a Clone 1 using a cDAQ3Mod1 = NI9217 for temperature RTD, and another Clone2 cDAQ1Mod1 = NI 9211 for thermocouple. Both are virtual devices for these tests.

 

However, the acquisition between the clones is not independent... I start one task in Clone 1, and the graphs/controls connected to Read.vi in clone 2 begin showing data. Or starting a task in Clone 2 gives errors like:

(e.g. "Task specified conflicts with an existing task name", or "Error -200477 occurred at Property Node DAQmx Timing (arg 1) in DAQmx Timing (Sample Clock).vi:4730004")

I tried giving a different Task name string at each Clone before starting the task creation event to see if it was the automatic naming the issue but the problem persists

 

Is there a way I can achieve this kind of independent acquisition using DAQmx?

 

Thanks in advance for your time. Best regards,

0 Kudos
Message 1 of 11
(3,654 Views)

Post your code. An explanation is not enough.

Paolo
-------------------
LV 7.1, 2011, 2017, 2019, 2021
0 Kudos
Message 2 of 11
(3,650 Views)

Quick thought: it sounds like your "Read vi" wasn't set to be reentrant.   So all top-level clones have to share access to the single non-reentrant instance.  Make it reentrant, then each clone will contain its own copy that can execute independently and simultaneously.

 

 

-Kevin P

ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.
0 Kudos
Message 3 of 11
(3,618 Views)

 

I checked the properties of the DAQmx Read.vi and it is stablished same as my vi, as reentrant. Good suggestion to check though,

 

I attach my VI and my launcher vi as requested previously.

 

My VI looks messy because it is still under construction, however the whole VI is just a 2 step sequence, one for a (horribly for now) implemented initialization, and then a producer-consumer loop for the acquisition part. The task creation/acquisition is in the consumer loop (below).

0 Kudos
Message 4 of 11
(3,611 Views)

@A_alejo wrote:

 

I checked the properties of the DAQmx Read.vi and it is stablished same as my vi, as reentrant. Good suggestion to check though,

 

I attach my VI and my launcher vi as requested previously.

 

My VI looks messy because it is still under construction, however the whole VI is just a 2 step sequence, one for a (horribly for now) implemented initialization, and then a producer-consumer loop for the acquisition part. The task creation/acquisition is in the consumer loop (below).


I only briefly looked at project, some suggestions

  1. Make subVIs. Your main is well over a screen sized block diagram, hard to debug
  2. Overuse of local variables. Not sure why you do this, you have an input, but use the local instead, see figure 1.
  3. There is something in the daemon, local or shared VI, that is messing up your acquisition. From what I can see you are writing to a local variable which may be shared across instances, not sure.
  4. Use a queue, user event or channel wire to write the data and then send to a reader.
  5. Consider using subPanels instead of Tab controls. It's a bit more work, but worth it in the end.

Figure 1: Why don't you use the control directly? Why is a local variable needed?Figure 1: Why don't you use the control directly? Why is a local variable needed?

 

I am doing something similar to your task, sorry I cannot share the customer's project, but I can give you some advice.

Break down your Main VI into subVIs. Make configuration subVIs for your DAQ, confugure everything for the task in these subVIs. Your daemon then should only be set to acquire data, this makes the daemon relatively simple. That is what I do, and it works well.

 

Figure 2 is a screen shot on my Main VI. Yes it is busy, but it fits on one laptop screen. There is a loop for handling Instrument Configuration, UI Changes, a Watchdog loop for monitoring, and other loops. It has a subPanel which various VIs are placed into. The loops are connected by User Events for messaging.

 

Figure 2Figure 2

 

mcduff

Message 5 of 11
(3,580 Views)

Just a quick note on the VI you posted as "figure 2".  On all 3 loops you have the event registration wire passed through as a shift register, but on the bottom two it appears that it's set up with the option on the output terminal to "Use default if unwired", and shows the dot indicating at least one frame is not wired. 

 

As such, there's a chance that the bottom two loops might stop responding to events, unless the only unwired case is the same one that stops the loop.

 

Even if that is how it's set up, using shift registers to pass event registrations back around isn't necessary (unless you're programmatically altering the registrations inside the loops, which is rare but not unheard of), so you could probably switch to normal terminals and have a lot less extra wires going through every case.  Or at the very least, remove the "Use default as unwired" option from them because it allows you to accidentally disconnect your event registration wire in any case and not notice because it doesn't break your VI.

Message 6 of 11
(3,576 Views)

@Kyle97330 wrote:

Just a quick note on the VI you posted as "figure 2".  On all 3 loops you have the event registration wire passed through as a shift register, but on the bottom two it appears that it's set up with the option on the output terminal to "Use default if unwired", and shows the dot indicating at least one frame is not wired. 


I have an "Events Unregister" Case, see below. This is where a use a "default empty event case". I like having this case for a couple of reasons:

  1. Makes block diagram smaller, do not need Unregister outside of loop
  2. The default is useful is my type def for the user event changes, I don't need to update an empty event in the unregister case.

Snap41.png


@Kyle97330 wrote:

As such, there's a chance that the bottom two loops might stop responding to events, unless the only unwired case is the same one that stops the loop.


That case is called when the loop exits or if I needed to unregister and re-register events in a loop.

 


@Kyle97330 wrote:

Even if that is how it's set up, using shift registers to pass event registrations back around isn't necessary (unless you're programmatically altering the registrations inside the loops, which is rare but not unheard of), so you could probably switch to normal terminals and have a lot less extra wires going through every case.  Or at the very least, remove the "Use default as unwired" option from them because it allows you to accidentally disconnect your event registration wire in any case and not notice because it doesn't break your VI.


I don't always programmatically change events, but I like having that option. And you are correct about accidentally disconnecting the event registration wire. But I chose to worry about that rather than update a bunch of empty event cases.

 

Basically, what is there is part of a Project Template using JKI State Machines linked with User Events. I use events for everything possible, even DAQmx Events and it leads to compact programming; everything can go to an event structure. The structure that I had shown is based on these threads with some differences.

https://decibel.ni.com/content/docs/DOC-12159 and
https://forums.ni.com/t5/LabVIEW/Community-Nugget-2009-03-13-An-Event-based-messageing-framework/m-p...

 

mcduff

0 Kudos
Message 7 of 11
(3,573 Views)

Thank you very much for all the best practices advised.

 

I started this implementation of VI way before I did the labview core 3 and then advanced architectures, where I got to know a lot of (new for me a bit still) labview concepts and ideas you mention. I´m pending to make my very first design using all these concepts, but looking forward to. Modularity and scalability become a great issue very soon otherwise.

 

My code is far from readable and far from well developed also, mainly it started as an idea and became bigger as it progressed, there was not real project planning for it and controls, indicators and wires were growing up as functionality and new ideas came up. I plan to change the architecture as soon as I solve this issue.

 

Regarding the clones, even if I use local variables, they should be accessed only within the vi and should allow the data to be kept separate between reentrant subvi´s.

 

At least at the moment the main take I can get is that: There is nothing regarding the nature of the DAQmx subvis/drivers/etc. that would prohibit the simultaneous acquisition of 2 differently configured daqmx devices using different usb ports in the same host computer. The issue should be somewhere in my implementation. Is that correct?

 

Thanks for your replies and your time

0 Kudos
Message 8 of 11
(3,551 Views)

@A_alejo wrote:

There is nothing regarding the nature of the DAQmx subvis/drivers/etc. that would prohibit the simultaneous acquisition of 2 differently configured daqmx devices using different usb ports in the same host computer. The issue should be somewhere in my implementation. Is that correct?


That is correct. Below is a screenshot of a program I am working on that shows multiple tasks running concurrently.

 

I tried looking through your clone, daemon  VI, and cannot figure it out. Sorry. Your Timestamp VI is not reentrant, but don't think that is the problem. Not sure what the library is in your project either, it seems like some network variable, maybe an issue, don't know I don't use them.

 

Since you are are starting out and learning more, re-factoring is highly suggested.

 

mcduff

 

PS The "Tabs" in the screenshot are not real Tabs. They are tabs hidden by a splitter with a subPanel below to mimic a tab.

 

Snap42.png

Message 9 of 11
(3,542 Views)
Solution
Accepted by topic author A_alejo

Dear all,

 

I wanted to let you know I succeeded in solving the issue, here is how.

 

My VI when running is a producer-consumer loops that uses a Notifier to send an unsigned integer number to the consumer loop, the value would depend on the event case inside the producer loop.

 

When the Notifier is created, I have assigned a string constant to it, "ACQ" as a Notifier Name input.

ACQ Notifier.PNG

This is what caused that the event was triggered in both clones at the same time, it seems it writes to the same memory address as I interpret it, regardless if the clones are configured as reentrant.

 

I changed the string for a String Control in the front panel as a test and I put different names on each clone, and this solved the issue.

 

At the moment I just replaced that control and did an automatic string+random_number generated as a name for the Notifier, which will be different for each clone.

 

Just as a note, before reaching the solution, I also tested replacing the Notifier with Queues, and the name string caused the same issue.

 

Thanks you all for your kind replies and your time.

 

Now I can work in overhauling the whole thing to a somewhat more decent architecture and subvi´s

regards,

0 Kudos
Message 10 of 11
(3,507 Views)