01-07-2011 02:10 AM
Hi everyone,
I am trying to put together a simple code to read a specified number of data into an array at a fixed sample rate and put this data into a local variable. I am going to implement this on a NI cRIO-9073 using the Scan Engine and the data is coming from a NI 9208 with a scan rate of about 250Hz, though that's not really important at the moment.
I have made this small test VI which I suspect contains a memory leak, but I'm not able to spot it. The reason for my suspicion is that when I run the vi on a VMWare virtual machine (LabVIEW 2010 on WinXP) it soon claims that it is running out of memory. Of course, the problem might be somewhere else, but I am hoping someone more experienced with LabVIEW programming will be able to spot any bugs very easily as it's really a very simpel piece of code. 🙂
I've included a copy of the VI together with a screenshot to illustrate.
Best regards, Martin
PS. My code seems a bit clumsy, so if anyone have a better solutions I would be very happy to learn about it!
Solved! Go to Solution.
01-07-2011 10:31 AM
Hello Martin,
I would try a different approach to your problem. Currently you are reshaping your array every iteration of the loop. This means that the LV memory allocator has to find a new piece of contiguous memory every loop iteration. You're probably fragmenting your memory and therefore running out of contiguous blocks of memory leading to the out of memory messages.
For these types of tasks, I recommend having a fixed size array that you initialize outside the loop and then use the Replace Array Subset function within the loop to update the values. This avoids the memory allocation issue you're running into.
Alternately, since I suspect you're using the local variable to pass the data to another loop, you can use an RT FIFO to handle the data. An RT FIFO is like a LV queue, but it's designed so you can preserve determinism in your application. Set up an acquisition loop that dumps data from the 9208 every 4ms into an RT FIFO. Then set up your processing loop to run at a slower rate - say every 200ms. The processing loop can read all of the elements out of the FIFO until it's empty every 200ms or a set number of samples. The RT FIFO is of fixed size, so you need to make it large enough to fit at least 200/4 = 50 samples. To be safe, you should make it several times larger, perhaps 200 samples. You can try different sizes of the FIFO and also different periods of your processing loop depending on your application requirements.
Using this method keeps you from having to create a counter to track the elements, since the FIFO Read function can tell you how many elements are in the FIFO and also when it's empty.
I recommend checking out the RT FIFO Communication example that ships with LabVIEW to get an idea of how to use these functions.
Gerardo
01-10-2011 04:15 AM
Hi Gerardo,
Many thanks for your reply. The memory allocation theory seems very plausible. I'll rewrite my example and let it run for a while - just to make sure that the problem is fixed.
I am also very interested in learning more about the RT FIFO, which I understand is the best way of passing large amount of data from the FPGA to the RT-controller. There is still a lot of details I don't yet understand about how the FIFO works (which is the main reason I am not using the FPGA at the moment), so I'd be very happy if someone could help me clarify a few things.
The actual data I am going to read from the NI 9208 is the pressures in the cylinders of a reciprocating engine. The engine runs at relatively constant speed of around 12.5 Hz. The engine has 4 cylinders, and I am measuring two pressures per cylinder (both above and below the pistons), so I have 8 pressure transmitters in total. I will be happy with about 20 samples per 360 deg, which gives me a sample rate of about 250 Hz. At the moment I have no way of determining the positions of the pistons and the engine speed will vary somewhat, so I would like to work with pressure data from 3-4 revolutions, so let's say that adds up to 64 samples per cylinder, or 512 samples total.
Some of things I am wondering about are:
1. Is there an easy way to add and and read these data as a 2-dimensional array (8x64) to the FIFO, or will I have to put the data into a 1-dimensional array, and split the data "manually" after reading?
2. Will the data in the FIFO only be replaced after I have read them, or will they be replaced continuously with the sampling rate?
Best regards,
Martin
01-10-2011 04:48 PM
Hello Martin,
I believe you have two different types of FIFOs confused. There are the RT FIFO functions (Create, Write, Read, Delete) that are used to pass data between loops in a RT VI. These FIFOs have nothing to do with the FPGA. I encourage you to check out the documentation on these such as this.
The FIFOs you refer to are FPGA DMA FIFOs, which are resources used to pass data between an FPGA VI and a host VI (RT VI in the case of cRIO). FPGA DMA FIFOs are tied to physical resources (DMA channels supported by the hardware). Here's some more documentation. There are plenty of examples of using DMA FIFOs that ship with the LabVIEW FPGA Module. Note that when you use the scan engine, some of these DMA channels are used without your explicit instruction.
Now that we've cleared that up (I hope), back to your questions...
1. Is there an easy way to add and and read these data as a 2-dimensional array (8x64) to the FIFO, or will I have to put the data into a 1-dimensional array, and split the data "manually" after reading?
Using the scan engine, you always access the data one sample at a time. It's probably most efficient to put this into a 1-D Array and then pass it to an RT FIFO. You would configure the FIFO to be of 1-D Array type with 8 elements. The size of the FIFO could fit N number of these. If you want to work with 64 at a time, perhaps make the N = 128 and in your processing loop, read the RT FIFO 64 times to get your 512 samples, process, and repeat.
There is also a way to access one sample for multiple channels in a 1D array so you can avoid having to build an array yourself. I haven't tried it, but there's some documentation here
2. Will the data in the FIFO only be replaced after I have read them, or will they be replaced continuously with the sampling rate?
You can configure the behavior of the RT FIFO Write if the FIFO is full. There is a timeout parameter and you can decide whether or not to overwrite if the Write function timed out. Additionally, the RT FIFO Read function has a boolean output to monitor if the FIFO is empty.
When using the FIFO, it's best to monitor the timeout and empty flags of these functions.
I went ahead and attached a sample VI of the concepts. I haven't had a chance to try it so you'll have to test it out, but hopefully you get the idea.
01-11-2011 05:39 AM
Excellent! Thank you very much for taking the time to explain this to me! I'll stick with the RT-VIs for now and come back to FPGAs when I'm more familiar with how the RT works.
Best regards,
Martin