LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Triggering a running event log

Solved!
Go to solution

I am undergoing an initiation-by-fire trying to get some new programing up before I can get through all the training, so this may be an easy answer.  I want a text log of the events triggered, as this VI will run for many hours and not have someone constantly observing it.  An example would be:

 

10:00:00 Power On

10:05:00 Valve A to Position 2

10:10:00 TCD voltage over 0.5 V, triggered fill routine

 

The big difference I see between the examples I've found and my code is that I want to call from many different points along what will be a very large bit of code, and most of these shift-register loops are all able to be contained inside the loop.  I am trying to use a value change trigger, but can't figure out how to get the While loop to trigger.  The portion of the code I'm working on is attatched- am I close?  Going about it totally wrong?  Thanks in advance for any guidance!

0 Kudos
Message 1 of 5
(3,167 Views)
Solution
Accepted by topic author bgalfond

Your bottom while loop will never run until the top loop completes, ie, data flow. It is waiting for the boolean to return from the top loop.

 

Use either a queue or user event to send stuff to your second loop, the val signaling property is not recommended, causes a switch to the UI thread.

 

Lastly, you send a command to the serial port and immediately check for a response. Most serial instruments that I have used are slow and require a small wait before being ready for a response. Does your instrument send a termination character, if so use it and just put a wait on the read, no need to poll the bytes.

 

Cheers,

mcduff

Message 2 of 5
(3,151 Views)

You have a somewhat complex program that has "Events" that fire at certain times, and want to log these Events.  Here's a suggestion:

  • Start by "not worrying about the Events".  If you want to "mark" them, create a sub-VI that has just the Error Line running through it (so you can place it "next to" an Event) and label it "Log Event".
  • Make your code as organized and "clean" as possible.  Often organizing it as a State Machine of one sort or another (such as a Queued Message Handler, where the Messages are the States) can be helpful.
  • Once your code is running more-or-less OK without logs, you can think about adding the logs in by making "Log Event" actually do something.
  • One thing to think about is what is the nature of your log.  I presume it will include a Time Stamp, possibly a "Type of Event" entry (could be an Enum), and possibly a value for the Event (see if you can settle on a uniform type so you'd only need to pass in the Type of Event Enum and the Event Value).
  • One (crude, but effective) way to write Log Event is simply to have it open the Event Log, go to the end, write the Event, then close the Log.  The drawback to this simple idea is that your main code will "pause" while the Event is being written -- if you can spare the second that this takes, then this is certainly simple.
  • Alternatively, Log Event could function as a Producer in a Producer/Consumer pattern, putting the Event information on a Queue (takes very little time) and have a parallel Consumer loop dequeuing the Events and writing them to a file.  A "trick" to make this work is to use what I call a "Wireless Queue".  Construct Log Event as a "Do Once" While Loop (I hope you know what I mean by that) that, when first called, creates a Named Queue that it keeps internally in a Shift Register.  The Consumer loop that runs in parallel also creates the same Named Queue, and the Magic of LabVIEW "joins" these Queues "wirelessly" (because they have the same name, so they are the same Queue).

Bob Schor

Message 3 of 5
(3,123 Views)

@mcduff wrote:

Your bottom while loop will never run until the top loop completes, ie, data flow. It is waiting for the boolean to return from the top loop.

 

Use either a queue or user event to send stuff to your second loop, the val signaling property is not recommended, causes a switch to the UI thread.

 

Yes, thank you! Queue commands are just what I was hoping for. This can help avoid an (unlikely in this case) race condition too no? As for the serial devices, there are two types coming in, one with termination characters and one that doesn't mention them in the manual. They are all on a multidrop cable so I need to individually name them in terminal first and will figure out any nuances then.


@Bob_Schor wrote:

You have a somewhat complex program that has "Events" that fire at certain times, and want to log these Events.  Here's a suggestion:

  • Start by "not worrying about the Events".  If you want to "mark" them, create a sub-VI that has just the Error Line running through it (so you can place it "next to" an Event) and label it "Log Event".
  • Make your code as organized and "clean" as possible.  Often organizing it as a State Machine of one sort or another (such as a Queued Message Handler, where the Messages are the States) can be helpful.
  • Once your code is running more-or-less OK without logs, you can think about adding the logs in by making "Log Event" actually do something.
  • One thing to think about is what is the nature of your log.  I presume it will include a Time Stamp, possibly a "Type of Event" entry (could be an Enum), and possibly a value for the Event (see if you can settle on a uniform type so you'd only need to pass in the Type of Event Enum and the Event Value).
  • One (crude, but effective) way to write Log Event is simply to have it open the Event Log, go to the end, write the Event, then close the Log.  The drawback to this simple idea is that your main code will "pause" while the Event is being written -- if you can spare the second that this takes, then this is certainly simple.
  • Alternatively, Log Event could function as a Producer in a Producer/Consumer pattern, putting the Event information on a Queue (takes very little time) and have a parallel Consumer loop dequeuing the Events and writing them to a file.  A "trick" to make this work is to use what I call a "Wireless Queue".  Construct Log Event as a "Do Once" While Loop (I hope you know what I mean by that) that, when first called, creates a Named Queue that it keeps internally in a Shift Register.  The Consumer loop that runs in parallel also creates the same Named Queue, and the Magic of LabVIEW "joins" these Queues "wirelessly" (because they have the same name, so they are the same Queue).

Bob Schor


 

Thank you, I appreciate the work process, the SubVi approach especially helped keep the whole log idea from being very overwhelming. As the log is more for user friendliness than a time-critical process, I put the dequeue in a simple loop every 100 ms.  It doesn't seem to effect system resources noticably- are there advantages to the shift register though?

 

New working solution attached.

0 Kudos
Message 4 of 5
(3,093 Views)

Glad to help. See suggestions in the snippet for bottom loop.

 

mcduff

 

Snippet.png

0 Kudos
Message 5 of 5
(3,088 Views)