I'm working with Interrupts for counting signals for about one year now - and things worked very fine with AttachInterrupt and incrementing variables in an ISR (https://www.arduino.cc/en/Reference/AttachInterrupt). Using an Arduino Uno I counted signals on Digital Pin 2 and Digital Pin 3.
Unfortunately I do find plenty of general informations (Timer 0 is 8 bit and used for delay() and millis(), Timer 1 is 16 bit and used by the Servo library, Timer 2 is 8 bit and used for the tone library) about timers (for example http://www.instructables.com/id/Arduino-Timer-Interrupts/), preloaders and prescalers - but almost nothing about a simple counter!
Since I do use millis() from time to time I would prefer Timer 1 or Timer 2, and since I do not see a reason for using 16 bits I would prefer the timer 2 with 8 bit incrimenting a variable after every overflow (255 counts) or after a specific number of counts (timer compare interrupt?) without prescaler or preloader.
I tried the following setup
cli();//stop interrupts
TCCR2A=0; // set entire TCCR2A register to 0
TCNT2 = 0;//initialize counter value to 0
TCCR2A |= (1 << WGM21); // turn on CTC mode
TIMSK2 |= (1 << OCIE2A); // enable timer compare interrupt
sei();//allow interrupts
and the following ISRs:
ISR(TIMER2_COMPA_vect) { // timer compare interrupt service routine
zaehler_compare_match++; //
}
ISR(TIMER2_OVF_vect) { // timer für Überlauf
zaehler_ueberlauf++; //
}
Nothing is working now, and I do not know how to declare a specific pin for my signal and how to get the data (255*zaehler_ueberlauf+counter) and reset the counter after a specific time (every second: millis()%1000==0). And I do not know, if I could count 2 pins in parallel?
Could anyone please help me with this problem?
thank you for your input, so Timer2 is a bad idea.. Timer0 is a taboo if I do want to use millis() -> I do have to use Timer1 and Digital Pin 5 (and there is no possibility to do 2 measurements in parallel)
Do you have an idea of an usable code?
TCCR1A=0; // set entire TCCR1A register to 0
TCCR1B=0; // set entire TCCR1B register to 0 (16 bit)
TCNT1 = 0;//initialize counter value to 0
TIMSK1 |= (1 << TOIE1); // enables overflow interrupt
and
ISR(TIMER1_OVF_vect) // interrupt service routine that wraps a user defined function supplied by attachInterrupt
{ overflow_counter++;}
seem to be a good start - however I have no idea how to get out the counted numbers?
Here is an example of a simple frequency counter. It uses blocking code and the counting period is for high speed counts, but this will give you the set up for the external clock source. The external clock source can be set for rising or falling edge. You read the counts with TCNT1. If the counts go over the 16 bit limit, you will need to deal with rollover counting.
//frequency counter using Timer1 counter without overflow count
//TCNT1 16 bit max value = 65,534
//20ms sample period gives frequency counter to a bit over 3.2 mhz
unsigned int dwell = 20000; // dwell in microseconds for counter
unsigned long final_counts;
unsigned long start_time;
unsigned long measured_time;
void setup()
{
Serial.begin(115200);
TCCR1A = 0; //initialize Timer1
TCCR1B = 0;
TCNT1 = 0;
pinMode( 5, INPUT_PULLUP); //external source pin for timer1
}
void loop()
{
start_time = micros();
TCNT1 = 0;//initialize counter
// External clock source on Timer1, pin (D5). Clock on rising edge.
// Setting bits starts timer
TCCR1B = bit (CS10) | bit (CS11) | bit (CS12); //external clock source pin D5 rising edge
while (micros() - start_time < dwell) {} // do nothing but wait and count during dwell time
TCCR1B = 0; //stop counter
final_counts = TCNT1; //frequency limited by unsigned int TCNT1 without rollover counts
measured_time = micros() - start_time;
Serial.print(measured_time); // report resulting counts
Serial.print("\t\t");
Serial.println(50 * final_counts); //20ms sample in Hz
}