09-11-2018 04:52 PM
@mcduff wrote:
I do not see a circular buffer in your examples, you are just enqueuing data. You need to think about how you want to implement your buffer, it is lossy, do you want to skip adding points to it if it is busy processing, etc.
There are lots of other things in your example that could be fixed, but I do not know whether you just put it together for an example.
Attached is a real hack of the program that will get it to do what you want, but I highly suggest you just look at it to see what can be done and rethink you problem.
mcduff
@mcduff, really appreciate your help and thanks for taking out time to modify the program.
1. You are right, i have used wrong nomenclature, it's just buffer and not circular buffer. I have buffered previous 3 data blocks using shift register.
2. In your program, PSD will be calculated at every 4 second. Basically it waits for 4 seconds data to gather. Whereas I am trying to achieve continuous PSD, being calculated at 1 sec, with previous 3 seconds data from shift register.
09-11-2018 05:49 PM
Once again, I do not recommend this as a final product, but something to think about. (I added some noise to the signal)
mcduff
09-13-2018 07:04 PM
Sorry for late reply.
@mcduff,
Thanks again. I tested MOD2 vi, and these are my observations,
-->I am trying to compare actual vs expected PSD results with (i) 0.25 Hz resolution, (ii) No window and (iii) No noise for both cases (a) complete cycles, (11hz) and (b) fractional cycles (10.5, 10.25hz).
So when I tested MOD2 without noise, results are same as original VI(using shift registers). Still getting -Inf values in-between @11hz input.
-->there seems to be 2 mistakes in circular buffer implementation. (i) in writing logic: check time graph for whole data block (i.e. 4sec) being fed to PSD with 10.25Hz signal. You will find discontinuity at every 1 sec. You need to remove subtraction block and directly connect (i MOD 4) to replaceArraySubset.
(ii) in reading logic: we are not reading data from where it is inserted in circular buffer. For example, @ i = 5, we will be feeding data block of 4, 5, 2, 3 to PSD, instead of 2, 3, 4, 5. It seems we have to write logic to specify read position and adjust array to read circular buffer in proper sequence.
I feel, original buffer logic using shift register (testActual.vi) provides required functionality, which you have implemented using circular buffer.
I also, tried different methods, but not able to find answer to main query, i.e. -Inf results in-between @ 11hz.
09-13-2018 07:24 PM
-->I am trying to compare actual vs expected PSD results with (i) 0.25 Hz resolution, (ii) No window and (iii) No noise for both cases (a) complete cycles, (11hz) and (b) fractional cycles (10.5, 10.25hz).
So when I tested MOD2 without noise, results are same as original VI(using shift registers). Still getting -Inf values in-between @11hz input.
I do not see that.
-->there seems to be 2 mistakes in circular buffer implementation. (i) in writing logic: check time graph for whole data block (i.e. 4sec) being fed to PSD with 10.25Hz signal. You will find discontinuity at every 1 sec. You need to remove subtraction block and directly connect (i MOD 4) to replaceArraySubset.
I used that so that the array starts filling up from the back, most recent acquisition is first, but the logic is wrong as you say. You need to also use a rotate array also to set the order correctly. So you need a replace and rotate array. I'll leave that to you as an exercise .
I also, tried different methods, but not able to find answer to main query, i.e. -Inf results in-between @ 11hz.
Do not see this at all.
mcduff
09-13-2018 10:50 PM
Nikunj,
I decided to try to demo your original question -- you want FFT resolution of 0.25 Hz, which requires 4 seconds of data to analyze. You want continuous recording and (what I'll call) "periodic updating" of the data and FFT -- I'm going to simulate continuously generating data at 1KHz, and acquire it in "chunks" of 1000 points at a time.
I'm using a Producer/Consumer Design, where my Producer is the "Generate 1000 points, add it to a "sort-of-circular-buffer" of 4000 points (I delete the last 1000 and add the new points at the beginning), and export it to the Consumer. The Consumer imports the 4000 points, plots it, FFTs it, and plots (part of) the FFT (I'm only plotting from 0 to 100 Hz in order to see the results more clearly).
I know you are using LabVIEW 2012, but since I am the "Channel Wire Guy", I hope you'll forgive me for using a Stream Channel to send the data from the Producer to the Consumer. Just think of that funny-looking Orange Pipe as a Kodosky-Queue (I just made that up!) that transfers the data from the Writer (on the left) instantly (as would a Queue) to the Reader (on the right). Anyway, here it is ...
The Data consist of two sinusoids, one at 10 Hz, amplitude 1, and one at 24.5 Hz, amplitude 0.5. There is also "noise" having RMS value of 0.5 added to the signal. As you can see from this plot of the Front Panel after the first 1000 points have been generated, there are "reasonable" values of the FFT, with peaks at 10 and 24.5 Hz (OK, it's hard to tell if it's 24.5 or not, but it's in the right neighborhood ...). If I wait another 3 seconds so that the initial "non-wave" portion of the signal goes off the end and is no longer analyzed, the peaks become very sharp, indeed.
I'm not sure why your code is giving you such weird values (maybe the uninitialized Shift Register?), but this "logical" method of doing a continuous acquisition + FFT certainly seems to work and give the "expected" result. I leave figuring out your bug innovative method up to you.
Bob "Channel Wire" Schor
09-14-2018 12:21 AM - edited 09-14-2018 12:23 AM
Never mind.
09-14-2018 07:24 AM
Aha! I was curious about RavensFan's "Never Mind" -- there is a post you might not have seen unless you had all replies e-mailed to you. He was pointing out to me what appeared to be a "bug" in my code regarding the 4000-point buffer. I was trying to add new data at the beginning of the buffer after removing "the final samples" from the end. Since I didn't wire a Starting Index in "Delete from Array", RavensFan originally thought I was removing and adding from the beginning of the Array (which makes sense, given that 0 is the usual "default" value for I32, and an index of 0 in an Array is the beginning element) and was urging me to use Build Array and stick the new data on the end.
A Curious Fact, however, about "Delete from Array" is that if you leave the Index unwired, it means "from the end of the Array". I use this all the time, so I neglected to mention this in my earlier post. I just "did the Experimental Proof" by modifying my routine to put an "Initialize Array" of 1000 elements inside the Producer, wired to the Loop Index "i". If I'm right, I should see a "downward" staircase, as the newest (and therefore largest) elements are at the front, and the oldest are at the back. Here's the Front Panel:
RavensFan undoubtedly realized this after his (now missing) post, which only goes to show you that Even Experts (and he is certainly one) Occasionally Forget.
Bob Schor
09-14-2018 09:44 AM
Hi Bob,
Thanks for pointing out my message. That is exactly what I was getting at, forgetting about the actual default of the index terminal for that function. Most functions the default is "0" when unwired. Delete from Array is odd in that it is "last".
I happened to post it, then I figured I better double check and realized your code did work they way it should, and not the way I was viewing it. Delete from Array has several little oddities I find confusing and often have to create test cases to make sure I use it correctly. I pretty much get it wrong the first time and need to change something.
-Bill
09-14-2018 10:12 AM
How 'bout them Ravens? Actually, I had a moment of panic, myself, when I read your post and quickly ginned up the demo that showed (for once) I got it right. It always pays to Test Your Code ...
Bob Schor
09-14-2018 03:55 PM
Staying up to watch that game, and then trying to recover from the results is what kept me online at 1:30 am.
Obviously, I wasn't thinking clearly.