LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

varying amplitude on the fly

I created the following attachment to allow for varying the amplitude on the fly. The ultimate goal is to take a 25 or so second prewritten waveform and play it back while allowing the operator to add in a multiplier. I started with the example code and tweaked it a little till I got the attached document.

 

Running this program with the "in loop mode" button off, or false allows the program to create a waveform outside the loop, and then send it in, thus all that can be done in the loop is vary the amplitude as I play back the file.

 

One of the big things I am now struggling with determining right now is exactally what is going on in my code, and how best to write it. Part of this stems from my lack of formal training in labVIEW or programming for that matter.

 

When I send the waveform into the while loop denoted by the blue #1 in the photo below I take that waveform multiply the whole thing by the scaling factor and send it over to the DAQmx write once every iteration of the loop. While this may work here my concerns are that when I go to longer larger sample data it would be innefficient to multiply the entire array by a multiplier for the little bit I am actually playing out. Am I correct in such concern. I could use the get waveform subset and only work with a smaller piece of the wave, but in my experience that tool can be a memory hog. Is it smart to do it the way I am or break the waveform up into smaller pieces with the subset tool?

 

The next question I have is more fundamental labVIEW programming.  When I feed a 1second or 25second sample into the DAQmx write tool in a loop which appears to have an execution speed of around .05seconds or so, how does my analog output work?

 

For iteration #0 I would assume I write t=0 to t=0.05seconds.

For iteration #1, am I rewriting t=0 to t=0.05 seconds in the attached VI or does labview build in an auto indexing function so that I really am writing t=0.051 to t=0.1?

 

When I stick a scope on the output it would appear that what is happening is the second, but I really have no good way of telling in each iteration of the loop what is actually being played out.  Does Labview have these abilities built in or will I have to add them on my own via shift registers and or other methods?

0 Kudos
Message 1 of 4
(2,081 Views)

I'm assuming that your waveform that your outputting is a periodic waveform.  In that case you really only need to put one period of the signal into the loop for writing to the hardware.  Adjusting the amplitude like your doing is a fine way of accomplishing that, as long as you don't increase it beyond the limits of the NI-DAQmx task or you will get an error.  

 

Your concern with a larger file/data that is going to be written: Are you reading a large waveform from file and wanting to only play back a small portion of it?  If so, it would be better to only manipulate the part that you will actually be writing to the NI-DAQmx task.  If your eventually going to output the whole waveform, doing the multiplication isn't going to be an intensive operation when compared to the memory managment tasks that will happen with the subset tool.

 

For your question on how the analog output works:

The NI-DAQmx Write VI will take the waveform data that you give it and it adds it to a memory buffer that then gets transfered to your card.  That is why when you write once, and then write again, the seccond write appears to be appended to the output of the first.  That behavior is built into the drivers so you don't need to implement it yourself with shift registers or anything.  Once you write your data using the Write VI, its committed to being transferred to the hardware and generated.  

 

I hope this helps.

Systems Engineer
SISU
0 Kudos
Message 2 of 4
(2,036 Views)

I finally think I figured it out. I looked at my original posting here, and I didn't realize the code didn't seem to post. None the less see below for my final code if interested. I was having a lot of issues writing to the card, so I set up for onboard memory less than half full and now it seems to be working.

 

Basically I have a 20second waveform at about 150kS/sec that has been generated. It is non periodic but I want to be able to play it back with a multiple applied to the current output. Then I want that program to play that wave till it reaches the end, then start over at the beginning and run in a loop. Hopefully the code makes it clear what I am trying to do here.

 

It is pretty difficult though to actually validate the code is working as I never quite know what portion of the wave I am actually playing out. So if anyone would mind taking a look at it and letting me know if it is done correctly for what I am trying to do it would be appreaciated. Otherwise if anyone else is having this issue in the future, I hope my code helps you.

0 Kudos
Message 3 of 4
(2,025 Views)

The code looks fine, I've got one problem with it and a couple of suggestions:

 

The true constant wired out of your loop to the stop global isn't doing anything.  Its not reccomended to use global variable if at all possible to avoid.  But since you don't write to the global till after the loop terminates, and by then you won't be reading from it anymore inside your loop.  I would reccomend removing it.

 

LabVIEW is a dataflow programming language, so the first two frames in your sequence structure could be combined into one frame.  The later blocks will wait to execute until the data "flows" from the other blocks that execute before it.  If you could have the loop time be taken at the beginning of the loop instead of at the end, then you could remove the sequence structure completely, and still have the loop time from the prior execution.  Usually you will want to avoid sequence structures unless you can't avoid it, and cases like timing are one of the few cases where its useful.

 

I hope these suggestions help.

Systems Engineer
SISU
0 Kudos
Message 4 of 4
(2,014 Views)