Hello all. We have developed a Labview program that allows us to take gas flow meter measurements. The program is developed using a cDAQ-9188 and the modules 9401,9221, and 9211. The program works great.
We want to put the same program on a cRIO chassis, using the same C-series modules. The chassis we have is a cRIO-9104 with a cRIO-9014 controller. This is so we can have the program run even if our regular PC messes up on us.
Naturally this requires to recoding to make the program cRIO-compatible. An issue we are having is deciding whether to put our timer code on the controller or in the FPGA. We know the FPGA has limited resources, so we don't want to overload it. We already have the FPGA giving out three analog values that are sent to the host; the values come from the 9221 and 9211. Our timing code, which involves the 9401 seems quite extensive, and we worry if we will overrun the FPGA.
Our present cRIO setup has the timing code in the host, while the FPGA handles the 9221 and 9211 values. When we run the host vi, the values from the 9221 and 9211 display fine. However, when we click the Reading boolean on the host vi, things get crazy.. The Boolean opens the case statement which lets the timing code run. The values that are to be shown from the case statement display very erratically (i.e. showing three sequential values then stopping for a while, then showing more values later). Worse, the temperatures and converted voltages from the 9221 and 9211 stop updating altogether. Looks like the case statement loops hog the system.
We have a Windows PC vi built also, which will be the vi we will run from the PC once we get the RT and FPGA vi's working. The Windows PC vi has a few network variables, controls, and indicators, but it doesn't even update until we press the Stop button.
What are you thoughts on how to make this work better? Is the timing code just bad altogether, or will moving it to the FPGA solve the problem?
Please see the attachments.
VIs in cRIO Rate zip:
Windows Main -- the VI that will run on the Windows PC
RT Main -- the VI on the 9014 controller.
cRIO Pulse-Temp -- the VI running on the FPGA
Rate -- this VI is the cDAQ version that we currently use. Just attached for reference.
You will see a lot of shared variables and controls ORed in RT Main. This allows us to control the RT vi and the Windows VI without a bunch of code deletion and insertion while we are debugging. The controls and indicators in RT Main will be removed and replaced by the shared variables once we get RT Main and Pulse-Temp working correctly.
The case statement in RT Main is where the big action is. It has two loops. The Pulse Counter loop runs the 9401 in Scan Mode. The unlabeled loop is the timer loop that starts a timer once enabled, then stops once Pulse Counter hits 100.
Now, of the two While loops in the main program, the bottom while loop that contains the Analog nodes gives the tell-tale signs that something is wrong. Normally when the program runs, these three values display and update quite rapidly. When we click that Boolean and the Case Statement in the top While Loop goes to True, it seems the bottom While loop freezes, and the timer and pulses indicators update sporadically.
Solved! Go to Solution.
This is a fairly common task to do on the FPGA. Here's another thread where I helped someone else achieve similar behavior (measuring an event rate)
jg69: Thanks for that. I put a Wait Multiples with a constant of 0 in the Windows vi and the main loop of the RT vi.
I originally had the counter code on the FPGA, but the problem with having it there is two-fold:
1. The data would not pass over into the RT vi. My Read/Write control originally had a "Pulses" element which went to an indicator, but that indicator never showed any values when the program ran until I moved it into the RT target vi.
2. The timing code and the counter code actually need to be together as they are critically connected. Pulses tell the timer when to stop, and they need to have no delays between them. Pulses and the timer need to be as in sync and exact as possible. I didn't want to risk any data variability with having the two code pieces on different hardware. I know the FPGA runs very fast, and the RT controller is close behind it. So if I move the counter code back to the FPGA, it would be best to have the timing code go with it, but can the FPGA handle all that? It is already running the analog inputs from the 9221 and 9211.
nanocyte. Thanks for the link. I see you use a SCTL, which looks a little like my Pulse Counter loop. I didn't know if a SCTL would run too fast. The counter needs to be in sync with the timer. I thought of using a SCTL for the timer and the counter, but I don't know if both of those can go in a SCTL, and since we can't have more than one SCTL, I am at a standstill on how to handle this.
Analog-In is not something that needs many resources in FPGA. Don't be to scared to put code inside the FPGA. Try and see how many resources are really needed when compiling the code.
Currently you are reading and transfering the Digital-In to your RT-code via scan engine which is kind of slow (<= 1kHz) compared to the speed you could reach inside the FPGA.
Ok, I put the counter code in the FPGA. It worked too; the pulses were counted and displayed as the flow meter ran. I'll be looking at the resources windows more often. I had not looked at them before. Now I have a metric to look at. Thanks.
Oh, but now I have one BIG problem. When I click the Boolean to run the counter, the other values stop updating. Now that I think about it, we had this problem before with a module like the 9401 locking up the chassis when counters were used. Wait though, the FPGA doesn't have a counter, so why would the 9401 cause the values to stop updating?
How shall I know? As far as I understand you drastically changed your code. Now something is not working - so share your new code with us.
Hello all again. I figured out something that fixed the Analog indicator update problem, but I don't know why this worked. I put the Analog I/Os in a separate While Loop. Then when I ran the FPGA vi, everything updated like I desired. So, why would the Analog I/Os not update when they were in the same loop with the Digital I/O?
This is made even more strange to me because the Digital I/O was in its own While Loop inside the main While Loop. The Analog I/Os were just inside the main While Loop.
My next problem which is related to this is the "timer" part of my program. I had mentioned that the timer and the counter need to be together, as they are critically connected. Well, the FGPA can not work with my timer code as it is. I get an error stating that the "Wire type is not supported", and this error appears on the wire from the Get Date/Time In Seconds VI. So I have to make a timer that works for FPGA. I looked at nanocyte's solution, and the answer here appears to be a SCTL. I put this in the FPGA VI, but when I use the Tick Counter Express VI set for msec, I get 0. All I have in the SCTL is the Tick Counter and an indicator. I need to convert the msec value to regular seconds anyway, but why am I getting a 0 in the indicator?