|
|
View previous topic :: View next topic |
Author |
Message |
Alex G. Guest
|
Low Frequency counter (1.00 to 100.00 Hz) |
Posted: Wed Dec 05, 2007 7:02 pm |
|
|
Hi,
I'm currently coding a function to get a really low frequencies (1 to 100 Hz) from an anemometer. The signal is like a square wave. I would like to count rising edges using timer_1 but the in the code example (exfreq.c) it's only rounding up. Does someone knows how I can get a more precise result using floats (let's say ±0.1Hz) ?
Here's the example:
int cycles8, cycles;
int32 freq;
long freqc_high;
long freqc_low;
cycles8=0;
cycles=0;
freqc_high=0;
t1_overflow=0;
set_timer1(0);
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
/* ___ wait one second ___ */
while (cycles!=0xFF) { //true=3, false=4
cycles8=0; //1 cycle
//start inner loop
while (cycles8!=0xFF) { //true=3, false=4
if (t1_overflow)//true=2,false=3 //----|
{t1_overflow=0;freqc_high++;}//6 cycles // |
else // |-- 8 cycles
{
delay_cycles(5);} //----|
delay_cycles(62); //x
cycles8++; //1
///2 cycles to jump to top
//math: end inner loop
//math: total inner loop=((3+8+x+1+2)*255 + 4)*255
//math: if x=62.87781 then inner loops takes 5mil instructions
//math: if x=62 then inner loop takes 4942920, have to fill 57080 cycles
}
delay_cycles(216); //y
cycles++; ///1 cycle
///2 cylces to jump to top
//math: outer=(3+1+y+1+2)*255+4=57080
//math: y=(57080-4)/255)-(3+1+0+0+1+2)
//math: if y=216.827450980392156862745098039216 then outer loop cylces is 57080
//math: if y=216 then outer loop cycles is off by 211 cycles. z=211
}
delay_cycles(211); //z
/* ___ end waiting 1 second ___ */
setup_timer_1(T1_DISABLED); //turn of counter to prevent corruption while grabbing value
if (t1_overflow) //check one last time for overflow
freqc_high++;
freqc_low=get_timer1(); //get timer1 value as the least sign. 16bits of freq counter
freq=make32(freqc_high,freqc_low); //use new make32 function to join lsb and msb
printf("%LU frequence en Hz\r\n",freq); //and print frequency
return 1.96*freq;
Cheers!
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
RLScott
Joined: 10 Jul 2007 Posts: 465
|
Re: Low Frequency counter (1.00 to 100.00 Hz) |
Posted: Fri Dec 07, 2007 9:07 am |
|
|
The key thing to understand in measuring low frequencies with high precision is that you should not try to count cycles. Instead you should focus on measuring the period of one or more cycles. Suppose you knew that 5 revs took 98334 microseconds. Then the frequency would be 50.847 Hz. The point is you can measure period with much more precision than you can measure frequency directly (at least for frequencies in this low range). If you wanted to get the same precision by counting cycles, you would have to wait until about 90000 revolutions went by. At 50Hz that would take you 30 minutes. I don't think you want to wait 30 minutes to get a reading. If you pick a time interval that allows about 20 revs, then your frequency precision would be 5%. Still not very good.
So let's say you are going to measure period. You could use the Input Capture mode of the CCP module to sample the instruction clock at each rising edge of your rev pickup. You could just use one rev all the time. This would give you the fastest response. Even at the low end of your range (1 Hz) you would get an update every 1 second. And what about the resolution? That is determined by several factors. The most obvious one is the resolution of the of the Timer 1 clock, which is probably more than adequate. Of course you will need to do some fancy overflow handling to account for the fact that at slower speeds your 16-bit Timer 1 may overflow. You will have to handle the overflow interrupt and form a software extension to the Input Capture values. There are pitfalls galore here in getting a coordinated extension to go with the values you capture, but with care you can do it.
The other limitation to the precision is your pickup itself. It is optical? Or magnetic? Whatever it is, it has its own inherent instability. So even if your device is rotating at exactly a constant speed, the exact time when the pickup fires may wander a little from one cycle to the next. Some pickup technologies are better than others. If you are limited by the precision of this pickup, then there is no sense in running the Timer 1 clock at its full speed. Use a prescaler to bring down the speed of Timer 1 so that it matches the precision of your pickup at the highest rotational speed. That may yield the added benefit of avoiding the possibility of 16-bit overflow over the RPM range that you are interested in.
Other considerations you may need to make is what to do when the device stops rotating completely. You should have a time-out that will report 0 RPM if the pickup signal stops for a given amount of time. Another refinement might be to vary the number of cycles over which you average, depending on the RPM. For example, using one cycle at 1 Hz may be just fine. But at 100 Hz, one cycle is only .01 seconds. You may not be able to measure this period accurately enough. In any case, you don't need to have 100 updates every second. So it makes sense at this speed to average over several revs. If you measured the period for 10 revs you would get 10 times the precision and still get 10 updates per second.
I hope this helps shed some light on the practical aspects of measuring low-speed frequencies.
Robert Scott
Real-Time Specialties |
|
|
Guest
|
Re: Low Frequency counter (1.00 to 100.00 Hz) |
Posted: Thu Dec 13, 2007 8:37 pm |
|
|
RLScott wrote: | The key thing to understand in measuring low frequencies with high precision is that you should not try to count cycles. Instead you should focus on measuring the period of one or more cycles. |
Thanks, I'm working on it |
|
|
|
|
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
|