LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Wait ms multiple timeout in event structure

Highlighted

Hello,

 

I am writing an application that needs to capture data only while a key is pressed and held.  DAQ stops if the key is lifted.  The DAQ code needs to execute every 66 ms.

 

It seems to me that an event structure is the best way to capture key-up and key-down events. Once a key is down, a boolean 'record' will turn true until the key is up, when it turns false.  This works just fine (see the attached VI).

 

The problem is in how the DAQ code fits in.  I could have it be the timeout case of the event structure, and then only execute if the record is found true.  However, I understand that the timeout is the number of ms to wait after an event is done executing before executing timeout.  Is there a way to make timeout occur on a ms multiple of 66 instead?

 

If I take the event structure out and instead use Wait ms multiple to time the DAQ loop, how would I listen for a key press and release?  Could I have parallel loops, one with the event structure and the other with the DAQ code and pass record between them as a global?  Since only the event structure loop will change record and the other will just read, does this avoid race conditions?

 

This is the most complicated thing I have ever made in LabVIEW, so I want to be sure I understand what I am doing before I dive in and make a pile of spaghetti all over my BD!

0 Kudos
Message 1 of 10
(2,239 Views)
Highlighted
I would use parallel loops using a Producer/Consumer architecture. You can look at the examples that ship with LabVIEW. The Producer loop would contain your event structure. When it detects the key down event it would post a message to a queue (much better than using globals) which would start the DAQ reads in your Consumer loop. This loop would be a state queued state machine. The "Start" message would start the process of reading teh DAQ values. A delay state would wait your desired delay, 66 ms. The state following that would again be the read state. This would continue until you receive the key up event which would post a stop message to your porcessing task. Once stopped it would sit idle waiting for teh start message again.


Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
Message 2 of 10
(2,235 Views)
Highlighted
Great description of a good solution.
"Should be" isn't "Is" -Jay
0 Kudos
Message 3 of 10
(2,206 Views)
Highlighted

That solution is very close to what I need, especially for the UI events.  Thank you!

 

There is one little problem though: I don't want a 66 ms wait inbeween the return and the next call. Unfortunately, the hardware I am working with doesn't interface directly with LV, so we have to trigger it and collect data in a C++ dll.  The quickest the hardware can run is around 66 ms a period.  Since it gets glitchy when running at top speed, we want to regulate how often the call is made to the DLL (every 66 ms).  The call will take almost all of this time to execute and return to LV.  A state machine isn't quite what I need since I need to regulate the amount of time in between one call to the next (as opposed to the amount of time between after return but before the next call) and I cannot guarantee that the call will always take the exact same amount of time.

 

Also, I was planning on using a producer-consumer architecture for the DAQ and the processing of the data although it is unusual for DAQ to be so slow.  Would that mean that I need three loops (UI loop, DAQ loop, and processing loop) and then have the DAQ act as the consumer to the UI and the producer to the processing loop, with a separate queue for each of the two relationships?

0 Kudos
Message 4 of 10
(2,192 Views)
Highlighted

This sounds reasonable


jdubb9 wrote:

That solution is very close to what I need, especially for the UI events.  Thank you!

 

There is one little problem though: I don't want a 66 ms wait inbeween the return and the next call.

 

Also, I was planning on using a producer-consumer architecture for the DAQ and the processing of the data although it is unusual for DAQ to be so slow.  Would that mean that I need three loops (UI loop, DAQ loop, and processing loop) and then have the DAQ act as the consumer to the UI and the producer to the processing loop, with a separate queue for each of the two relationships?


A UI Event Enquing Commands to a consumer loop that has two states "Start" and "Stop" (Toss in init and exit states for fun Smiley Wink ) Start and stop states control a timed loop that acquires data and enqueues that data for processing by yet another function.

 

Sounds like good encapsulation of the functions, Good modularity for expansion, great abstraction of the details..... Good work!

 

At CCI (Plug ahead-) I have a similar archetechure for a test main-line. GUIevents enqueue commands to a test exec.  Test exec enqueues vectors to Test State machine.  Test state machine enqueues results to Data Distributor. Data distrubutor tickles the test exec when results a in, places data in a file and on the GUI Display.  Add bells and whistles (user permissions, dynamic breakpoints, error recovery, automated Pizza ordering, etc....) and a pretty adaptable non-LVOOP application is born.

 

"Should be" isn't "Is" -Jay
Message 5 of 10
(2,168 Views)
Highlighted
You could still use the state machine. If you have your known frequency for your data collection you would simply time the read of your data and your wait state would subtract that from your period and read again. Granted, this will not be fully deterministic with respect to the timing but it sounds like this may not be an issue in your case. You simply want to read as fast as possible but no faster than 66ms between reads. The one issue with the timed loop is that you will need something to interrupt the lopp with the Stop event. BTW, if you use the state machine remember that you may want your Stop or Exit events to be queued at the opposite end of the queue. You will need that if you want to ignore any any states that are already queued.


Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
Message 6 of 10
(2,158 Views)
Highlighted
Thank you both so much for your help!  I have a working version of the message queue from the event structure to a state machine, and it looks like adding the last loop for processing won't be too difficult.  Thanks again for your insight 🙂
Message 7 of 10
(2,056 Views)
Highlighted

Quite welcome.

 

Good Luck

"Should be" isn't "Is" -Jay
0 Kudos
Message 8 of 10
(2,024 Views)
Highlighted

Good Day,

 

I am new to labview and i will appreciate some help! I am trying the to run a program for 8 hours a day(24hours), i tried timed loops and sequences and so many examples. Nothing seems to work.  I am using a cFP-2120 and cFP-PWM-520. i am attaching the small program that i am trying to run.  I am using LabView 8.2

 

Waiting for your kind reply   

0 Kudos
Message 9 of 10
(1,990 Views)
Highlighted

Don't hijack someone else's thread.  Start a new thread.  Provide more description as to how it isn't working for you.  What are you trying to do and how is it actually behaving.

0 Kudos
Message 10 of 10
(1,987 Views)