CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Finding frequency

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Aayush13



Joined: 12 Aug 2016
Posts: 14

View user's profile Send private message

Finding frequency
PostPosted: Tue Jan 03, 2017 8:50 pm     Reply with quote

I have hooked up a function generator to pin A1 to get the various values for the sinewave. I have found the amplitude and the RMS value already. I want to write code to find the frequency of the sine wave. How should I go about doing this?

Last edited by Aayush13 on Wed Jan 04, 2017 10:02 am; edited 2 times in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Wed Jan 04, 2017 3:06 am     Reply with quote

First:

setup_adc(ADC_CLOCK_INTERNAL);

is _not_ recommended if your system clock is above 1MHz. read the data sheet and correct this.

Now a lot depends on just how fast this signal is?.
If it is above a few tens of Hz, then really you need to read the frequency a different way. Instead of using the ADC, have an external zero crossing detector, and feed the output of this into one of the CCP inputs. Then there is code in the examples for measuring a frequency using the CCP.
If however it is slow enough that you can get several ADC samples each cycle, then you basically can do the same in software. Now you say 'unipolar'. Do you mean you have the signal rectified?. Normally you'd use an op-amp to offset the AC signal, and bias this so that it's being fed into the PIC with it's 'zero' at perhaps half the Vref (so at 2.5v, since you are not using an external Vref). Then you set a flag when the signal is in it's positive half cycle (so >512). When you see the signal go into the -ve half cycle, with this flag 'true', you have seen the +ve to -ve zero-crossing. Record the value of a timer when this happens, and you have the period of one cycle of the waveform.
temtronic



Joined: 01 Jul 2010
Posts: 9174
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Jan 04, 2017 7:58 am     Reply with quote

I'll assume he's measuring line frequency as his acquisition loop is about 33ms.

Just thinking about a simple way with current data...

One somewhat inaccurate method to get a rough frequency would be to take the array max index, subtract the array min index, then multiply by the loop 'delay'. Effectively the number of 666us delays between ADC max and ADCmin.

IE: given array[21] = 255, array[41]=0

41-21=20

20 * 666= 13,320 us or .0132ms

1/.0132 = 75.75 Hz

rough , doesn't take into consideration the time to read the ADC and store the data or increment the counter but.....
it'd be interesting to see what real numbers look like.

Jay
Aayush13



Joined: 12 Aug 2016
Posts: 14

View user's profile Send private message

PostPosted: Wed Jan 04, 2017 8:17 am     Reply with quote

temtronic wrote:
I'll assume he's measuring line frequency as his acquisition loop is about 33ms.

Just thinking about a simple way with current data...

One somewhat inaccurate method to get a rough frequency would be to take the array max index, subtract the array min index, then multiply by the loop 'delay'. Effectively the number of 666us delays between ADC max and ADCmin.

IE: given array[21] = 255, array[41]=0

41-21=20

20 * 666= 13,320 us or .0132ms

1/.0132 = 75.75 Hz

rough , doesn't take into consideration the time to read the ADC and store the data or increment the counter but.....
it'd be interesting to see what real numbers look like.

Jay


Could you explain why you put 21 and 41 for array[]?
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Wed Jan 04, 2017 8:44 am     Reply with quote

He doesn't.....

Read what he says. He is saying _if_ the high points and the low point in the array were 21, & 41, then the timing would be as shown.

You need to be testing the values in the array to find the low and high points.

However accuracy will be very bad. Given the huge sample interval, you could miss the high point and the low point by nearly a mSec each.


Last edited by Ttelmah on Wed Jan 04, 2017 8:52 am; edited 1 time in total
temtronic



Joined: 01 Jul 2010
Posts: 9174
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Jan 04, 2017 8:48 am     Reply with quote

21 is the index(location) of the element in the array that has the minimum value from the ADC and 41 is the index(location) of the element of the array that holds the maximum value from the ADC.
These are just examples for my post. You'll have to do the code to get them from your program. You need the difference between them, in my case 20 'units'. Multiplied by the 'loop delay' ( 666us in your code) to get a rough time between high and low of the sine wave.
Actually while typing this , you need 4X the result , as my idea just gets you 90* worth of time.

I need another coffee.....

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Wed Jan 04, 2017 8:55 am     Reply with quote

It would (of course) be a lot more accurate to find successive high points (so the full 360 degrees).

However he hasn't answered the question about the nature of the waveform.

Ideally if the data is an offset sine, then my thought would be to find the two values that 'span' where it crosses the zero, and make an assumption that the signal is linear between, and hence calculate the time where it crosses quite accurately by interpolation.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Wed Jan 04, 2017 11:10 am     Reply with quote

The general principle with sine waves is to measure period/frequency by sampling where the waveform is changing at its fastest.
In other words, at the zero crossing (or its equivalent for an offset waveform).
Or has something changed in the last half century, when I wasn't looking?

Until you tell us what your amplitude and frequency ranges are we can offer little further help.

Mike

You're also not giving any clues about how you're getting amplitude and RMS values.
It's just possible you already have the data to hand and simply need to extract it.
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Thu Jan 05, 2017 1:40 am     Reply with quote

Exactly.
And given the low sample rate relative to the actual frequency, linear interpolation between the samples each side will give a better result.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group