LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

QMH Generate User Event

Hi,

 

I've been having trouble passing a Generated User Event from a consumer loop back into the Message Handling loop. My example program only has one consumer loop but the eventual application will have a message handling loop, producer loop, writing loop, UI display loop, and a while loop with graphs for displays. The reason for a Generate User Event action is because on occasion, a consumer loop will need to trigger an event in the main message handler. What am I doing wrong here that the generated event won't pass into the message handler?

 

Thanks,

Anton

0 Kudos
Message 1 of 9
(3,841 Views)

I am pretty sure you are pulling the string data from the wrong place.  You want the string to be from the event (part of the Event Structure), not the state from the Queue.


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 2 of 9
(3,809 Views)

The problem is that the queue in your producer loop is empty once the do button is pushed.  So it is simply waiting at the dequeue element in the producer loop.  The event will be captured, but you have to go back into the do state of your producer loop.

 

[edit]  But if i can offer some suggestions, i would remove the case structure in the producer loop and replace it with just your event structure.  I would then handle your initialize stop and exit loops in your consumer.  Im not sure why you need to register events to your event structure though.  Instead of generating an event in your consumer loop you could simple enqueue a stop cose in your consumer loop.



-Matt
0 Kudos
Message 3 of 9
(3,805 Views)

Hey Matt,

 

The problem is that the queue in your producer loop is empty once the do button is pushed.  So it is simply waiting at the dequeue element in the producer loop.  The event will be captured, but you have to go back into the do state of your producer loop.

If I run the highlight execution, it looks like the Message Loop (I am guessing this is what you are referring to as the producer) is stopped in the Do event. Maybe I don't understand fully but I thought it would go to the timeout event and just wait there, no?

 

Im not sure why you need to register events to your event structure though.  Instead of generating an event in your consumer loop you could simple enqueue a stop cose in your consumer loop.

The reason why I want to register events is because there will be instances where other consumer loops depend on a specific consumer (e.g. a producer loop acquiring data reaches # of samples it needs will then trigger a stop in writing and display consumers). By registering events, I thought I could then message the other loops (I have cluster of queues) to stop. Do you think this is more effective than say, using a notifier?

 

I am basing this code off a template that a gentleman named Simon wrote: http://forums.ni.com/t5/Example-Program-Drafts/Simon-s-DAQ-Templates/ta-p/3494514

 

What the template meets 90% of what I need. What it is missing is 1) a way to communicate between consumers (e.g. send calibration values from writing consumer to display consumer) and 2) a way to order control of the consumers (e.g. lock UI controls then trigger data acquisition/writing). Sifting through the discussion forums I felt event registration could satisfy those needs but I am open to suggestions.

 

THanks!

0 Kudos
Message 4 of 9
(3,789 Views)

If you highlight the execution it stops at the dequeue element in the producer loop, it never enters the case structure.  The event structure would timeout if the application executed the case structure again, but you have no timeout wired to it, therefore it is by default -1 and does not actually timeout.  If youd like a timeout case, wire a value to the timeout terminal, say 100-200ms. 

 

I looked at the post by simon and his consumer loops do not message the producer loop. The consumer loops can message each other, but the producer loop only messages consumer loops, not vice versa.  Most importantly though he enqueues a do command every iteration of the do case, so that if the do case does timeout (youll have to wire a timeout to it) it will cycle back to the do.

 

Using events is better than notifiers in this case and in that case. 

 

I think if you fix the timeout case and enqueue a do in the do case, this will do what youre looking for.

 

You have also not programmed a way to stop the application. I see you have a stop case, but the stop does not stop the application.

 

 



-Matt
Message 5 of 9
(3,780 Views)

In my experience, I find it best that your main GUI loop is NOT a State Machine.  It should just be a loop with an Event Structure in it.  If you need sequencing, make that a seperate loop.

 

I also find it best to just have direct communications with whoever needs the data.  So if consumer 1 is trying to get data to consumer 2, then it should just send the data through consumer 2's queue.  I find routing VIs to be a pain and over complicate things.

 

The other option I like to do is to not use queues at all.  I use User Events to pass data everywhere.  So each loop registers for the events it cares about.  When it is done processing or just needs to pass data somewhere, it just generates an Event and then whoever cares will get it.  If you are going this route, I highly recommend you have have a look at the Delacor Queued Message Handler.


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 6 of 9
(3,777 Views)

Thanks Matt. I will try what you have suggested and update this thread. I think it will work. Crossrulz (see comment above this) also made a good suggestion regarding direct communication - I think both of your suggestions of just making the Command loop consist of a while + event are good ideas.

 

 

0 Kudos
Message 7 of 9
(3,764 Views)

Okay so I have updated the program with some recommendations from you and Matt. The main message handling loop I have removed states and the case structure. I've kept the Command Message control outside the event structure so I could see what the string is after a dequeue. 

 

The Consumer loop seems to be moving well now but I am still have some trouble getting the User Event to execute. Specifically, it looks like when I press the DO button, the bottom loop runs as planned but when it shoots a Stop back to the event structure, the <Message> handled is actually " Doing something". What am I doing wrong here?

 

I am not quite ready to abandon the queues completely because I'm not comfortable yet with the User Events alone. Thanks for that suggestion though.

 

I also find it best to just have direct communications with whoever needs the data.  So if consumer 1 is trying to get data to consumer 2, then it should just send the data through consumer 2's queue.  I find routing VIs to be a pain and over complicate things.

If I had an additional consumer loop(s) where they each had their own queue(s), could I transition their states from a different consumer (e.g. producer calls up writing consumer loops queue)? I could bundle all the queues right at the start of running and call individual queues from within the consumer, rather than using the event generation as you have mentioned.

 

Thanks

0 Kudos
Message 8 of 9
(3,738 Views)

The reason you're not seeing the "Doing something" is because in your consumer loop you never enqueue the messages. Because of this, your code waits forever at "Dequeue Element," since there's never anything to dequeue. 

 

You can create as many consumer loops as you want, based on the number of different named queues you use. 

0 Kudos
Message 9 of 9
(3,709 Views)