Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Allowing regeneration without using it

Solved!
Go to solution

Hello!

I'm working on an application that outputs a sine wave (low freq, say 50Hz to ease calculations) one period at a time, so the amplitude can change each cycle. To improve response time, I don't want to use and fill a buffer, just the minimum required (I use 1000 samples/cycle, so a 1000 sample buffer that gets updated each cycle). This however leads to failures, since the smallest delays can accumulate and eventually lead to a buffer underrun.

I would like to enable regeneration, so that if the application is unable to write quickly enough, the device just reuses the previous cycle, but just then. However, for some reason if I do this I always get two uses of a cycle, even if in non-regeneration the application is able to send data quickly enough

 

Bottom line: how can I enable regeneration, but prevent it when I am able to update the buffer quickly enough?

Message 1 of 14
(4,272 Views)

In order to answer your question more effectively, I would like to get a little more information on your exact application.  This problem could easily be solved by doubling the size of the buffer to 2000 samples and changing it to a ring buffer so that the new waveform can be stored as the old is read out of the buffer.  I gather from your post however that this is not an acceptable solution.  If you could please explain what it is about your application that makes this option unacceptable.  Also, if you could please post some screen shots of your code so I can get an idea of how you are generating this waveform and why you are experiencing these overwrite errors.  Lastly, take a look at the following KnowledgeBase article over the different analog regeneration modes and see if any of this information proves helpful.

 

Analog Output Regeneration Modes

http://digital.ni.com/public.nsf/allkb/DD750D84BAD703E386256E6E005B41AC?OpenDocument

 

Chris L

Regards,

Chris L
Applications Engineer
National Instruments

Certified LabVIEW Associate Developer
0 Kudos
Message 2 of 14
(4,195 Views)

The idea to use a double-sized buffer, and read half of it while writing the other seems interesting, but I can't seem to make it work: if I disable regeneration I get an "attempted to write samples that have already been generated" error, and allowing regeneration seems to make the buffer update extremely slow (and dependent on how long the VI has been running).

 

I am attaching a picture of my application. The basic operation is: if it's been almost 50ms (a period of my 20Hz output wave) since the last write, then sample the input, generate another period, with a different amplitude, and send it to be written. The forced timing is there so that the application would not fill the device buffer by writing too often, and then hang while waiting for more space to become available.

The main idea is that the response needs to be as fast as possible, since this is an interactive application. That is why I only want to regenerate when necessary, since regeneration means loss of responsiveness

0 Kudos
Message 3 of 14
(4,174 Views)

Oh-oh, I forgot to attach the code

0 Kudos
Message 4 of 14
(4,162 Views)

Good morning, I hope you had a good weekend.  Thank you for posting the screen shot of your code.  I will be working on your issue later today and should have something back to you by tomorrow.  

 

Regards,

Regards,

Chris L
Applications Engineer
National Instruments

Certified LabVIEW Associate Developer
0 Kudos
Message 5 of 14
(4,136 Views)

I have taken a look at your code, and tried to re-create your VI so I could work with it, but the entire VI is not visible in the screen shot.  There seem to be some issues with the program, but without the entire code it is very difficult to troubleshoot.  Could you please attach your VI so that I can open and run it?  This will help me out greatly in implementing the type of buffer I mentioned earlier.  Thank you.

Regards,

Chris L
Applications Engineer
National Instruments

Certified LabVIEW Associate Developer
0 Kudos
Message 6 of 14
(4,117 Views)

I initially left some portions out because I didn't think they affected anything. I am posting the VI, hopefully it helps.

On a side note: the last write operation is intended so that the output after the VI finishes returns to a controlled value. This doesn't work however, and the output stays at a random value after the VI exits

0 Kudos
Message 7 of 14
(4,111 Views)

I have made some changes to your code which I think will give you the functionality you are looking for.  I have tested it out and the output waveform seems to be very responsive to any change in amplitude generated by the incoming signal.  I have also not experienced any timeout errors.  Test it out and see how it works for you.  If you have any questions or you still experience errors or other issues please let me know.

Regards,

Chris L
Applications Engineer
National Instruments

Certified LabVIEW Associate Developer
0 Kudos
Message 8 of 14
(4,099 Views)

Thank you for the modification, changing the DataXferReqCond property seems to significantly improve reliability. Unfortunately, the timeout errors are still there - the time it takes for them to occur is pretty random, from little over a minute to more than 10 (which is why I added the "run time" variable, to be able to check)

Also the whole application seems very sensitive to CPU load : if you start something like Borland C (the old IDE from ~1993, which takes over a whole core of the CPU even when doing nothing), then expect the VI to crash within a minute or so (on a quad-core system, load 3 copies of the parasitic program). This is why I am keen to use regeneration - for an end-user, this failure rate would not be well received

0 Kudos
Message 9 of 14
(4,085 Views)

Based on your feedback I have updated the VI again to implement 2 seperate while loops.  One is for the analog read function and the other is for the generate waveform and write functions.  Seperating these two tasks into two seperate loops allows enough time for the read task to fill the buffer before the write task asks for more samples.  With this type of architecture, you can read and write continuously without allowing regeneration.  However, this method is still sensitive to CPU usage.  When I maxed out my CPU at 100%, there was a slight delay between changing the input signal and seeing the update on the output waveform.  The positive about this structure is that you should never receive any overwrite errors.  However, you may not be able to update the waveform every period if the CPU usage goes too high.  When I had mine maxed out, the loop occasionaly took up to 250ms to iterate. (This was the exception however, with most iterations happening at or below 50ms.)

 

You may also try allowing regeneration in the previous VI I sent.  This is sort of full circle back to where we began, but with the changes I made it may work a little better for you.  Try out these two options and let me know if there's anything else I can do for you. 

Regards,

Chris L
Applications Engineer
National Instruments

Certified LabVIEW Associate Developer
0 Kudos
Message 10 of 14
(4,078 Views)