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 CCS Technical Support

Frequency counter

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



Joined: 20 Feb 2008
Posts: 33

View user's profile Send private message

Frequency counter
PostPosted: Wed Mar 05, 2008 2:35 am     Reply with quote

My next work with PIC is count the frequency, could you tell me how to measure the frequency of a sine wave or even not sine wave, and which part of the PIC will contribute a lot in this measurement ?
Thanks so much !!!
barata



Joined: 07 Feb 2008
Posts: 6
Location: Portugal

View user's profile Send private message

EX_FREQC.C
PostPosted: Wed Mar 05, 2008 3:43 am     Reply with quote

Hi,

there are many ways to make this, here are two of them:

You can use a zero crossing detection like in the EX_FREQC.C in the examples of the compiler. this code works good i try it some years ago.

Other way is use a f/v conveter, is a IC how convert frequency in voltage, to can measure is ADC of the pic, is a simple hardware.
smiles



Joined: 20 Feb 2008
Posts: 33

View user's profile Send private message

PostPosted: Thu Mar 06, 2008 7:19 am     Reply with quote

Hi thanks ! I read the example, I think coding now is not my big problem
The problem here is I don't understand so good about how to measure frequency with a PIC
I imagine quite simply that you put your signal to a pin, but what if that signal is negative at one time (pin receives negative voltage), what if that signal is high amplitude (like 220VAC), what are the components that can create frequency signal, is frequency measurement applied for synchronous signal and can we with our specified circuit just measure one range of frequency ?
Hope you answer me, thanks so much !
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

PostPosted: Thu Mar 06, 2008 7:41 am     Reply with quote

smiles wrote:
...I imagine quite simply that you put your signal to a pin, but what if that signal is negative at one time (pin receives negative voltage), what if that signal is high amplitude (like 220VAC), what are the components that can create frequency signal, ...


You cannot connect any old signal to a PIC pin and just "measure its frequency". When people talk about using a PIC to measure frequency, they are usually thinking about a clean logic-level signal. Clean means just two logic transitions per cycle - one going high and one going low. If you have a high-amplitude signal, like 220 vac, then you must use a circuit to convert that signal into a clean logic signal.

If your signal is not clean, then there are several ways to clean it up. One is to use a comparator with hysteresis to ignore a little bit of noise that might be riding on top of the signal. Another method is to use time filtering - a one-shot for example, which ignores all transitions for a given period of time after a recognized transition. For this to work you need to know in advance approximately what the measured frequency must be so you can set the one-shot time period. Finally, for the case where the signal is really buried in lots of noise, like trying to detect the pitch of a flute in an orchestral recording, you will need to use very sophisticated signal processing methods, like the Fourier Transform, to isolate the frequency of interest.

Robert Scott
Real-Time Specialties
smiles



Joined: 20 Feb 2008
Posts: 33

View user's profile Send private message

PostPosted: Fri Mar 07, 2008 2:48 am     Reply with quote

Thanks so much, I got some ideas !
Now I want to ask which pins is the best for receiving that signal (the signal for measuring frequency purpose) ?
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

PostPosted: Fri Mar 07, 2008 6:01 am     Reply with quote

smiles wrote:
..which pins is the best for receiving that signal (the signal for measuring frequency purpose) ?


Use a CCP pin. That will allow you to capture the value of Timer 1 on every rising edge of the signal being measured. If you subtract two of those captured Timer 1 values, you get the period between cycles. Count for several cycles to get an average value that is more accurate.

Robert Scott
Real-Time Specialties
smiles



Joined: 20 Feb 2008
Posts: 33

View user's profile Send private message

PostPosted: Fri Mar 07, 2008 7:22 am     Reply with quote

Thanks Scott, I will simulate with Proteus first !
smiles



Joined: 20 Feb 2008
Posts: 33

View user's profile Send private message

PostPosted: Mon Mar 10, 2008 3:03 am     Reply with quote

Hi, this is my test circuit on Proteus (crystal 4MHz) http://img81.imageshack.us/img81/3371/88568235ij7.jpg, I put a pulse generator (100Hz,5V high and 0V low) to CCP1 pin, write the code as below but the value of frequency I got on LCD is <50 Hz always, what wrong with my code ?
(I will use probe of real oscilloscope to create pulse and applied to pin CCP1 on my real hardware, so try to test on simulate tool first)
Code:

   // GUIDED WORDS AND VARIABLES
   int i=0;
   int32 sum;
   int16 pulseWidth[5],period,freq;
   char words[]="THE VALUE OF FREQUENCY: ";
   char words1[]="   >=50Hz";
   char words2[]="   <50Hz";
....
#int_ccp1
void isr()
   {
   int16 currentCCP;
   static int16 oldCCP = 0;
   currentCCP=CCP_1;
   pulseWidth[i]=currentCCP-oldCCP;
   sum=sum+pulseWidth[i];
   i++;
   if(i==5)
   {
      period=sum/5;   //average value of period
      freq=1000000/period;   //frequency value
      disable_interrupts(GLOBAL);
      disable_interrupts(INT_CCP1);
      setup_timer_1(T1_DISABLED);
   }
   }
//**********************
void main()
{
   // TODO: USER CODE!!
   InitPic();
   InitLcd();
   Speech(words,0x00);
   setup_ccp1(CCP_CAPTURE_RE);    // Configure CCP1 to capture rise
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);       // Start timer 1
   enable_interrupts(INT_CCP1); // Setup interrupt on falling edge
   enable_interrupts(GLOBAL);
   do
   {
   }
   while(i!=5);
   if(freq<50)
   Speech(words2,0x80 + 0x40);
   if(freq>=50)
   Speech(words1,0x80 + 0x40);
   do
   {
   }
   while(1);
}
....
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

PostPosted: Mon Mar 10, 2008 5:30 am     Reply with quote

Are you sure sum is initialized to zero? It would be helpful if you could display some information - something more than just "<50" or ">50". For example, it would be interesting to see exactly what pulseWidth[0]...pulseWidth[4] are. Do it for several know frequency settings of your pulse generator. Then perhaps you can see a pattern that will lead you to the answer.

Robert Scott
Real-Time Specialties
smiles



Joined: 20 Feb 2008
Posts: 33

View user's profile Send private message

PostPosted: Tue Mar 11, 2008 3:18 am     Reply with quote

Follow your advice and finally try this and it works (on simulation) Very Happy
Thanks again !!!
Code:

#int_ccp1
void isr()
   {
   int16 currentCCP;
   if(start==1)
   {
   currentCCP=CCP_1;
   pulseWidth=currentCCP-oldCCP;
   freqNum=(float)1000000/pulseWidth;
   freqRes=ceil(freqNum);
   disable_interrupts(GLOBAL);
   disable_interrupts(INT_CCP1);
   setup_timer_1(T1_DISABLED);
   i=1;
   }
   if(start==0)
   {
   oldCCP=CCP_1;
   start=1;
   }
   }
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