From 04:00 PM CDT – 08:00 PM CDT (09:00 PM UTC – 01:00 AM UTC) Tuesday, April 16, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Two vs Three Loop Architecture

I have a real time application that is running on a compact Field Point controller.  The application has three tasks:  dynamically control a test stand, log data to file (on the removable compact flash on the cFP-2220), and communicate with a host computer for user interface and start/stop control.  I've tested all three parts separately and found that the slowest update I can tolerate in the control loop is ~50ms before I drive the PID unstable, but I only need to log data every 1000ms.  This naturally led me to a three loop architecture with Control, Write Data, and Communication loops all running at different periods and priorities.  In this configuratoin I'm using about 83% of the cFP's processor while the VI is running and I occasionally lose the ethernet connection as usage spikes to 100%.  Would it be beneficial (in terms of reliability) to rework the code to use only two loops? 

 

Also, I'm using shared variables to pass data between the three loops, but I've read on this forum that variables are to be avoided (link). To quote the poster:

 

"Never use variables of any kind since they are prone to race conditions!"

~Norbert B

 

I've implemented an RT FIFO to stop the loops as it is cleaner than multiple boolean variables, but I fail to see how a low-level FIFO would be any different (in regards to race conditions) than a single-process variable when passing something like a double array between the Control and Write Data loops.

 

And just one last question:  Is it a bad idea to read the same channel of an input module in two parallel loops running at different priorities and periods?

 

Thanks for reading all that!  

CLAD
0 Kudos
Message 1 of 15
(3,300 Views)

For passing data between your loops I would suggest looking up queue data structures and/or action engines there is plenty of info on both on the forums.

 

As for the number of loops, it is not uncommon to have several loops. often set up in pairs as a fast aquisition loop and a slower processing loop (queued master slave architecture) One pair as a GUI handler, another pair as a data collection and processing handler, and a third pair as communication between devices or other computers on a network. From your description, I would probably use three loops as well. The high processor usage may be derived from inefficiencies in collecting and communicating data. A common problem is to open, write and close the connection in every iteration, whereas it is better to open and close outside the loop and process in the loop.

 

There are acceptable uses for variables, although they should be renamed, as they act differently to the expected behaviour of "variables". In this situation, you shouldn't need to use them if you implement other data sharing.

 

If you share a resource, the other loop will be waiting for it to be available and will make it seem like the program is hanging. You should read the data once then make it available to the other loop in your data sharing.

_____________________________
- Cheers, Ed
Message 2 of 15
(3,262 Views)

"I'm using shared variables to pass data between the three loops"

Don't do that. Share variables are not designed for that, although they can be used for that. The basic reasons is they are slow and can cause race conditions and they make data copies.

Use a queue or functional global as mentioned. If you use a queue, do not use it's name to call it. Use the reference.

The write to disk and the user interface should be using only a small percent of the CPU, although you have not mention how big is your file, and what type of file it is.

 

So be sure that your CPU is used at the loop you need. Two loops will not help you. Coding style is everything.

 

 "Is it a bad idea to read the same channel of an input module in two parallel loops running at different priorities and periods?"

Usually yes. Why you want to do this? Read it in one loop and send the data to the other if needed.

 

Hope it helps

 

0 Kudos
Message 3 of 15
(3,245 Views)

Thank you both for your replies.

 

Would a RT FIFO be able to fulfill the same function as a queue?

 

I am controlling shaft speed and pressure of a pump and therefore need to read values for rpm and pressure at a rate sufficient to permit dynamic control.  I also need to log these data, but I only need to log them once per second.  Thus I wanted to gather data from the cFP modules in two loops.  Only the control data overlaps, so if I were to read all channels in the high priority loop I'd be throwing away most of the data.  I could certaintly pass the control data to the middle priority loop.

 

This control/data collection application is one state of a larger VI.  There are three shared variables in this state that I will try eliminating with a functional global.  The other difference between this VI and others I've successfully written for the cFP is the number of shift registers.  I don't know if that could be over taxing the system, but I have 10 SRs in the top loop, 5 in the middle loop, and 2 in the lower loop.

 

Thanks again for the info. 

CLAD
0 Kudos
Message 4 of 15
(3,201 Views)

Shift registers are very very fast and good to be used. The only problem you can have from them, whould be if they cary a huge amound of data.

 

0 Kudos
Message 5 of 15
(3,184 Views)
So I have two data points that I'm reading fromthe current input module, Inlet Pressure and DIscharge Pressure, that both need to be logged and used for control.  If I read just those two channels in the top loop and pass them to the middle loop, I still have to read the rest of the channels on that module in the middle loop.  Wouldn't this be the same problem as reading those two channels in both loops?
CLAD
0 Kudos
Message 6 of 15
(3,174 Views)

I am not familiar with your hardware, but i guess that if you read one channel, then you have to wait for the reading to finish before you do another one.

If the above is true, i whould put all the reading stuff in one loop. Using a shift register and a case structure, you can determine how often the slower readings should be made.

This way you will always know the sequence of your data reading.

0 Kudos
Message 7 of 15
(3,129 Views)

testingHotAir wrote:
So I have two data points that I'm reading fromthe current input module, Inlet Pressure and DIscharge Pressure, that both need to be logged and used for control.  If I read just those two channels in the top loop and pass them to the middle loop, I still have to read the rest of the channels on that module in the middle loop.  Wouldn't this be the same problem as reading those two channels in both loops?

In this situation I suggest you read your data points in the faster control loop and write them to a notifier.  In your data logging loop read, read the values from the notifier.  Your logging loop will have the most recent value, your control loop will run at full speed, and you only need to read from the input module in one place.

0 Kudos
Message 8 of 15
(3,115 Views)

Wow, you guys were right.  I replaced all my variables with functional global variables and RT FIFOs and moved all read/write activities into the top level loop and reduced my processor usage by 30%. 

 

Now I need to figure out why I have one FIFO overflowing unexpectedly and why another FIFO doesn't seem to be transferring data between loops.

 

Thanks for all your help!

CLAD
0 Kudos
Message 9 of 15
(3,096 Views)

Ok...now I have a FIFO problem.  I've attached screenshots of the block diagram and front panel of the test VI I'm working with.  The VI just has three timed loops at different priorities and periods, like my real application, and I'm just trying to pass a 4x8 array of doubles from the top loop to the middle loop using the RT FIFO.  The front panel showes the results of running the VI; the "appended array" is the indicator on the RT FIFO write "element" terminal and the "element out" array is the result coming out of the FIFO read.  Why aren't all the values being written being recieved? 

 

Thanks.

 

 

 

 

 

Message Edited by testingHotAir on 03-10-2009 04:13 PM
CLAD
0 Kudos
Message 10 of 15
(3,082 Views)