LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Temporary stop listening to a queue

Solved!
Go to solution

Good afternoon,

 

I'm working on a supervisory VI to PLC.

My main.vi consists of 5 principal subVIs: one OPC-DAQ and four workspaces (see Capture1.png).

path3721.png

All subVIs will be always running inside the main.vi

The menu buttons does the function of show/hide the front panel of its corresponding workspace subVI.

 

The workspace subVI gets data from the OPC-DAQ.vi through a queue (and notifiers, but my problem is with the queue).

 

Here's my problem: the OPC-DAQ subVI enqueues elements to a queue named "q_medições". And each workspace subVI have a dequeue element for "q_medições".

What I want is:

- When first Menu Button (Menu Button is a Radio Button control), only first workspace subvi will be dequeing elements from "q_medições" 

- When 2nd menu button is on, only the 2nd workspace subvi will be dequeing elements from "q_medições"

- Same for 3rd and 4rd buttons

 

Please see a example of block diagram from a workspace subVI. These subVIs knows the current Menu Button from the "n_menuAberto" notifier

Captura2.PNG

 

There's a way to temporary stops a listener listening a queue without releasing the queue?

What is the best way to "hold" the Dequeue Element function until the right Menu Button is pressed?

0 Kudos
Message 1 of 10
(4,221 Views)

@mthheitor wrote:

There's a way to temporary stops a listener listening a queue without releasing the queue?

What is the best way to "hold" the Dequeue Element function until the right Menu Button is pressed?


There are two ways to block a Queue -- don't Enqueue, or don't Dequeue.  I created a little test routine (I, at first, didn't think this was possible, but it worked ...), shown here using a Stream Channel Wire instead of a Queue (I'm something of a "nut" about Channel Wires).  

 

Here's how it works:

  • This is a Producer/Consumer Design, with the Producer generating "Data" at 1 Hz, with the Data being 0, 1, 2, ..., the number of seconds.
  • The Consumer can be in one of 5 States -- 0 .. 3 are collecting data from the Producer (equivalent to your four workspaces) while State 4 just counts the number of times that the Consumer Loop runs (I leave as an Exercise for the Reader understanding how fast the Consumer Loop runs in each of its 5, i.e. 0 .. 4, States).
  • The Consumer reads the Knob that says "who gets the data?" -- setting it to 4 means "nobody gets the Data".
  • If you run this, you can see the latest 1-second counter in the last of the States 0 .. 3 that was selected.  If State 4 is selected, you will be counting "something else", namely the Consumer Loop index.
  • Before actually running this code, predict what would happen if you started in State 4 (the "Something Else", or "don't process the Producer" State).  
  • Push Stop to stop the program (but the Knob has to be in 0 .. 3 to stop the Consumer ...).

I wrote this in LabVIEW 2018.  I'm attaching it as a Snippet and as a VI.  If you had attached your VI instead of a picture of your VI, I could have made sure you were running LabVIEW 2018 and could run this example -- oh, well.

DEMO Multi-QueueDEMO Multi-Queue

 

Bob Schor

Message 2 of 10
(4,195 Views)

There are a few ways to do this. I think the simplest would be to just use multiple queues. Instead of the listeners trying to ignore messages, make the sender enqueue the messages to different places depending on where it needs to go. Another way is to use User Events, which can register and deregister for event notifications using Dynamic Event Registration. You'd still need another communication method to control the registration and deregistration though, as once you deregister for events you stop being able to send messages via said Event 🙂

 

Another way to do this would be a "message dispatcher", where there's an intermediate "listener" that can receive elements from your main queue and can send them on to separate queues.

 

Having your listeners stop listening means you have to repeat code in ALL listeners to get them to stop listening to the queue, whereas doing it from the sender means it only happens in one place. Having multiple items dequeue from the same queue is typically, but not always, bad practice. Multiple dequeuers are usually used when you have multiple worker functions trying to process data from the same source that can be recombined later, as each element only gets dequeued one time, no matter the number of listeners.

 

Contrast that with User Events, where you can call Register For Event in each listener. Each Registration will receive the Event when it's sent out, so ALL of your subVI's will see all messages. You could then include an "address" in the message to tell the Event Structures to only process events sent to them, and to ignore all others.

Message 3 of 10
(4,194 Views)

Sorry @Bob_Schor, these VI Snippet are something I always wanted to learn, but the pinned post in the forum doesn't do a lot to teach about snippets (https://forums.ni.com/t5/LabVIEW/Notice-Attach-VI-Snippets-to-post-rather-than-upload/td-p/3660471)

But this does: https://knowledge.ni.com/KnowledgeArticleDetails?id=kA03q000000x2PkCAI&l=en-US. Please pin this tutorial within the inside the pinned post of the Forum. Cause I always thought Snippet were something about the forum, not a LabVIEW feature.
(I know this sounds like non-smart, but I have friends that does not know about the snippets. The word "snippet" is something I've only see in LabVIEW, and it was a little confusing in my opinion. But now I know what is a snippet, thanks.)

 

I'm using LV2012 and could not run your code. Please, can you save in LV2012?

0 Kudos
Message 4 of 10
(4,179 Views)

@BertMcMahan multiples queues sounds like wasting resources, because the data is always the same (measurements from sensors). The only thing that changes is what each workspace subVI do with the data. The 1st workspace (Home), for example, let the user freely interact and move with the LVDT, cylinder, hydraulic pumps and motors. The 2nd workspace (Testing) do a automatized test to a specimen...

And one of the sensors has a 5 MHz acquisition rate (during the standard test), imagine send this data through 4 different queues.

 

I'm using User events to do simple things like start and stop camera, send stop to some loops. I think implement the listen/stop-listen system with User Events would be too much complicated, at least for my current knowledge.

 

The message dispatcher have the same thing that I want to avoid: multiple queues for the same data.

I have only one producer in the queue (OPC-DAQ.vi), and only one consumer (workspace subVI). But the dequeue change its place according with the Menu Buttons of the main.vi.

I do not want multiple dequeue at the same time, only one dequeue will be active.

 

About the "address" it's a interesting idea. I'm thinking in use a "Preview Queue Element" before each "Dequeue Element", if I have elements in the queue, verify if the workspace subVI is the corresponding active (Menu Radio Button = workspace.vi) before dequeue each element of the "q_medições". Maybe this can work 🙂

 

Thank you for the tips.

0 Kudos
Message 5 of 10
(4,170 Views)

You don't need to send data along all four queues- you select one of the four queues on which to send data. On other words, your sender chooses one queue and sends it to that queue and that queue alone.

 

The dispatcher doesn't send copies of the same data either, it just decides to forward some of the data along, taking the responsibility of deciding the "to" queue away from the VI generating the data. It only sends it along one of the queue wires, not all four.

0 Kudos
Message 6 of 10
(4,168 Views)

@mthheitor wrote:

About the "address" it's a interesting idea. I'm thinking in use a "Preview Queue Element" before each "Dequeue Element", if I have elements in the queue, verify if the workspace subVI is the corresponding active (Menu Radio Button = workspace.vi) before dequeue each element of the "q_medições". Maybe this can work 🙂

Don't do this - it's a recipe for race conditions! What happens if someone else dequeues from the queue during the time in between your "Preview Queue Element" and "Dequeue Element"? Then the element you get from the queue will not be the same as the one you previewed. Follow BertMcMahan's advice and use a separate queue for each or use a user event with an address.

0 Kudos
Message 7 of 10
(4,155 Views)
Solution
Accepted by topic author mthheitor

hi,

Preview q will work , the receivers should de-Q after ensuring the information is meant to them. 

bp
Message 8 of 10
(4,121 Views)

@mthheitor wrote:

I'm using LV2012 and could not run your code. Please, can you save in LV2012?


I'll try.  I'm "on the road" for a few days, but have my laptop, so I should be able to download my own code and see if I can Save for Previous ...

 

Bob Schor

0 Kudos
Message 9 of 10
(4,096 Views)

@Bob_Schor wrote:

@mthheitor wrote:

I'm using LV2012 and could not run your code. Please, can you save in LV2012?


I'll try.  I'm "on the road" for a few days, but have my laptop, so I should be able to download my own code and see if I can Save for Previous ...


Channels were not around in 2012, so you will have that issue.

 

I will also put my vote behind the multiple queues.  It is a lot simpler for your message handlers.  Ultimately, I say you should have a library for each message handler.  In that library, you have an Action Engine for maintaining the queue that it receives data on that is set to be private (don't let outside functions mess with it, only the receiver of the queue data should maintain the queue) and have a public VI for sending messages through that queue.  Then your main VI just has to decide which "Send Message" VI to call to get the data to the right place.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 10 of 10
(4,082 Views)