LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Finding the period

Dear labview users,

i'm just starting to learn to use labview for a project (using labview 10) and i've encountered a problem.
i'm using VISA to read information from a microcontroller. the microcontroller gives an analog signal via USB to the computer from 0 to 1023(0 to 5V). the data that i'm getting is a sine with varying amplitudes. i'm able to plot it in both an waveform chart and an XY graph i've also been able to get it into an 2D array with the time on the second row.

now i need to calculate the period from that sine like signal and i've been unable to do that. i've tried peak detection, tone and pulse measurment and some others. and either i haven't been able to connect them properly or when i was able to connect the peak detection.vi i didn't get good measurments.

in the picture you'll see the basic program that i've build to read the data from the microcontroller. i'm using scan from string currently with an waveform chart. but i've also been able to build it with an decimal string to number and using an XY chart with on the X axis the time.

thanks in advance.

0 Kudos
Message 1 of 11
(6,823 Views)

At the risk of repeating myself, "A VI is Worth a Thousand Pictures".  Do not post pictures of your VI, post the VIs, themselves.  This saves us time and effort, so that we'll spend time and effort on helping you instead of saying "Please post your VI".

 

What do you know about Signal Analysis?  Signal properties?  How "clean" is your signal (a picture of your particular Signal, now that could be useful ...)?

 

If you've had a course on Signal Theory, you know the relationship between a signal and its frequency content, so I'll assume this is "new stuff" to you.  Look at your signal -- what operation(s) on it do you think would give you an estimate of the (dominant) frequency?

 

Bob Schor

0 Kudos
Message 2 of 11
(6,785 Views)

thanks for the reply ! and sorry for that, i'm rather new here. here is the VI and the picture of the signal that i'm getting. basicly it's an sine with an decreasing amplitude.

and concerning the signal theory; yes i'm rather new to it. i do know that 1/f=T and that that is also a way to determine the period but i've mainly been focusing on determining two peaks and then substract T2-T1 to get the period. although determining the signal's frequency could work just as well.

Download All
0 Kudos
Message 3 of 11
(6,779 Views)

So, first, the Bad News -- I see by the VI you attached that you are working with LabVIEW 8.0.  I'm going to post a simple example I wrote with LabVIEW 2016 -- it is simple enough that you should be able to reproduce it from the Snippet (which is an exception to the Don't Post Pictures, Only VIs rule, as Snippets, when copied into the appropriate LabVIEW Block Diagram, become VIs through NI "Magic").

 

So I don't have experience using the Peak Detector function, so I do what I tell my students to do, "write a little VI that generates a known signal", and analyze that.  This is a 1000-point sinusoid that, if it represented a 1KHz sample, would be a 5 Hz decreasing-amplitude sinusoid.  I pass it through Peak Detector and look at the results.

Peak Detection.png

And here's what this produces:

Peak Detection Results.png

Not bad.  But then, there's no "noise" in this signal.  Build this, then experiment with adding noise (like adding a Random Number, multiplied by a Noise control that you can vary, to every data point) and see when/if problems develop.

 

Bob Schor

Message 4 of 11
(6,759 Views)

Could you please elaborate more on the exact syntax your microcontroller is sending for the data?  I suspect an issue in how you are reading your serial port and now is the time to fix it.  It also could be causing you other issues.

 

My main concern here is that you are using the Bytes At Port function to tell how many bytes to read.  In a very large percentage of communications, this is not something you should do.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 5 of 11
(6,747 Views)

The actual signal has relatively flat tops, so if peak detection does not give you the needed accuracy maybe a 'zero' crossing approach will work better. 'Zero' has here to be defined since it is not a constant value (the signal looks like it also has a decaying offset).

The processing steps you may want to try are:

1 - Find the 'zero' crossing levels as the average values of two consecutive peaks. For example your first two peaks are at approx. 800 and 150 making the expected crossing value 475.

2 - Find the time where the crossing occurs either by finding the nearest value (a simple array search) if your sample period gives you the needed resolution or using linear interpolation (use the Threshold 1D Array function in your Array palette)

0 Kudos
Message 6 of 11
(6,709 Views)

thanks for all the reply's! i really appreciate it!

@Bob Schor

i was able to make the peak detection work via a sine function(there is also a pre-build VI under find examples about it), but the problem is that i need to find the peaks from an analog signal send by an arduino, and then i'm running into two problems. 1 is that it doesn't seem to be rather proficient at finding the peaks(but i suppose that could be fixed by adjusting some options) and 2 is that(if i'm right, mind you i'm rather new to this program) on the X-axis it shows loop iterations and not the actual time. so i cant find the actual period.

@crossrulz

i actually had to google what syntax is (english is not my main language) i'm using an arduino, which uses C i think ?
i'm basicly using this program which i found online. it gives an anlog signal from 0 to 1023

int potPin = 0; 
int val = 0;     

void setup()
{
  Serial.begin(9600);  
}

void loop() {
  val = analogRead(potPin);
  Serial.println(val);
  delay(10);
}

@localDSP

so if i understand this correctly you're saying that i need to basicly plot a line through the middle of the sine like function. let's say a sine like function has an beginning amplitude of 500  (so it goes from +500 to -500) and decreases after that. it's crossing point would be 0. and then if i can find t1 and t2 from when it crosses the 0 it's half a period and i'm able to calculate the period via (t2-t1)*2=period.

how exactly do i express that as a VI ? do i need to use the compare function for that ? like use the equal function and compare the imput untill it crosses the exact same number? how do i connect it so that when the compare function gives a true value that i can get an exact time (from the tick count(ms)) ?

0 Kudos
Message 7 of 11
(6,696 Views)

Ok, you do NOT want to use the Bytes At Port.  Just tell the VISA Read to read some "large" number, like 50, of bytes.  From the default inputs of the Configure Serial Port, you have the Termination Character turned on (which you want).  So the VISA Read will stop reading data when one of three things happens: reads the number of bytes specificed, reads a termination character, or times out (timeout currently set to 10 seconds).  So by telling the VISA Read to read more bytes than any message you ever expect, you will get complete messages.  If you use the Bytes At Port, you could check in the middle of a message coming through and then your data will be messed up.

 

So all you need to do to fix your serial communications is use a constant instead of the Bytes At Port to tell the VISA Read to read more bytes than a single message will ever be.  I like to use 50.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 8 of 11
(6,689 Views)

So one of the "features" of LabVIEW over, say, a "C" language on a simple microprocessor like an Arduino is the concept of Time being an important language primitive, and the integration of hardware-based Timers (like proper DAQ hardware for doing precisely-timed data acquisition and control).

 

When you get data from your Arduino, you really have no idea of the time coordinate of your data points, which makes it (shall we say) "tricky" to come up with a set of timed samples (by now you should realize that a "Sample" has two coordinates -- the sampled value and the time at which the sample was taken).  To compound the time uncertainty, you are then transmitting the data via what seems to be a fairly slow Serial Port communication from your Arduino to LabVIEW.

 

There are a number of relatively inexpensive DAQ devices that will do a much better job of acquiring data and giving you better X-resolution (i.e. more than 12 bits of A/D) and hardware timing (multiple KHz, with the ability to send, say, 1000 points at USB speeds to the PC continuously, so you know pretty precisely the relative timing of the points).  If you are a student, look at NI's myDAQ, or the USB-6002, for example.

 

Bob Schor

0 Kudos
Message 9 of 11
(6,688 Views)

First, it is safer to measure the period as the time difference between two crossings in the same direction than to only measure a half period (and multiply the value by 2). Your signal is not a clean tone and you can't be sure that the positive and negative half periods have the exact same length.

You need to find the time difference as for example shown on this figure.

Period Interpolation.jpg

 

For both the yellow and the green case you need to find the mid-point between the two consecutive peaks and then use the Threshold 1D Array function to find the exact time where the crossing occurs.

You can find your peak values (and approximate locations) using the Peak Detector VI that Bob suggested a few posting ago. From that you can extract the peak values you need to calculate the average value. You can use the approximate location of the high peaks to calculate an appropriate start index value to input to your Threshold 1D Array function. If you don't do that the function will find the first location where you are crossing the green level (marked as Not t2 on the figure) and not the one you want.

As discussed in other postings all this assumes that your waveform is correctly time stamped.

 

If you end having a waveform with constant dt, then you can calculate your time values directly by multiplying your fractional indices by dt.

If you end having un-equally spaced samples, for example an XY graph with X and Y arrays, you can still use the same method, but you'll have to use the fractional index value returned by the Threshold function to look-up the time in your X array. Use the integer part (n) of your fractional index to find the time X(n) and use the fractional part (a) to correct your time by a*(X(n+1) - X(n))

 

Suggestion: If you want to practice array manipulation and interpolation in LabVIEW you could create your own function (sub-VI) with same functionality as the Threshold 1D Array and (hopefully) get the same results.

0 Kudos
Message 10 of 11
(6,671 Views)