Go Down

Topic: frequency counter for Atmega2560 (Read 1 time) previous topic - next topic

Ducaqabe

Hi , Nick Gammon

first thanks for your tutorial on this link http://www.gammon.com.au/forum/?id=11504 it is very useful, tutorial
I want to use the code on "Frequency Counter sketch for Atmega2560" on your tutorial,  when I tested the code it is counting either  odd numbers or even numbers , I tested using sigal generator,

what I wanted is to count numbers for example:
starting from:  80, 81, 82, 83, 84, 85, and so on
but the code is counting for example. 80, 82, 84, 86, 88, 90  and so on it is jumping over a one number
if I start for example  81,  it continued as  83, 85, 87, 89, 91

can you please help me by  telling what I have to change in your code to count - like . 60,61,62,63, 64,65,66,67,68,69,70  continued like that not jumping any number?

thanks


Nick Gammon

Yes, well that was on the Atmega328P. Perhaps if you post the code you used we can see what you did and compare it to the datasheet.
http://www.gammon.com.au/electronics

Ducaqabe

#2
Jan 27, 2013, 10:07 am Last Edit: Jan 27, 2013, 11:38 am by Ducaqabe Reason: 1
Hi, Nick Gammon

thanks for quick reply

I am using Amega2560 - seeeduino,the code is yours:  the code is working perfectly,when I tested, the problem is jumping over one number.
here is the code:
Code: [Select]
// Timer and Counter example for Mega2560
// Author: Nick Gammon
// Date: 24th April 2012

// input on pin D47 (T5)

// these are checked for in the main program
volatile unsigned long timerCounts;
volatile boolean counterReady;

// internal to counting routine
unsigned long overflowCount;
unsigned int timerTicks;
unsigned int timerPeriod;

void startCounting (unsigned int ms)
 {

 counterReady = false;         // time not up yet
 timerPeriod = ms;             // how many 1 mS counts to do
 timerTicks = 0;               // reset interrupt counter
 overflowCount = 0;            // no overflows yet

 // reset Timer 2 and Timer 5
 TCCR2A = 0;
 TCCR2B = 0;
 TCCR5A = 0;            
 TCCR5B = 0;  

 // Timer 5 - counts events on pin D47
 TIMSK5 = _BV (TOIE1);   // interrupt on Timer 5 overflow

 // Timer 2 - gives us our 1 mS counting interval
 // 16 MHz clock (62.5 nS per tick) - prescaled by 128
 //  counter increments every 8 uS.
 // So we count 125 of them, giving exactly 1000 uS (1 mS)
 TCCR2A = _BV (WGM21) ;   // CTC mode
 OCR2A  = 124;            // count up to 125  (zero relative!!!!)

 // Timer 2 - interrupt on match (ie. every 1 mS)
 TIMSK2 = _BV (OCIE2A);   // enable Timer2 Interrupt

 TCNT2 = 0;    
 TCNT5 = 0;      // Both counters to zero

 // Reset prescalers
 GTCCR = _BV (PSRASY);        // reset prescaler now
 // start Timer 2
 TCCR2B =  _BV (CS20) | _BV (CS22) ;  // prescaler of 128
 // start Timer 5
 // External clock source on T4 pin (D47). Clock on rising edge.
 TCCR5B =  _BV (CS50) | _BV (CS51) | _BV (CS52);

}  // end of startCounting

ISR (TIMER5_OVF_vect)
{
 ++overflowCount;               // count number of Counter1 overflows  
}  // end of TIMER5_OVF_vect


//******************************************************************
//  Timer2 Interrupt Service is invoked by hardware Timer 2 every 1ms = 1000 Hz
//  16Mhz / 128 / 125 = 1000 Hz

ISR (TIMER2_COMPA_vect)
{
 // grab counter value before it changes any more
 unsigned int timer5CounterValue;
 timer5CounterValue = TCNT5;  // see datasheet, (accessing 16-bit registers)

 // see if we have reached timing period
 if (++timerTicks < timerPeriod)
   return;  // not yet

 // if just missed an overflow
 if (TIFR5 & TOV5)
   overflowCount++;

 // end of gate time, measurement ready

 TCCR5A = 0;    // stop timer 5
 TCCR5B = 0;    

 TCCR2A = 0;    // stop timer 2
 TCCR2B = 0;    

 TIMSK2 = 0;    // disable Timer2 Interrupt
 TIMSK5 = 0;    // disable Timer5 Interrupt

 // calculate total count
 timerCounts = (overflowCount << 16) + timer5CounterValue;  // each overflow is 65536 more
 counterReady = true;              // set global flag for end count period
}  // end of TIMER2_COMPA_vect


void setup () {
 Serial.begin(115200);      
 Serial.println("Frequency Counter");
} // end of setup



void loop () {

 // stop Timer 0 interrupts from throwing the count out
 byte oldTCCR0A = TCCR0A;
 byte oldTCCR0B = TCCR0B;
 TCCR0A = 0;    // stop timer 0
 TCCR0B = 0;    
 
 startCounting (500);  // how many mS to count for

 while (!counterReady)
    { }  // loop until count over

 // adjust counts by counting interval to give frequency in Hz
 float frq = (timerCounts *  1000.0) / timerPeriod;

 // restart timer 0
 TCCR0A = oldTCCR0A;
 TCCR0B = oldTCCR0B;

 Serial.print ("Frequency: ");
 Serial.println ((unsigned long) frq);
 
 // let serial stuff finish
 delay(200);

}   // end of loop

what I have to modify this code so it can count .. 1,2, 3, 4, 5, 6, 7, 8, instead of 1 , 3, 5, 7, 9 or 2, 4, 6, 8, 10 using signal generator.

thanks

dhenry

Code: [Select]
startCounting (500);  // how many mS to count for

Would this have anything to do with your trouble?

Change the gate time.

Ducaqabe

hi  dhenry
thanks for helping.
I am not in the lab, I don't have signal generator my selv, I will test  after 1 hour, so instead of this
Code: [Select]
startCounting (500);  // how many mS to count for shall I increase or decrease the counting number , I will test soon, but my problem is the code is counting either odd numbers or even numbers, and I want to count both,  like this way. 90, 91, 92, 93, 94,95,96 ....... and so on 

dhenry

My telling you what to do doesn't help you, if you don't understand why you are observing what you are observing.

The original code isn't well documented but the following may help you understand what is happening:

Code: [Select]

unsigned int timerPeriod;

void startCounting (unsigned int ms)
...
  timerPeriod = ms;             // how many 1 mS counts to do
...
  startCounting (500);  // how many mS to count for
...
  float frq = (timerCounts *  1000.0) / timerPeriod;


Once you figure out the problem, the solution is right there.

Nick Gammon


I am not in the lab, I don't have signal generator my selv, I will test  after 1 hour, so instead of this
Code: [Select]
startCounting (500);  // how many mS to count for shall I increase or decrease the counting number , I will test soon, but my problem is the code is counting either odd numbers or even numbers, and I want to count both,  like this way. 90, 91, 92, 93, 94,95,96 ....... and so on 


Why are you expecting the count to go up anyway? What frequency are you putting into it?

Putting in 1 KHz square wave I get this:

Code: [Select]

Frequency: 1000
Frequency: 1000
Frequency: 1000
Frequency: 1000
Frequency: 1000
Frequency: 1000
Frequency: 1000
Frequency: 1000
Frequency: 1000
Frequency: 1000
Frequency: 1000
Frequency: 1000
Frequency: 1000
Frequency: 1000
Frequency: 1000
Frequency: 1000
Frequency: 1000


I don't see why it would increase by odd or even numbers. It is supposed to be giving you the frequency of counts per second, with the gate time (that dhenry mentioned) being the sample period.

Quote
Change the gate time.


Which way, dhenry? Provide reasons for your answer.
http://www.gammon.com.au/electronics

Nick Gammon


The original code isn't well documented but the following may help you understand what is happening:


I have repeatedly asked you to post code to demonstrate some of the things you claim you have done, dhenry. If you were to do so, we could see how properly-written and documented code looks like.
http://www.gammon.com.au/electronics

Go Up