05-31-2023 04:51 AM
Hello everyone,
I have an application that reads from some indicators of the front panel and it stores the data of the indicators in a csv files according the the timestamp recorded at the moment. The application is based on QMH, the data is enqueued and sent to another module that writes the csv files. The refresh rate of the indicators is set in the comms loop to 1s. This is the timestamp of the file I obtain:
It looks like the recording is being executed every second but the "Get Date/Time in seconds" function is not returning the actual value...some of them are repeated. I have checked closely this function and what is happening is that the time is not exact the milliseconds have an e 11:28:09.701 -> 11:28:09, I guess over time it gets a moment when the value "jumps" to the next value.
Is there a better way to get the time?
05-31-2023 04:58 AM
Hello,
You can use the ms data if more precision is needed in your log.
As using windows engine and nor RTE you can face some ms discrepancy thus leading to what you see.
Seeing your log I am not sure you have 1 value per second but something like 0,95 value per second (...:29 and ...:34 are missing even by correcting the duplicates).
05-31-2023 12:04 PM
Can you attach your code?
06-02-2023 02:47 PM
What "governs" the loop that contains the time measurement? Also, how are you "acquiring" time?
LabVIEW is generally pretty good handling Time -- it has its own "Time" variable (called a TimeStamp, which has a theoretical precision that is "unreasonably high" (I worked it out, once, but it is shorter, I believe, than an attosecond, a nano-nanosecond, not to be confused with a nanu-nanu second). It is your responsibility to structure your code "as best you can" to make the code run as close to the hardware time precision as possible. This means using DAQ hardware for time signals, better than Wait until Next ms Multiple, better than Wait (ms), and maybe using a Frame sequence to "anchor" the Wait at the beginning or end of the loop. Another thing to do is to save Time with a little bit more precision than you require, "just to see" if there are unexpected "wobbles" in the timing.
If you had posted your code (preferably in a version no more recent than LabVIEW 2021), we could be more helpful.
Bob Schor
06-06-2023 02:30 AM
The program is too big to share here, but I will share the function I created to time the loop. Previously the function used to this purpose was "Elapsed Time" in the Timing palette, but it wasn't working properly. So I created the attached function (RT_Timer.vi) to emulate the behavior of "Elapsed Time". However the behavior I get is the one presented.
The program used "Elapsed Time" to give a True value to a case structure with a snippet of code that reads the acquisition data from a registers (Read_Register_Timestamp.vi). The data generated by this function is enqueued to be stored in a file by another loop.
This code is integrated into the state of the message handling loop "Update Read", where all indicators are updated.
I hope this explanation will help to better understand how it works.
06-06-2023 11:09 AM
One of the reasons to ask to see all of the code is that I cannot envision a situation where a well-designed DAQ loop governed by hardware timers set to run at 1 Hz would not accurately run at 1 Hz. I could imagine all kinds of ways that accurately-recorded 1 Hz data could be "packaged" and sent to other loops (in a QMH or elsewhere) with a TimeStamp value generated who-knows-where (but quite possibly not synchronously with the DAQ loop).
As an example, consider a simple Producer/Consumer Loop. The Producer "produces" 1000 points at 1 kHz and enqueues it to a Consumer. The Consumer does a bunch of data processing that takes a chunk of time, then writes the data, appending a TimeStamp. The time in the TimeStamp will be a pretty accurate estimate of when the data were saved, but not as good an estimate of when they were acquired.
I think that is what is going on with your code. Find the "Time Leak" -- it is undoubtedly "buried" in a too-large, too-busy loop.
Bob Schor
06-07-2023 10:20 AM
I would simplify to something like this.
06-08-2023 12:47 AM
Hello everyone,
I finally got the solution to get the right timestamp. A separated loop with a subVI that reads the indicator values and adds the timestamp, then the values are enqueued. However, I've tried to pass the time with a local variable to the clock but I'm getting a "Not enough memory" error. This way is functional, but I can't edit the time of the acquisition loop.