Go Down

Topic: frequency counter for Atmega2560 (Read 2562 times) 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.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
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.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
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.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

kb8vsa

#8
Sep 01, 2016, 05:31 pm Last Edit: Sep 01, 2016, 08:11 pm by kb8vsa Reason: error in code
Hello Nick and thanks much for your posting on this link http://www.gammon.com.au/forum/?id=11504 .  It is very useful, in helping me get started with an Arduino 2560 that Im using to collect 2 frequency signals and 7 analog signals... My frequency signals range from 1 - 15 Khz on one channel and 4 khz on the second channel.  

I have your code running fine for the input on pin 47 but having problems getting the second frequency recognized.  The second input reads only 0's ...

My modifications to your original code to include a second input include the following additions...Im wondering if you can glance at this and see the error of my ways..



// Reset timers 2, 4, and 5

TCCR4A = 0
TCCR4B = 0
TCCR5A = 0
TCCR5B = 0

// Count the events on D43 & D47

TIMSK4 = bit (TOIE4);
TIMSK5 = bit (TOIE5);

after Timer 2 stuff ... set all timers to zero

TCNT2 = 0
TCNT4 = 0
TCNT5 = 0

// Start timer 4 and 5

TCCR4B = bit (CS40) | bit (CS41) | bit (CS42)
TCCR5B = bit (CS50) | bit (CS51) | bit (CS52)

//Run the ISR

timer4CounterValue = TCNT4
timer5CounterValue = TCNT5

// If just missed an overflow

if (TIFR5 & TOV5 || TIFR4 &TOV4)

// stop timers 2, 4 and 5

// disable timers 2, 4 and 5

// calculate the total counts

timerCountsSpeed = (overflowCount << 16) + timer4CounterValue;
timerCountsTorque = (overflowCount << 16) + timer5CounterValue;


cattledog

Quote
I have your code running fine for the input on pin 47 but having problems getting the second frequency recognized.  The second input reads only 0's ...

My modifications to your original code to include a second input include the following additions...Im wondering if you can glance at this and see the error of my ways..
You are trying to adapt a sketch which uses the external clock source as input for the timer. That input for Timer5 is broken out on the mega digital pin 47.

Unfortunately, there is no breakout for the equivalent pin on Timer 4. You need to spend some time looking at the Arduino pin out diagrams along with the processor pin diagrams. Where did you get the idea that you should be reading the second frequency on pin 43?

You need to go back to Nick's website, and look at the frequency counters near the bottom of the pages in replys #12 and #13. They use the input capture pins and not the external clock source. You should be able to modify one of the for your two frequencies on the Mega. For the Mega ICP5 = digital pin 48 and ICP4 is digital 49.

kb8vsa

#10
Sep 01, 2016, 11:18 pm Last Edit: Sep 01, 2016, 11:26 pm by kb8vsa
thanks cattledog .... Ill take a look .. not sure where I found the mapping to pin 43 and T4 but tried several combinations without successful combination.  At a glance it looks like T4 is available on processor pin 27 but thats not mapped to a terminal on Mega.... Ill take a look at Nicks other freq measurement posting...

thank again

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy