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 measurements in a good way?

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







Frequency measurements in a good way?
PostPosted: Fri Feb 28, 2003 3:08 pm     Reply with quote

I am planning to make a data logger (16F870) which should store 2 independent frequencies in an external memory but I am uncertain how I should implement it in an intelligent way...

Both frequencies varies between 0-200Hz and the accuracy of measurement does not need to be 100\% perfect. The problem is that I would like to store the values at certain time intervals, say every 100ms, or perhaps with some form of timestamp in order to be able to calculate the total measurement time when analysing the stored data.
First I was thinking of have a free running timer which at interrupt saves the latest measured values but ran into problems since this interrupt may occur at the same time as the interrupts used for frequency measurements. Hence the measured frequency got corrupt.

Does anyone have a theory on how to tackle the problem?

Regards,
/John
___________________________
This message was ported from CCS's old forum
Original Post ID: 12238
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

Re: Frequency measurements in a good way?
PostPosted: Fri Feb 28, 2003 3:26 pm     Reply with quote

:=I am planning to make a data logger (16F870) which should store 2 independent frequencies in an external memory but I am uncertain how I should implement it in an intelligent way...
:=
:=Both frequencies varies between 0-200Hz and the accuracy of measurement does not need to be 100\% perfect. The problem is that I would like to store the values at certain time intervals, say every 100ms, or perhaps with some form of timestamp in order to be able to calculate the total measurement time when analysing the stored data.
:=First I was thinking of have a free running timer which at interrupt saves the latest measured values but ran into problems since this interrupt may occur at the same time as the interrupts used for frequency measurements. Hence the measured frequency got corrupt.
:=
:=Does anyone have a theory on how to tackle the problem?
:=
:=Regards,
:=/John
------------------------------------------------------------
I'm not sure how the timer isr would corrupt the frequency
values, because the PIC (and CCS) does not support nested
interrupts.

Maybe you're reading the freq variable outside of the
isr, and it's a word variable (2 bytes) ? In that case,
just disable interrupts and copy the freq variable to
another variable. Then re-enable interrupts. That way,
you can't ever read a partially updated word value.
You'll always read the correct value.

---------

You didn't ask this, but the standard way to measure frequency
with a PIC is to use the CCP module.

If you want to extend the Timer1 to 24 bits, and avoid the
"gotcha's" involved with interrupt latency, you can see my
sample code here:
http://www.ccsinfo.com/forum/viewtopic.php?t=906
Using a 24-bit timer allows you to measure low values
of the frequency without having to switch between different
CCP pre-scalers.

--------

Edited on Jan. 31, 2005 to update the link so it actually points to
the correct thread. When the old forum was ported over to this
new forum, the embedded links didn't work anymore. Now at
least this one is fixed.

___________________________
This message was ported from CCS's old forum
Original Post ID: 12239


Last edited by PCM programmer on Mon Jan 31, 2005 1:01 pm; edited 1 time in total
John
Guest







Re: Frequency measurements in a good way?
PostPosted: Sat Mar 01, 2003 1:15 pm     Reply with quote

:=I'm not sure how the timer isr would corrupt the frequency
:=values, because the PIC (and CCS) does not support nested
:=interrupts.
:=
:=Maybe you're reading the freq variable outside of the
:=isr, and it's a word variable (2 bytes) ? In that case,
:=just disable interrupts and copy the freq variable to
:=another variable. Then re-enable interrupts. That way,
:=you can't ever read a partially updated word value.
:=You'll always read the correct value.
:=
:=---------
:=
:=You didn't ask this, but the standard way to measure frequency
:=with a PIC is to use the CCP module.
:=
:=If you want to extend the Timer1 to 24 bits, and avoid the
:="gotcha's" involved with interrupt latency, you can see my
:=sample code here:
:= <a href="http://www.pic-c.com/forum/general/posts/10833.html" TARGET="_blank"> <a href="http://www.pic-c.com/forum/general/posts/10833.html" TARGET="_blank">http://www.pic-c.com/forum/general/posts/10833.html</a></a>
:=Using a 24-bit timer allows you to measure low values
:=of the frequency without having to switch between different
:=CCP pre-scalers.

Thanks for your reply.
Since I am using a F870 I only have one CCP so I thought I'd test using int_rb as the interrupt for measuring both frequencies. The idea was to use RTCC as a free running timer which value is captured when an int_rb occurs. I used timer 2 to create "constant" intervals for saving the data. As I tested the code below I found that it works ok at higher frequencies but at lower it gives errors (signal period higher than the period between data save).
In the test code below I only measure one frequency and don't really save it, only print it on screen. I feel that it could be done much more effective but I don't know how... (the great newbie feel :-) )
Is it possible to get it to work or should I do it completely differently?

#include <16f870m.h>
#fuses HS, NOPROTECT, NOWDT, PUT, NOLVP
#use DELAY(clock=4000000)
#use fast_io ( A )
#use fast_io ( B )
#use fast_io ( C )
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)
#bit speed = 0x06.4 //RB4

//GLOBAL VARIABLES
int speedcount=0; //timer_0 value
short speed_on=0; //speed timing period?
int speed_r_over=0; //increases at every timer0 roll over

#int_timer2
timer_2_isr(){
disable_interrupts(GLOBAL);
printf("\r \%3U \%2U", speedcount, speed_r_over); //"save" data
enable_interrupts(GLOBAL);
}

#int_rb
rb_isr() {
if (speed && !speed_on){ //trig L->H measure start
set_timer0(0);
speed_r_over=0;
speed_on=1;
}
else if (speed && speed_on){ //trig L->H measure stop
speedcount=get_timer0();
speed_on=0;
}
}

#int_rtcc
timer0_isr() {
speed_r_over += 1;
}

void main( void )
{
set_tris_a ( 0b11110000 );
set_tris_b ( 0b11111100 ); //RB4 speedtrigger
set_tris_c ( 0b10000000 ); //RC6,7 RS232

setup_timer_2(T2_DIV_BY_16, 250, 8);
setup_counters(RTCC_INTERNAL,RTCC_DIV_256);
enable_interrupts(int_rb);
enable_interrupts(INT_TIMER2);
enable_interrupts(int_rtcc);
enable_interrupts(GLOBAL);

while(1); //just wait for the interrupts...
}

/John
___________________________
This message was ported from CCS's old forum
Original Post ID: 12257
John
Guest







Maybe not in a good way, but it works...
PostPosted: Sat Mar 01, 2003 4:15 pm     Reply with quote

Don't know why I wrote the rb isr as I did... Changing it to the following made it work at least (with some other minor code changes).
#int_rb
rb_isr() {
if (speed) {
speedcount=get_timer0();
set_timer0(0);
}
}
/John
___________________________
This message was ported from CCS's old forum
Original Post ID: 12260
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