lvb Posted January 6, 2009 Report Posted January 6, 2009 I I have recently been reviewing design patterns. During this, I came up with a use case that requires high precision (< 1 msec) event triggering. A sample use case would be to create an alarm application that would show a user on-screen messages or log messages to file at a specific relative time. Instead using absolute time as a time base, I thought that relative time should be used, as in a stopwatch. Alarm times could be entered by a user programatically. Furthermore, the user should be able to pause and resume the stopwatch. Is there any type of architecture beyond a while loop running every 1 msec that would be appropriate? Is there a way to code this without polling? Just pondering, please share your thoughts! Quote
ASTDan Posted January 6, 2009 Report Posted January 6, 2009 Hello, I like using change detection events You can incorporate this into an event loop. I usually use a producer/consumer archtecture with the events being the producer and a queued state machine as the consumer. You could set up a counter timer channel to send out a pulse every millisecond and wire that into a change detection digital input. Dan Quote
lvb Posted January 6, 2009 Author Report Posted January 6, 2009 QUOTE (ASTDan) I like using change detection events You can incorporate this into an event loop. I usually use a producer/consumer archtecture with the events being the producer and a queued state machine as the consumer. You could set up a counter timer channel to send out a pulse every millisecond and wire that into a change detection digital input. Thanks for the reply Dan. That would be a great solution for hardware triggering, but the use case I was considering would not involve DAQ hardware. Any ideas for this? Quote
ASTDan Posted January 6, 2009 Report Posted January 6, 2009 QUOTE (brianafischer @ Jan 5 2009, 01:27 PM) Thanks for the reply Dan. That would be a great solution for hardware triggering, but the use case I was considering would not involve DAQ hardware. Any ideas for this? Hmmmm. I think you are going to have to poll. You have to keep track of time and ask what time it is relative to that. I like using a FGV to do this. You could put the FGV in a dedicated loop and send a message to your main loop when the time elapsed. Dan http://lavag.org/old_files/post-8614-1231180877.vit'>Download File:post-8614-1231180877.vit Quote
jdunham Posted January 6, 2009 Report Posted January 6, 2009 QUOTE (brianafischer @ Jan 5 2009, 09:23 AM) I I have recently been reviewing design patterns. During this, I came up with a use case that requires high precision (< 1 msec) event triggering.A sample use case would be to create an alarm application that would show a user on-screen messages or log messages to file at a specific relative time. Instead using absolute time as a time base, I thought that relative time should be used, as in a stopwatch. Alarm times could be entered by a user programatically. Furthermore, the user should be able to pause and resume the stopwatch. Is there any type of architecture beyond a while loop running every 1 msec that would be appropriate? Is there a way to code this without polling? Just pondering, please share your thoughts! You seem to have two questions, one is about <1ms timing, which is hard but not impossible. How are you going to measure that time? That should dictate at least part of your design. I don't think either of your use cases bear any relation to sub-millisecond timing. The other question is whether a stopwatch-like app should use relative time or absolute time. I would vote for absolute time because your timing code may have bugs (which you will eventually fix, of course) whereas the OS time is generally correct already. Quote
ragglefrock Posted January 6, 2009 Report Posted January 6, 2009 To get <1ms resolution you'll probably have to end up polling. You could use a Timed-Loop with a MHz clock, if you're running on RT. This loop would constitute your timer, and its period would be set to the relative alarm time in microseconds. Every time it executes, it could signal via an RT FIFO that the event occurred. This avoids polling and gives great timing. The problem comes when you want to let the user adjust the timing and pause the timer. To do this, you have to get a message to the Timed Loop. That's easy enough with another FIFO, but the problem is that the loop only executes on its period. So if you send a pause command, the loop has to wait for the next event before processing the command. That doesn't seem to fit your requirements. This becomes especially noticeable when the events get far apart. For instance, if your alarm rate is every 5 seconds, then you'd have to wait up to 5 seconds to be able to pause or adjust the alarm. Quote
Yair Posted January 6, 2009 Report Posted January 6, 2009 The problem with absolute time is that at least in Windows the timer has a ~16 ms resolution. In Windows, you can get sub-ms resolution by calling the performance counter API functions and there should be some examples VIs in the forums. You should be able to do something similar in other OSes. I didn't understand your desired architecture exactly, but it sounds to me like the most practical solution would be using a timeout mechanism. You can do this with an event structure's timeout event or with any of the synchronization primitives. This makes LabVIEW wait the desired time and allows you to break the wait if needed. Quote
lvb Posted January 6, 2009 Author Report Posted January 6, 2009 QUOTE You seem to have two questions, one is about <1ms timing, which is hard but not impossible. How are you going to measure that time? That should dictate at least part of your design. I don't think either of your use cases bear any relation to sub-millisecond timing. The use case is a simple example that I created, not a real-world implementation. The main design question is how to obtain an accurate sub-msec timing in a sequencer where events may be scheduled at varying times without an extremely resource-intensive polling loop. QUOTE The other question is whether a stopwatch-like app should use relative time or absolute time. I would vote for absolute time because your timing code may have bugs (which you will eventually fix, of course) whereas the OS time is generally correct already. As far as the relative vs absolute time, I was attempting to implement a "pause" condition which meant the alarms could be delayed. This would mean the alarm times could be delayed while the sequencer is active. Quote
ragglefrock Posted January 6, 2009 Report Posted January 6, 2009 QUOTE (Yair @ Jan 5 2009, 01:17 PM) The problem with absolute time is that at least in Windows the timer has a ~16 ms resolution.In Windows, you can get sub-ms resolution by calling the performance counter API functions and there should be some examples VIs in the forums. You should be able to do something similar in other OSes. I didn't understand your desired architecture exactly, but it sounds to me like the most practical solution would be using a timeout mechanism. You can do this with an event structure's timeout event or with any of the synchronization primitives. This makes LabVIEW wait the desired time and allows you to break the wait if needed. The Timeout architecture would be perfect and easy to implement, but I don't know of any APIs that give microsecond timeout resolution. Quote
jdunham Posted January 6, 2009 Report Posted January 6, 2009 QUOTE (brianafischer @ Jan 5 2009, 01:45 PM) The use case is a simple example that I created, not a real-world implementation. The main design question is how to obtain an accurate sub-msec timing in a sequencer where events may be scheduled at varying times without an extremely resource-intensive polling loop. The problem is that in the real world, the Windows/Mac/Linux OSes don't guarantee response time (that is, they are not "deterministic"). If you use some LV timeout operation and ask for 10msec, you'll *probably* get control back in about 10ms (unless Windows starts re-indexing your hard drive, or someone opens Excel, or...). Even if you could ask for 10usec response, the system's ability to return to your task in that time is a crapshoot. This problem can be solved with LabVIEW Real-Time, and the special hardware needed to run it, but that toolset is kind of spendy. The next step down is to use the LabVIEW Timed Loop and a DAQ card with a counter/timer, but you are still at the mercy of the OS. The lack of determinisim is why it's useful to use the OS System clock for your timing. If your timeout is continually late (it will never be early) then the errors will accumulate. But if you constantly check the time of day or the millisecond tick count, then you can correct for this. On the other hand, polling always gets a bad name, but your polling loop may not be totally resource-intensive. Don't forget that the CPU is usually running NOOPs most of the time anyway, or else the OS is doing low-level polling operations. If your task is low-priority, polling is probably not a big deal, unless you are trying to do power management. Of course if your task is low priority, you won't get the deterministic response you crave. The other issue is figuring out what to poll to measure time. You might be able to poll the Program Counter of your CPU (which counts clock cycles) but I don't remember how to do that. Quote
PaulL Posted January 7, 2009 Report Posted January 7, 2009 The O/S timing resolution is certainly a problem for submillisecond timing. As far as not polling goes, I actually have done this using shared variable events. I execute a timer method in its own thread (and this in turn calls the Elapsed Time express VI), passing it the urls of shared variables (timeHasElapsed, timeTarget, stopTimer) for the particular timed process. I register for events on the timeHasElapsed shared variable to trigger responses in the application. I previously talked about this here: Newbie-needs-help-with-timer-control. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.