LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

NI9217 FPGA timing

Hi there, I'm starting to build a new application using 2 cRIO-9002/9102 systems, each with 7 NI9217 and 1 NI9401 modules for RTD data acquisition and heater control using the 9401 modules...eventually its going to be a more complex setup but right now I'm working on getting one RTD channel to sync and output data as I'd like it to.  I'm basically new to LabVIEW and have been looking through all of the FPGA training info, KB examples, and forum articles here and have managed to get a basic program running, but I have a few questions that I haven't been able to find answers to anywhere else so hopefully someone can help me out.  I've attached my FPGA and host VIs for reference (I think...), though they're really just modified versions of the 9217 shipping example.  I'm running on LabVIEW 8.2 and FPGA Module 8.2. First, a few questions to make sure I understand why the example is doing things the way that it is...

1) In the host VI, right at the start there is a sequence of passing the loop timer count, then an FPGA run command.  I'm guessing this is to initialize the loop and deal with the whole first loop cycle anomoly issue?

2) In the example, the LSB weight and offset are calculated outside the loop, I'm assuming this is so they're only calculated once and not every single loop cycle? Is that just a time savings or is it also more efficient on the FPGA?

Ok, on to the real question...I have the 9217 set in high res mode with a single RTD, so I should be getting 5Hz sample rate out of it, but when I set the loop timer to 200ms I get odd results.  Specifically, the delta t between each sample is 203.125ms, 203.125ms, 203.125ms, 203.125ms, 187.5ms...I've found that as I change the loop timer to various values I get different uniformity in the delta t, for example at 250ms they're all the same...I'm guessing this has to do with one of several things.  One, right now I'm running the host VI on my local PC, not on the RIO itself.  Two, I'm not really sure if how I'm doing the actual timing measurement is correct, its getting me a time but its likely not optimal method...should I be doing that on the FPGA directly somehow?

In the long run, we don't really need very highly accurate timing for our application since we're ultimately going to be sampling at only 1.25Hz on the 9217s, but I'd still like to set up the timing for the highest accuracy I can manage at the start so I can understand how the different portions of my code affect timing and synchronization.  I'd appreciate any suggestions anyone can provide as I'd like to really understand all this before I start adding all the other modules/channels into the mix.

Thanks!

-Greg
Download All
0 Kudos
Message 1 of 14
(7,000 Views)

Hi Greg,

Thanks for contacting National Instruments.  I have been looking into your questions and I have some answers for you.  These are some pretty good questions and are pretty important for understanding how the cRIO system works as a whole.  Here goes...

1)  The loop timer that you are seeing at the very beginning is there to set up how the loop will execute and sets up the timing for that loop.  You are right in that it does this.  The loop timer actually only executes on the first iteration of the loop and sets flags for making sure that the timing of the loop stays consistent and executes in the specified amount of time.

2)  As for the calibration data, the actual module is calibrated at the factory when it is made and this data is stored on an EEPROM on the actual module.  This data is used basically for converting the binary numbers returned by the module into actual Engineering units that will make more sense to you.  Since these values are static and do not change, there is no need to have the reading of this data inside of a loop.  Reading it once and storing the data will suffice.  This will make the program more efficient in that you are using less calculations and taking the necessary steps to ensure the timing that you want.

Now, on to the real question... as for getting the different delta t's between each sample, this looks like it is occurring because you are running the program on the host PC.  Running the program on the host PC eliminates the value of the Real-Time operating system on the cRIO controller, or 9002.  Usually, we recommend that all calculations and samples take place on the FPGA/RT system and the host PC mainly be used for displaying data to the user and merely provide a user interface.  With non Real-Time operating systems, you can never be completely sure what is going on in the background, so other processes may take priority over your VI that you are running and hurt the determinism of your application.  I have attached a link below that goes through some of the basic ideas behind Real-Time.

I hope some of this helps and please don't hesitate to reply back if you have any more questions about this issue.  Thanks!

http://zone.ni.com/devzone/cda/tut/p/id/3938

Regards

Noah R
Applications Engineering
National Instruments
Message 2 of 14
(6,964 Views)
Oh, and one other thing I forgot to ask...I'm guessing that since I'm eventually going to be using all 28 RTD channels and all 8 DIO channels on each chassis I'm going to need to use DMA/FIFO to transfer the data from the FPGA to the host since there would just be too many front panel objects otherwise and it would fill up/overload the FPGA.  So the problem I think I might have is that it appears that the Target-Host FIFO setup only allows U32 data, but the data from the 9217 is I32...is there an easy way to get around this? I've thought about just passing an additional constant or an array of booleans to identify the sign but that seems crude and there's got to be a better/easier way, but I'm out of my element here.

Thanks,

-Greg
0 Kudos
Message 3 of 14
(6,962 Views)
Hi Greg,
 
You are correct in that the Target to Host FIFO only allows U32 data to be passed through it.  This is intentional in that the U32 data representation is the most efficient way for the data to be passed using the PCI Bus.  As for a workaround, you may want to try using one of the methods that you mentioned earlier if you are not able to accomplish what you need with the I32 data type.  I hope some of this information helps and good luck with your application!
Regards

Noah R
Applications Engineering
National Instruments
0 Kudos
Message 4 of 14
(6,918 Views)

Hi Greg,

I have been doing a little more research into you question, and I want to clarify something about your question a little further.  When using the I32 numeric data type, 31 bits are used for the actual value while one final bit is used to determine the sign of the value.  When passing the data through the FIFO, it will copy the data as a 32-bit integer exactly as it appears.  However, when you are programming in the Host VI and need to convert the data to a nominal value, you can use the Binary to Nominal VI that is already programmed with the knowledge and capability to convert the binary data coming from the 9217 into an I32 nominal value.  So in summary, transferring the data as a U32 number will not affect anything with your data and you should not have to use any kind of a workaround to get the correct data.  I hope this helps and clarifies some of your questions.  Thanks!

Regards

Noah R
Applications Engineering
National Instruments
0 Kudos
Message 5 of 14
(6,903 Views)
Noah,

Thanks for all that info, it was certainly helpful.  I'm now running a slightly simpler host VI on the 9102 now until I can figure out the file I/O stuff, but the timing accuracy is much better.  I'm also presently using a few I32-U32 conversions to deal with the FIFO stuff I've just added, primarily so I can display the numbers I'm used to seeing for debugging purposes, but as you suggest, I'll probably remove those once I get everything working .  So now I'm on to attempting multiple channels and the use of DMA FIFOs to pass the data to my host VI and I've run into some additional questions, hopefully you can help me out here as well.

I've attached my FPGA VI as that appears to be where I'm running into trouble, at least when I step through the debugging on the FPGA emulator.  Specifically, from everything I've been able to find about how the FIFOs work, when I set one up I choose the depth, which indicates the number of actual elements (as opposed to bits, bytes, etc.) that can be written to the FIFO.  So in my case I'm trying to output 8 RTD cal values, and 4 RTD values.  As my first attempt, to keep things easier in my head, I'm using two different FIFOs to do this (I can probably go to one once I understand it better, but for now two is more sane for me).  I've set DMA FIFO 0 for the LSB weights and offsets, so since I need to set 8 elements the closest FIFO depth is 15, and I've padded my array with 8 extra zero values which should, I think, fill the FIFO and cause the FIFO Full item to flag true.  I'm doing the same thing for the FIFO associated with the RTD outputs, just using a depth of 7 with 4 padded zeros.  When I run this through the emulator, however, I never seem to make it past reading the LSB weights and offsets, DMA FIFO 0 never fills up and I can't proceed.  What am I missing here?  I haven't been able to find any clues anywhere in the KB or tutorials or forums other than what has gotten me to this point (which as far as I can tell from what I've read, should be working).

Thanks again for all the help,

-Greg
0 Kudos
Message 6 of 14
(6,884 Views)

Hi Greg,

Thanks for the response and the sample program with the explanation!  I have been looking over your program and I think I may see why exactly you're seeing the FIFO not fill up.  When you are checking the FIFO to see if it is full, the only time the value will return as true from the FIFO Write function is when it is full and you attempt to write another element to it.  In your case, you have your information in a For Loop and are only placing the elements you have to fill it up into the FIFO and not running through the loop again in order to see if the FIFO is full.  I hope that makes sense with how the FIFO will return a True value for being full.

However, with all that being said, you do not have to fill the FIFO completely each time you write to it.  When you set the depth, you are basically just creating a buffer that is of a certain size.  Please don't feel like you have to pad the FIFO with extra values just to take up the extra space.  I have attached a link below that you may have looked at already, but it does go through some of the basics behind the FIFO.  Also, the LabVIEW help is a great resource for getting information about anything involving FPGA.  I hope some of this helps and good luck with your program!

http://zone.ni.com/devzone/cda/tut/p/id/4534

Regards

Noah R
Applications Engineering
National Instruments
0 Kudos
Message 7 of 14
(6,824 Views)
Noah,

Thanks again for the reply, its good to know I don't need to actually fill the buffer prior to reading, but I'm still having an issue with the FIFO Full question...I'd already gone through that article and all the help files I could find and was aware that the FIFO Full doesn't flag true until you try to pass additional elements AFTER its actually full, which is why I padded on an extra zero (so I'd would be trying to pass 16 elements to a 15 element FIFO, which should then trip the flag).  I've even tried padding my array with 1000 extra zeros and the FIFO still never flags as full, this is what's been confusing me.  I appreciate your help with this, I know its pretty nit-picky stuff, but I'm eventually going to be running close to 40 RTDs and then I'll actually need to worry about more careful FIFO management.

Thanks again,

-Greg
0 Kudos
Message 8 of 14
(6,815 Views)

Hi Greg,

Thanks again for the reply.  I think the problem you may be seeing is a result of running your program in Emulator mode.  I have been able to write a sample program on my own and I am able to see when the FIFO is full when I'm not running in Emulator mode.  When you use the Emulator, you cannot simulator a FIFO as it is physical memory.  Try running your program without Emulator mode enabled and it will hopefully work then.  Please let me know what you see.  Thanks!

Regards

Noah R
Applications Engineering
National Instruments
0 Kudos
Message 9 of 14
(6,682 Views)
Noah,

Thanks for that piece of info, I might suggest putting that somewhere in the help file since I never came across that anywhere (though I am using 8.2 so it may already be there in newer versions).  Alas, it did exactly the same thing when I actually ran it on the target.  It tries to write one sample larger than the defined size of the FIFO and just hangs.  So I've pushed on with trying to get the host VI working for now, since for the time being I won't need to worry about determining if the FIFO is full or not and it seems to work if I write just the 8 samples I need.  So yet again, I have run into some sort of problem using the FIFOs (should I perhaps post all these FIFO questions under a new thread since it has little to do with the original topic of the thread?)  I've again attached my host and FPGA VIs for review.  What I'm finding is for sure associated with how I'm opening, reading, flushing, and closing the FIFOs since when I run this code without all the FIFO stuff, just using front panel indicators, everything seems to run fine.  Basically, if I reboot the 9002, and reset the FPGA, and then step through on debug mode from the start of my host VI, I first get a 61003 error after the Run command (I'm guessing since I've inserted FIFO config and start blocks upstream) but that's not the real issue...when I get to the first FIFO read to obtain my LSB weights and offsets, it correctly pulls out the 8 values I've written and then says there are 0 elements remaining (its a 15 element FIFO so I should be seeing 7 elements remaining no?), and then proceeds to lock when it enters the loop I use to flush the remainder of the FIFO.  If I remove the flush loop, I can proceed to the loop for reading the RTD data, which works nearly ok for a single iteration (I have a weird issue with the ordering of the RTD data coming out of the subVI that converts to resistance and temperature, but I'll worry about that later).  It then loops back around to take sample #2 and promptly hangs, though I can't identify where.  I'm sure I probably don't need all of the FIFO configure, start, and stop blocks, but initially I put them in hoping it would help me keep track of what was going on and the order and all that...perhaps this is screwing things up?  I'm also not sure if how I'm flushing the FIFO's is correct, I've looked through all the shipping examples on DMA and found none that actually seem to do this, as all the examples are completely filling the FIFOs on every run.  I've read all the help files and looked at all the DMA example VIs, and I can't for the life of me see where I'm going wrong, is there some more detailed FIFO tutorial out there?

Thanks again for all your help Noah, its frustrating but I do think I'm making progress...feels like I'm almost there

-Greg
Download All
0 Kudos
Message 10 of 14
(6,665 Views)