12-06-2012 08:48 AM
I have a .vi that I am reading two different sensors that operate at different sampling rates. I am able to read both of these, however, there appears to be some strange timing/lag issues with the devices. The first device is a GPS unit operating at 5Hz. This is convenient as GPS time is included in the data I am reading. The other device is a sensor operating at 6Hz. Ideally, I'm trying to log the data from both of these devices to the same file. An example is attached. It appears it's collecting the GPS data, although it appears to write it at some much lower rate. Strangely, while it's writing to the file, it will slowly store "chunks" of data in order at a much lower rate. It seems like a buffer get's full, and then it jumps ahead by about 5 seconds (see lines 214-220 of attached file). All the while, the 6Hz sensor data is getting logged normally. I'm stumped. Would it be best to log these as separate data sets in separate files? Thus creating two "parallel" read/write executions within the same .vi?
Any help, or examples, would be much appreciated!
Solved! Go to Solution.
12-06-2012 10:24 AM
We really cannot tell how your VI works from looking at the data. Please post the VI.
Clearly you cannot fully synchronize two data sets sampled at different rates. Also RS-232 serial ports are asynchronous, so you cannot be guaranteed that the data will always arrive on time.
What do you want? Suppose one source produces data a0, a1, a2, a3, a4 in one second and the other source produces b0, b1, b2, b3, b4, b5 in the same second. What should the file look like?
Lynn
12-06-2012 11:14 AM
Lynn,
After posting, I began to think about the issue of "how it would look" in the file. I decided now to log the data from each sensor in individual files, with system time included in each to synchronize the data. I think that will make it work. I'll post the .vi in a bit after I've had a chance to test and "clean it up".
Thanks,
Jordan
12-06-2012 02:04 PM
Updated the VI to log data from each device into it's own file. Issue now is with the "*_GPS.csv" file. There are two times contained within this file, a GPS time that is the GPS time reported from the RS-232 GPS device, and a system time from the host machine. Each 1 second of elapsed GPS time actually takes about 3 seconds. After a while, there is a sudden jump in the GPS time to "catch up" to actual time (see lines 49 and 82). I know the GPS device is working correctly and accurately reporting the GPS time as I have verified by monitoring with Tera Term. I suspect it's a loop/timing issue, but am not sure how to resolve.
Any thoughts/feedback would be appreciated!
12-06-2012 02:10 PM - edited 12-06-2012 02:10 PM
GPS file attached as .txt. Website wouldn't let me attach as .csv???
12-06-2012 07:45 PM
Jordan,
Does your neck get sore from swinging your head around on the giant screen to see your block diagram? The style guides recommend keeping the code to the size of one screen.
I calculated the derivative of the time columns and noticed that the system clock column is consistently 3-4 times longer than the GPS column. I think this means that you are missing data.
The way your program is written, the loop iteration rate is limited by the slower of the two parallel processes. Each process reads its serial port, regardless of whether a complete mesage is there or not, parses it and writes to its file. Since the system clock timestamps in the file tend to be about 0.7 s apart, I think that the loop takes about that long to iterate. Does the GPS loop count indicator show about 1.3 times elapsed time or 5 times elapsed time?
Some things to consider:
- You have termination characters enabled. If your serial devices are sending termination characters, use them to end the reads and get rid of the Bytes at Port nodes. You should never use both at the same time - they fight each other.
- Your parsing can probably be simplified by using Spreadsheet String to Array with a comma delimiter and %s format. Then use an expanded Index Array to get the substrings.
- Writing to file can introduce unpredictable timing because the OS controls when things happen. If a file needs to be fragmented or moved, the time can be much longer than it would for writing a similar amount of data.
- You do not need the sequence structure. Dataflow will take care of everything. The only real change required without it is to run the error wires through the while loops with the VISA Resource controls.
- Speaking of those loops: The lower loop with OSM Resource Name will always run exactly one time and quit immediately.
I suggest that you look at the various architectures which provide parallel loops, such as the Producer/Consumer (Data) design pattern. With that you would separate the serial reads into separate loops of their own. The data wold be parsed and written to files at different rates (and possibly bigger "chunks") than you are doing now. The data is passed between loops via queues. With such an architecture the data is read from the remote devices at the rate they send it. The parsing and file writes can take place at significantly different rates without loss of data.
Lynn
12-07-2012 09:23 AM
@johnsold wrote:
Jordan,
Does your neck get sore from swinging your head around on the giant screen to see your block diagram? The style guides recommend keeping the code to the size of one screen.
Yes!
As I previously mentioned, the data logged in the GPS file seems to contain sequential data. In other words, it captures the incremental GPS updates (5Hz) but writes them slower than they're being reported. It seems like this data is stored in a buffer and is written incrementally for as long as it can keep up, finally it seems like the buffer gets full and then you seem the jumps in GPS time. This is where the missing data
@johnsold wrote:
I calculated the derivative of the time columns and noticed that the system clock column is consistently 3-4 times longer than the GPS column. I think this means that you are missing data.
@johnsold wrote:
The way your program is written, the loop iteration rate is limited by the slower of the two parallel processes. Each process reads its serial port, regardless of whether a complete mesage is there or not, parses it and writes to its file. Since the system clock timestamps in the file tend to be about 0.7 s apart, I think that the loop takes about that long to iterate. Does the GPS loop count indicator show about 1.3 times elapsed time or 5 times elapsed time?
I would say about 1.3.
Thanks for the tips! When wiring into the "array type" of the "Spreadsheet String To Array", it defaults to Double. How do you change it to String?
@johnsold wrote:
Some things to consider:
- You have termination characters enabled. If your serial devices are sending termination characters, use them to end the reads and get rid of the Bytes at Port nodes. You should never use both at the same time - they fight each other.
- Your parsing can probably be simplified by using Spreadsheet String to Array with a comma delimiter and %s format. Then use an expanded Index Array to get the substrings.
- Writing to file can introduce unpredictable timing because the OS controls when things happen. If a file needs to be fragmented or moved, the time can be much longer than it would for writing a similar amount of data.
- You do not need the sequence structure. Dataflow will take care of everything. The only real change required without it is to run the error wires through the while loops with the VISA Resource controls.
- Speaking of those loops: The lower loop with OSM Resource Name will always run exactly one time and quit immediately.
12-07-2012 10:06 AM
Jordan,
I think you are right about a buffer filling up.
The 1.3 factor indicates that the system clock times in the file reflect the actual rate at which the loop iterates. Since the GPS is generating data at 5 Hz and you are reading and recording it at 1.3 Hz, eventually you will lose data.
You need to do two things to make Spreadsheet String to Array produce a string array. Both are shown at the bottom of the image I posted. The format string is "%f" and the data type wired to the array type input is a 1D array of strings. Event though the input shows a double default datatype, it is actually a polymorphic input. When you wire a string array to it, it automatically chages to that datatype. The detailed help for the function mentions this, although it is not worded in such a way as to be obvious to someone not familiar with the concept.
Lynn
12-07-2012 10:20 AM
Lynn,
I have it setup similar to your example, but the array type does not automatically switch to string, rather it shows as double array type.
12-07-2012 11:30 AM
Jordan,
You need to create the empty string array manually and then connect it. Drop an array constant on the block diagram. Then drop a string constant into the element box of the array constant. You then have srting array with no data in it. Wire that to the default datatype input of the Spreadsheet String to Array function.
Lynn