02-05-2019 03:15 AM
Hi,
I have made a continuous sinewave generator using basic sine function and plotted it on the waveform chart.
I want to add two waveforms of different frequencies. I have sampled both waveforms at same dt.
But when I try to add the waveforms with different amplitude or frequency and plot it, I get unexpected results.
It seems that there is some problem with sampling. I don't know what it is.
Solved! Go to Solution.
02-05-2019 03:41 AM - edited 02-05-2019 03:53 AM
Hi gkartik,
problems with your VIs:
- building large arrays in a subVI (feedback node!) is creating problems in the long run
- what result do you expect from adding waveforms with different t0 values? (Yes, your two subVI instances will not run at the same time!)
I get unexpected results.
What is the "expected result"?
And why don't you use the "Tones and Noise" function?
02-05-2019 05:43 AM
Hi GerdW,
My expected results should be according to Fourier series, that I should be able to a resultant of a sum of sinusoids of different frequencies.
I have edited the subVI and connected the same t0 to both instances. But again I don't see expected results. I see the following
02-05-2019 05:50 AM
But this time I was successful in getting the results.
I removed the subVI and instead of adding the waveform of the two sinusoids, I first added the array outputs of two sinusoid waveforms and then built the resultant waveform using build waveform.vi.
I think there is something wrong when we try to directly add the waveform data.
02-05-2019 06:37 AM
Apart from the building of the array in the sub VI, it's not reentrant.
Both VI's add the data points to the same array. The shift register in the sub VI is the same data for the two instances of the sub VI. Basically, it's a functional global that you've made. Make the sub VI reentrant, if you was a quick fix.
02-05-2019 07:18 AM
I made the sub VI to be have preallocated clone reentrant execution. And it worked.
02-05-2019 07:22 AM
Since the two instances were sharing the same subVI one at a time, the sampled outputs had a lag. Is it the reason why I was seeing weird output?
02-06-2019 02:52 AM
@gkartik wrote:
Since the two instances were sharing the same subVI one at a time, the sampled outputs had a lag. Is it the reason why I was seeing weird output?
The two instances of the sub VI are calling the same VI. The same VI also means there is only one set of VI data (shift registers, controls\indicators and feedback nodes). So both instances of the sub VI will add to the same data in the feedback node.
This will definitely cause troubles. Not sure if 'lag' is the right term. The data from both signals will be added to one signal (the one in the feedback node), and then added. So you're arbitrarily interleaving the two signals, and then adding the one signal to itself. You'll might lose one simple when adding, as the first instance doesn't have the latest addition from the second instance.
Behavior like this will be hard to predict. Unless you want a functional global, avoid VIs with 'state' data, like uninitialized shift registers, feedback nodes and locals.
How to avoid VIs with state?
1) Make the VI reentrant. Basically, the PtByPt principle. The Vis will still have state, but it's on a per instance base, so not shared between each instance.
2) Put the state data in an input\output. In this example, put the data in an input\output in stead of the shift register, and in the caller put it in a shift resister.
The PtByPt VI are neat at first, but terrible when scaling up. They operate well if you can have an instance for each usage (for instance two instances for two channels). But what happens when you have 20 channels? You should want to put this in a for loop. That is where the PtByPt principle fails. Each iteration will call the same instance, and you're back to the original problem, even with a reentrant VI.
The 2nd solution would be my preferred solution. Of course, I'd not use the raw data, but make a nice class for it. Classes are perfect for this. You can put all the state data in the class' private data, and then treat the instances as the objects that they are. Next best thing is a type def'd cluster, but if you know how to do that, I'd encourage you to give a class a go, you're 90% there.