08-06-2013 10:13 PM
WOW! I was not expecting this at all. You are beyond awesome. Thank you so much. I will take a deeper look at it tomorrow but so far I can tell how it works and it does all seem to make sense. Thanks again.
08-07-2013 11:57 AM
nathand,
I applied the changes you made and it works like a charm. However, there are a few issues that concern me. The vi as you supplied it was not saving in seperate columns for each channel so I made some additions. Another issue I have seen is the presence of extra unneccesary zeros in the data being logged. These zeros are in fact not data being collected but rather an indicator that there was no data present. However, that could be misconstrued as actual data and cause confusion. I understand that it is due to the initilized array of zero values and then it outputting zeros when there is no data. Is there a way of initilizing an empty array and also ensuring that when there is no new data that the last "sampled" data is "held"? I know you have done plenty already and I really appreciate it.
08-07-2013 12:03 PM
The way I set it up, with the data in the shift register, the only time you will get invalid 0 data is if the data gets logged before data is received on a channel. Once data is received on a channel, it will stay in that array until it is overwritten by new data on the same channel. If that's not how it's working for you - for example if you didn't use a shift register - then it would help if you upload your modified VI so I can see what you're doing.
I don't know about the separate columns, I have no previous experience with TDMS. I'd have to experiment with it a bit to see what's happening.
08-07-2013 12:16 PM
I pretty much just added your modified code as it was with a few changes. I also attached some data. The only channel that should have zeros is the second column in the excel file.
08-07-2013 12:32 PM - edited 08-07-2013 12:36 PM
About the spurious 0s in your data - look carefully at what you're doing! I think that the problem is that you always put something in the queue, even if there is not a full CAN packet to read from the FIFO. Try moving the Enqueue into the case structure.
Don't put obtain queue in the loop - each new obtain queue opens a new reference that you never dispose of, which will lead to steadily increasing memory use. Just grab the queue wire from the obtain queue outside the loop, and branch that into the upper loop.
The TDMS issue is much easier than adding a for loop. Remove the for loops and array manipulation, and wire the mode (terminal at the top of TDMS Write) to be "interleaved" instead of leaving it unwired which causes it to default to "decimated."
EDIT: also, there's no need for the 10ms timer in the bottom loop. As I mentioned previously, the dequeue will handle timing because the timeout is unwired - it will wait until there's data available, however long that happens to be. Once you fix the upper loop so that it only enqueues data when there's a CAN packet to send, this should work well. However, you may want to move the Release Queue function to outside the upper loop or otherwise work out the timing because as I have it, if no CAN packets are received then it won't exit when you hit the stop button because the queue will continue waiting forever. Releasing the queue causes any queue functions that are waiting on it to complete, returning an error saying the queue reference is no longer valid. You may want to handle that error in some way because the dequeue will also return an empty array, which you won't want accidentally added to the data file.
08-07-2013 01:49 PM - edited 08-07-2013 01:59 PM
I made the changes and that definitely helped with the stop button problem I was experiencing. The zeros were reduced but are still present. I think the problem lies in that sometimes the packet of data is not in the proper order. In other words, when the convert frame to channel vi receives the message ID, sometimes it is actually reading in one of the other elements. Likewise, at times it is fed frame data that is not actually frame data. How can I ensure that the packets of data are sent in the proper order?
EDIT: I take that back. The out of order packets are only present if I'm using the highlight tool.
08-07-2013 02:02 PM
Again, please upload the latest version of your VI. It might be useful to see the FPGA side, too, to see how you're putting data into the FIFO (although I expect that's straightforward).
I would change the CAN Frame Read loop so that it always enqueues one entire CAN packet. If there are more than 6 elements to read in the FIFO, read those elements, enqueue them, and loop again. Right now you might be enqueueing more than one packet, in which case the remaining data will either cause problems or get discarded. I don't know what the CAN frame channel conversion library will do if it receives a longer input array than expected, but perhaps it's adding extra elements to the output in that situation. If the queue ever fills on the FPGA side, that could lead to incomplete packets too, but I think that's less likely unless your FIFO sizes are small and your packets are arriving very quickly.
08-07-2013 02:09 PM
I think I am enqueueing more than one packet. I included the FPGA.
08-07-2013 02:16 PM
Try it with only enqueuing one packet at a time.
You might also want to make the logging a bit more sophisticated, if the goal is to write once every time interval rather than once every 10 packets. One way to do this would be to use the timestamp from the CAN packet. Every time you write to the file, store the timestamp in a shift register. Each time you receive a packet, compare the timestamp with the saved value from the shift register. If the difference is greater than the time interval for logging, then write to the file and update the shift register value.
08-07-2013 02:48 PM - edited 08-07-2013 03:05 PM
I think I know for certain what is causing the problem. It is not the number of elements enqueued but rather it is the output from the frame to channel conversion block. It always outputs an array with a total number of elements equal to the message with the largest number of channels. In my case, that would be five elements. That means that when messge 1, which has only 2 elements, is processed the FtoC block outputs an array with five elements with the first element starting at index 0. Thus, the replace array block sees that there is "data" for indices 2 through 4 and writes over the actual data with zeros. The same does not apply to message 3 because it starts at index 7 and has nothing to write over. I hope that made sense.
With that being said, how can I have the output array from the FtoC block take on the size of the message being currently processed?
EDIT: The problem was fixed by adding the get number of channels vi and sending that to a reshape array block.
I'd like to thank all of those who contributed to the posting. Thank you for your help. Especially nathand for going the extra mile. With the changes suggested I now have a data logger that only requires changing which file to use as a database.