LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Writing waveforms from Ch. 0 of niSCOPE to binary file in a multi-record setup?

Hello,

I am not very experienced with niSCOPE and writing waveform records, so I need some expert help here.

Here is my application:
I am generating a pulse train using a 6602 counter/timer. Each rising edge of this pulse train triggers an niFGEN to generate a single sawtooth waveform output to another device and, at the same time, acquiring data from Ch. 0 of an niSCOPE. I am fetching one record per rising edge of the pulse train for the niSCOPE (multi-record setup).

The attached VI is where I am at thus far. All triggering and reading/fetching of the waveforms seems to be working just fine when testing with an oscilloscope. I now need to save each waveform record along with the timestamp of its rising edge trigger to a binary file. The bottom of the VI is where my attempt is at saving the waveforms to a binary file, so the attention should be there when looking at it.

I am running LabVIEW from a computer connected to the NI PXI-Chassis using a cross-over cable.

Questions:
1.) Do I need to convert the data coming in on Ch. 0 of the niSCOPE to digital? Does it come in as analog from an oscilloscope? If I need to do this, how can I accomplish this?

2.) When I try to run an example VI to write a waveform to a binary file by choosing "My Computer" in the bottom left of the VI window, it works it saves the file just fine. When I change this to run on "PXI2", a file is not even created and I get an error on File Dialog (code# 7, I think) each time the file is attempted to be closed. This may be a stupid question, but why can I not save data to a file on my computer if running the VI on "PXI2"?

3.) Assuming the saving of each waveform to a binary file is working (read: (2) is successfully addressed), how can I also write the timestamp of the starting trigger for the waveform along with the waveform in the binary file? An example VI of how I can accomplish this would be fantastic, but I haven't been able to find one thus far.

4.) When I was messing around and trying to accomplish this, it seemed that doing this writing may slow down the entire process too much. I need to record data to the extent of the sawtooth waveform generated by the niFGEN AWG for each trigger. Is there any changes I should make to my acquisition process in the niSCOPE section so that I can read each waveform, along with keeping the timestamp for each, and write this information to a binary file?

I need to get this working quickly, so any help on this is greatly appreciated. Thanks in advance.
0 Kudos
Message 1 of 11
(5,843 Views)
Does anyone know the reason for question (2) above?

When acquring and fetching waveforms, is it being stored permanently on the harddrive in the PXI Chassis? I am at the point that all I really need to know is how to save the waveforms I am acquiring and fetching using the niSCOPE to a binary file on the internal harddrive in my PXI-1044 chassis. I am running LabVIEW from a separate computer hooked up to the chassis using a crossover ethernet cable.

Does anything special need to happen to store data to an external harddrive hooked up to the chassis via USB port?

Thanks in advance for any information regarding my questions.

Chris

Message Edited by cgifford on 06-20-2007 12:33 PM

0 Kudos
Message 2 of 11
(5,832 Views)

Hi Chris -

I may not be able to answer all of your questions completely, but I can help with the architecture of your hardware setup.  First, I'd like to know which PXI controller you're using.  Is it a remote controller or an embedded controller?

1. The data retrieved from the digitizer is discrete analog data, not digital.  Digital data is transmitted as an array of bits, but what the digitizer returns is an array of samples taken from your analog waveform.  So each value exists at a finite moment in time (discrete), but carries a decimal value of the signal's amplitude (analog).  This data can be recorded, manipulated, and viewed as-is.  There is no need to try changing it to a "digital" format. 

2. Which example program were you running?  And what is "PXI2" supposed to indicate?  From the constants on your block diagram, it looks like your PXI chassis is designated as "PXI1".  This designation is used in conjunction with the slot number of a module to identify that specific module for a driver session, but it shouldn't be needed to designate the location of a log file.  You simply need to provide a valid hard drive path for your log file, such as C:\log.bin or C:\Log Files\Test1\data.log.  You can also provide a network path if you have write access to that folder, but I don't recommend it for streaming to disk.  The high latency and low bandwidth of a common 100Mb network will be far too slow for most situations.

3. The best thing I can do for you here is point you to the NI High-Speed Digitizers Help file.  This file contains a lot of documentation on our your digitizer works, including a full state model that describes how triggering and driver calls control your acquisition.  You can find the file in your Start menu under Programs » National Instruments » NI-SCOPE » Documentation.  Inside the file, browse to Devices » PXI-5124 » State Model.  I recommend reading this article in depth to understand how records are acquired and transferred to the host.

I don't fully understand the design of your application.  The code you posted does this:  Generate a pulse train with a 6602 and route it to the PXI_Trig0 line.  This signal is then used as the Reference trigger on your 5124, which tells the digitizer when to acquire each record of data.  At the same time, your 5422 is using an undocumented external signal as a Start trigger, though the digitizer is permitted to start acquiring immediately.  What signal is sending the Start command to the 5422?  Is it desired for the 5422 and the 5124 to start asynchronously?

Both the 5124 and the 5422 use the PXI_Clk10 signal as a reference clock, but the 5422 has twice the sampling rate of the 5124.  Since the sawtooth being generated is 1000 samples in length and each of the digitizer's records is 8192 samples, there are 16.384 sawtooths generated per record of acquired data.  Is that the expected behavior?

When you say "the timestamp of the starting trigger", what are you referring to?  I can only assume that you mean the timestamp of the Reference trigger for each record acquired by the digitizer.  This value is returned in the wfm info output of the niScope Fetch VI.  You can either use the timestamp of the first sample in each record (relativeInitialX) or you can calculate the timestamp of the trigger itself (absoluteInitialX - relativeInitialX).  These timestamps are stored and returned for every record acquired, regardless of how many records you fetch at a time.  (So if you fetch multiple records at once, they will be returned as an array of the wfm info cluster.)  Writing this data to the binary file is a simple matter of adding another Write to Binary File VI in each iteration of the loop.

4. I don't understand the wording of the sentence, "I need to be able to acquire data to the extent of the sawtooth waveform generated...for each trigger."  Can you reword that or elaborate to make it easier to understand?

To make the loop iterate faster, I recommend:

  1. Use the HWS or TDMS (LV 8.2 only) file formats instead of simple binary functions.  These formats were designed for streaming data, and they handle file sessions in the Windows OS differently to accommodate this.
  2. You're only acquiring 8.192 million samples of data.  Instead of trying to stream it to disk, you might be able to hold all of it in RAM and then write it to disk afterward.
  3. Instead of fetching cluster or waveform data, fetch an array of numbers.  This is a faster operation.

I hope this helps.  I know it's a lot to digest at once. Smiley Happy

 
David Staab, CLA
Staff Systems Engineer
National Instruments
Message 3 of 11
(5,820 Views)
Thank you so much for your reply, David. Let me try and explain my situation and setup a little better, as well as discuss the points you made in your reply. Beware, you may want to refill your coffee as this post is long :).

I am using an embedded controller in a PXI-1044 chassis. I now have the chassis hooked up to our local network, and I am deploying my project to the chassis over the network as I am also connected to the local network. I have an oscilloscope next to me that takes as input the pulse train for a trigger and the generated sawtooth from the niFGEN for each trigger (rising edge of the pulse train from the 6602 counter). Just to make sure synchronization is taking place, the sawtooth is also fed as input to the niSCOPE for acquisition.

"PXI2" is what shows up when I choose to run a VI on the PXI chassis rather than "My Computer"; not sure why the 2 is there either, but that is what it says. I may have tracked down the issue I was having with writing, but more about that a little later...

The attached VI is an update, although not much has changed. My application design is like this (keep in mind that some values for VI's are still constants in the block diagram while others are controls on the front panel): I am using the 6602 to generate a 1 KHz pulse train and routing this pulse train to PXI_Trigger0/RTSI0. I am also using the PXI_Clock (10) as a sample clock for this, and also using this same clock as the reference clock for both the 5422 and the 5124 (as per the synchronization help file mentioned for synchronizing multiple devices). Both the 5422 and the 5124 are triggered by a digital rising edge (from the pulse train) on PXI_Trigger0/RTSI0 (as it was routed there). For each trigger, the niFGEN generates a sawtooth waveform using a stepped trigger mode and outputs it. For each trigger, the niSCOPE acquires data. They are both synchronous, which is tough to see since one has its trigger source on the front panel and the other has its trigger source on the block diagram. All devices use PXI_Clock so they are synchronized.

The expected behavior is to only generate a single sawtooth waveform per trigger with a certain number of sample points. I want to acquire the same number of samples using the niSCOPE, which is what I meant by "the extent of the waveform" in my previous post. So, should I change the 8192 to 1000 for the number of samples for the niSCOPE? What would you recommend for the sampling rate? I have been using 5 MHz for the niFGEN and 5 MHz for the niSCOPE...this is how it should be done, correct? If it is different in the VI, please let me know. For some reason, I have to adjust all of the values each time I open it since the default values are not the ones I want.

I want to generate and acquire one waveform per trigger (one waveform per record). However, I want to be able to record a large number of records so I have enabled the circular buffer-like treatment of the acquired waveforms. The 100 or 1000 records is actually just a number I am giving it for now to make sure it is working before recording many more records.

As for saving the niSCOPE data, I would like to save all data in a single file that is NOT ascii (to save space). I have been looking at the HWS file format, and would like to use it. I think the attached VI includes this at the bottom of the while loop. For each trigger, I would like to save the time (as accurate as possible) that the trigger occurred for the record/waveform, which appears to be (absoluteInitialX - relativeInitialX) as you said in your post (thanks!). I just need to store as much information about the waveform and time information for it as possible with the waveform in the file. So it looks like I will need to use the wfm info for that information, providing portions of it as waveform attributes in the HWS VI's?

What format of data do you recommend I fetch, and will I be fetching a "Single waveform" or "Multiple waveforms"? Should I use I32, DBL, WDT, or other for the format? A balance between good precision in values and time it takes to fetch/record would be best.

Given all of the above, I am having one troube with saving data to a file. As a reminder, I am deploying the project to the chassis over the network. When I choose a location and/or file to save the HWS data to, I only get choices that are on the PC's hard disk (such as C:\Documents and Settings\cgifford\...) NOT the chassis's hard disk. When I choose something other than "C:\" I get an error that the file could not be opened. However, when I choose "C:\" everything goes fine. The saved data is nowhere to be found on my PC though, so I am assuming that it is being stored on the internal 60G hard disk in the chassis that must be named "C" by default or something!?

I have been told by phone support that I should be able to make a direct connection with the chassis just like another PC, and should be able to access the information on its internal hard disk in a drag and drop fashion. I however cannot directly connect to the PXI chassis to get the data that has been saved on the hard disk. We are running Windows XP on the PC. We did some poking around and noticed that the chassis is not running Windows file sharing, and only has ftp and http running. We tried to access it using ftp, but we didn't have a username and password to supply it. So, how can we enable Windows file sharing on the chassis? How can I connect to it to do drag and drop to get saved waveform data off of it? This is the main problem I am now facing. Eventually we would like to store data to an external hard disk connected to the chassis, which assumes that I can have access to the internal storage to tell it to save files to the external hard disk. For now saving it to the internal hard disk is just fine until everything is proven to work, but I would like to get the data off of the internal hard drive to put on another computer.

Any answers/suggestions on my above questions are greatly appreciated. I also want to thank you for reading this long post :). I eagerly await a reply. Thanks again in advance.

Chris
0 Kudos
Message 4 of 11
(5,809 Views)
I have figured out my problem with saving the file and accessing it on the chassis. I was unaware of the ftp ability in MAX to access the internal hard disk.

Any answers/suggestions for the other questions in my previous message would still greatly be appreciated. Thanks.

Chris
0 Kudos
Message 5 of 11
(5,795 Views)
Hi Chris -

These posts are getting epic in length!  To try and curb that effect, I'm going to tag-team this thread with another NI employee.  I'll be addressing the hardware design and programming, and someone else will discuss networking, file storage, LV optimizations, etc.  Hopefully this will keep details from slipping past me when I pour through all the information!



Having gone through your description of the program's expected behavior and the code you attached, I have a fear that it's not doing what you may think it's doing.  (Have you verified the output data written by the program with a PRBS or test signal?)  Let me explain my concerns.

1. You're setting some DAQmx Timing properties on the counter task, but these properties don't apply to this type of task.  The properties you want to set are found in the DAQmx Channel Property NodeCounter Output:General Properties:Counter Timebase:Source and :Rate.  Even so, the Device Routes diagram (found in MAX) for your 6602 does not show the PXI_Clk10 line as a valid timebase for counter operations.  Only the onboard 20MHz Timebase and 80MHz Timebase can be used to generate a pulse train.

This isn't necessarily a deal-breaker.  Regardless of when the rising edge is received by the arb and digitizer, they'll each have to wait until the next sample clock edge to start their work.  So, as long as they generate synchronous sample clocks -- which they're doing by PLLing to PXI_Clk10 -- and they receive the trigger pulse at (relatively) the same time, they'll react to it in unison.


2. Our AWGs have an inherent delay between the receipt of a Start trigger and the generation of the first sample of a waveform.  This delay is given in each device's spec sheet:



This means that, even though the digitizer and arb will receive the trigger edge at the same time, the arb won't start generating its waveform immediately.  If the digitizer and arb are both sampling at the same rate (using aligned sample clocks from the PXI_Clk10 derivation), the first several samples of the digitizer's record will not contain data corresponding to the arb's sawtooth output. 

This may be acceptable, but I wanted to let you know about it.  If you want the digitizer samples to correspond one-to-one with the arb samples, you'll have to tweak the Triggering:Trigger Delay property in the NI-SCOPE driver to correspond to the arb's Start trigger delay.



In response to your questions:

What would you recommend for the sampling rate?
This is up to you.  If the digitizer's record size is equal to the arb's waveform size, then you'll want the same sampling rate on both devices to ensure a point-to-point comparison.  There is a specification in the 5422's sheet that you should consider:



The shortest period of your sawtooth signal should be 1/10M = 100 ns.  This will avoid distortion in the output.


So it looks like I will need to use the wfm info for that information, providing portions of it as waveform attributes in the HWS VI's?
That's how I would try to do it.  Though I have to ask why you need the timestamp of the trigger, if you already have the timestamp of the first sample?  Also, please note that these timestamps are not referenced to the PXI system, only to the individual device.  The timestamp counter is started as part of the device's power-on procedure, and there is no way to anticipate that moment in time.


What format of data do you recommend I fetch, and will I be fetching a "Single waveform" or "Multiple waveforms"?
Well, you're only acquiring on one channel, so it'll be a Single Waveform.  As for the datatype, this is also up to you.  You can retrieve and store unscaled binary data (I32) for the fastest possible fetch.  You'll want to store the gain and offset values with the data so it can be reconstructed later.  You also have the option of fetching scaled values (DBL), which takes slightly longer to do (because the driver software has to scale them for you.)  Neither of these types of fetches puts the timing information in the data, so you'll need the relativeInitialX and xIncrement values to reconstruct the waveform timing.  You can also fetch a waveform (WDT) or cluster.  These fetches require the most effort by the driver and therefore take the longest to do, but they have all the scaling and timing info wrapped up neatly for you.

If you're using the HWS format, I recommend a scaled or raw fetch to get the most speed out of your loop.

Message Edited by David S. on 06-21-2007 05:40 PM

David Staab, CLA
Staff Systems Engineer
National Instruments
Download All
Message 6 of 11
(5,774 Views)
Thank you so much for the information! It explains several things I was not able to locate successfully myself.

Since the 20 MHz and 80 MHz timebases are the only options for controlling the pulse train coming from the 6602, it appears like either will work for my purposes. What is used by default if no reference/sample clock is provided? As long as the AWG and digitizer are synchronized, that is what matters most for our application.

I did notice the 65 sample delay in the AWG output. I have verified that this is OK for our purposes. Since the delay is constant, we can either adjust for it using a trigger delay or adjust for it at a later time.

I verified that the timestamp information can either be for the trigger itself or the first sample for our purposes...so that shouldn't be a problem. I will take your advice and use the HWS format and either raw or scaled fetch.

Now that those questions have been addressed, I have two other questions. We are going to need to record for a long time (2 hours!!!!), meaning a ton of records and needing to have the fetching keep up with the acquisition to not get a buffer error. I currently get this error when I toy with the sampling rates, number of samples to generate and read in, number of records to record, etc. I plan on generating the single sawtooth waveform per trigger composed of 1000 samples at 5 MHz. I plan on acquiring using the digitizer at 5 MHz or 10 MHz sampling rate. I also really only care about storing the sample points of the incoming waveform up to the extent of the sawtooth (which happens to be about the first 1075 samples or so in this case). I don't care about the rest of the information coming in for the remainder of the time between triggers.

1.) When I choose to plot the fetched waveforms and I want to read in 1075 samples, the X axis only goes up to half of this value (537) yet shows the entire waveform. This doesn't make sense to me, and it really doesn't change if I adjust the digitizer's sampling rate to 5 MHz or 2.5 MHz. So to get the X axis to display the correct range, I have to read in 1075*2=2150 samples. Any idea why I am getting this behavior, and is it really reading in 1075 samples and the X axis range (0 to 537) is just displaying wrong?

2.) As I will be recording for a very long time (desired to be up to 2 hours!), is there any way that I can ensure that the fetching can keep up with the acquisition so I don't get an error? If I take the saving operation completely out, it can keep up just fine. The save operation is delaying things, of course. I know I can turn the plotting off and that will speed things up, and I know that I can adjust the data read in (raw or scaled) for a little more efficiency. Can I adjust the size of the buffer to allow me to acquire more without an error since the fetching can't keep up? How can I fit this into my design? Or is really the only solution to record data for a long time in my setup to run my VI to record the maximum number of records without it crashing, restarting it, and repeat the process for 2 hours? As an example, I ran the VI and gathered 50000 records, reading 1075 samples per trigger, at 2.5 MHz, and saving everything into a single file on the internal disk of my chassis. The resulting file was about 230 MB and the 50000 records were acquired very fast but fetching the records took a much longer time to catch up. No error occurred however and it was able to do this just fine.

These are really the only two things that I need to address to finish. The attached VI is what I currently have for reference, but it does not include the counter clock change to 20 MHz or 80 MHz timebase as you suggested in the previous post and the fetch data type has not been decided upon. Please let me know your thoughts on the above. I truly appreciate your time, help, and patience. I eagerly await a reply. Thanks again!

Chris
0 Kudos
Message 7 of 11
(5,768 Views)
 
 

Hi Chris -

What is used by default if no reference/sample clock is provided?
Your question is answered in part on page 41 of the 660x User Manual.  You can find out what happens in your own program by reading the properties in question (instead of writing them) after the task has started.  The values committed to the hardware will be returned to your indicators.


I currently get this error when I toy with...
Which error?  Please post the error number and text.


2.) As I will be recording for a very long time...
First, I need you to read two articles on streaming data:  Streaming Data to and from Disk and High-Speed Data Streaming: Programming and Benchmarks. 


...The save operation is delaying things of course...fetching the records took a much longer time to catch up.
You can confirm this using the Tools » Profile » Performance and Memory option in LV 8.x.  (In LV 7.x, you'll find it under Tools » Advanced » Profile VIs.)  This will tell you exactly which VIs are taking so long.  However, I'm certain that fetching and saving to disk are the bottlenecks, here.  There are two things you can do to alleviate them:

1. Use a producer-consumer queue structure.
One of the articles I linked above explains the theory.  You can study some code by opening the niScope EX Save to File - HWS Low Level - Single Channel Stream.vi

2. Fetch multiple records at a time.
Right now, you're only pulling one record from the device each time you call "niScope Fetch".  If the call itself is a slow process, why not take advantage of the spent time and retrieve multiple records at once?  Change the Fetch Number of Records property to a higher value.  You'll also need to change the Fetch function to "Multi Waveform" so it pulls more than one record.  (Yes, this is contrary to what I said in an earlier post.)  The example niScope EX Multi Record.vi example in LV shows how to do this.  Note that the example performs a continuous acquisition into one waveform, whereas you'll be doing a multirecord acquisition into several waveforms.


On that note, I also noticed that you're not creating a new waveform in the HWS file for each record.  If you don't call niHWS New Wfm Reference in each iteration of the consumer loop, you'll accidentally overwrite the wavform properties with each new record.  Here's an example of the method I'm describing.  (This should be all the file writing code you need -- the gain and offset parameters in your program are unnecessary for scaled data.)

 

 

Message Edited by David S. on 06-22-2007 11:42 AM

Message Edited by David S. on 06-22-2007 11:45 AM

David Staab, CLA
Staff Systems Engineer
National Instruments
Message 8 of 11
(5,748 Views)
Thanks again for your help David,

I have read through your suggestions and related articles. After making sure I was giving each waveform a new name (which turned out to be an expensive operation in the long run), I think the complete functionality was there....it was just a bit slow.

I decided to implement a producer/consumer queue architecture with multi-record fetches. My try at this is the attached VI. The producer/consumer and saving portions are all that need attention, as everything else is being successfully done. Could someone take a look at it and make sure that it is doing what I am wanting it to do: fetch 10 records at a time (each of size 1075 samples) in a producer/consumer architecture? Is this the most efficient option possible for me? Would doing a producer/consumer architecture with fetching single records be better somehow?

The reason I ask is because it is still incredibly slow. I am assuming this is just because I am writing a ton of data/waveforms to disk. For example, acquiring 1000 records using a producer/consumer architecture and fetching 10 records at a time takes a very very long time (I couldn't muster up the patience to wait for it to finish!). 10000 records would finish being acquired and fetched, but the number of elements in the queue was still very large and would reduce slowly. Is this normal and expected? Am I doing something wrong?

Will I be able to acquire and save data for a long period of time considering the queue was growing fast and reducing much slower? Would it be a good idea to make this entire VI a subVI, and run this subVI every so often so the queue doesn't get incredibly large?

I need some serious help here, as I have exhausted my knowledge on the implementation. Through my eyes, the implementation looks fine....it just seems to me like it should be faster. Thus, my only focus to finish this is to make it as fast as possible at saving waveforms to disk. Please look at the attached VI and let me know your thoughts.

Thanks again for all your time, help, and expertise. It is greatly appreciated!

Chris
0 Kudos
Message 9 of 11
(5,725 Views)
Hi Chris -

I decided to answer your questions by editing your program.  I commented the block diagram to explain my edits.  I ran this code with a test setup (6608, 5142, 5421 -- all identical in architecture to your hardware) using various file sizes.  I was using a MXI Express controller on a 3.2 GHz Pentium 4 with 1 GB of RAM.  It ran fine up to 3000 waveforms per file, then started having problems (probably due to the MXI connection, though I'm not knowledgeable enough to say for sure).
David Staab, CLA
Staff Systems Engineer
National Instruments
0 Kudos
Message 10 of 11
(5,669 Views)