Input CapturePin for Counter on atmega328

I learned best for counting and fast frequency measuring is usage of Timer/Counters.

Using the 16 bit Timer1 seems appropriate
I think I understand that stuff in general, e.g. setting a proper prescaler and mode in TCCR1A/B

I'm just confused about my findings, which is the proper pin to apply the pulses:
Some tell about
PB0 = ICP1 = Pin 14 = Arduino D8
Nick Gammon refers to
PD5 = T1 = Pin 11 = Arduino D5

Am I mixing different counting/timing modes or do I) mix texts for different controllers ?

If you can guess where my confusion comes from,
(and perhaps even can help clarify,)
any comment is appreciated.

Either can work but they work in dramatically different ways.

ICP1 drives the "Input Capture" peripheral. The Timer / Counter runs as a Timer. You specify whether a lo->hi transition or a hi->lo transition is captured. When a value is captured, an interrupt is generated. In your interrupt service routine you copy the value to a safe place and set a flag to indicate fresh data is available. The value is essentially a timestamp of the event.

T1 drives the Counter directly (External Clock Source). Reading the counter (TCNT1) gives you the number of pulses that have occurred on the T1 pin. Typically, you would have a blink-without-delay structure in loop. Every X milliseconds, you read the counter, determine the delta, then calculate the frequency.

The first method (Input Capture) works well for "lower" frequencies or measuring individual pulse widths. The second method (External Clock Source) works well for "higher" frequencies.

Thanks for your reply.
I see the difference, just have to find the exact difference how the counter is set up for both cases.

The first method (Input Capture) works well for "lower" frequencies or measuring individual pulse widths.

It requires an ISR for every pulse to process the counter value. Has the advantage that the timer value is preserved, compared to a pure ISR on pin change. An ISR takes at least some µs, so it's limited to frequencies of about 50kHz, but giving each single pulse width.

The second method (External Clock Source) works well for "higher" frequencies.

As a minimum an ISR for counter overflow is required, allowing to get the total pulse count as slowly as desired.

If I understand it right, even a prescaler can be applied , if the exact number of pulses is irrelevant ?
Pulses can be as fast as the clock speed ( 16 MHz ) ?

michael_x:
Thanks for your reply.

You are welcome.

I see the difference...

Definitely. That is a very good description of the difference between the two.

If I understand it right, even a prescaler can be applied...

No. You can have an External Clock Source or you can have a prescaler but not both.

Pulses can be as fast as the clock speed ( 16 MHz ) ?

Nyquist says "no". One-half the I/O clock speed is the absolute maximum. According to Atmel, that should be further restricted to I/O-clock-divided-by-2.5...

However, due to variation of the system clock frequency and duty cycle caused by Oscillator source (crystal, resonator, and capacitors) tolerances, it is recommended that maximum frequency of an external clock source is less than fclk_I_O / 2.5 .

Thanks for that additional info.

I understand for signals in the 100kHz to 1 MHz range I can count pulses, but cannot get their individual pulse/pause lengths.

BTW: What happens if a UART ( more precisely: the UART inside an atmega328 ) does not get the expected stop bit?
Does it simply wait and resync with the next 0000-111-0 and interpret the 1-0 as a new start bit ?

This could give a rough estimate of pulse/pause lengths
or help detect an unknown but rather high asynchronuous baud rate ...

Hello,
I want to ask to you all masters in microcontroler, I want to count pulses that occurred in pin D5 from a Hall Effect sensor with hardware counter using Timer/Counter1. I'm using Arduino Promini At328 5V/16MHz, with 3,3V supply
here's my code:

unsigned int count;
unsigned long lastCount;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(5, INPUT);
  
  noInterrupts(); // disable all interrupts
  TCCR1A = 0; // Normal Mode
  TCCR1B = 0; // Reset Register TCCR1B
  TCNT1 = 0; // Reset Timer/Counter1
  OCR1A = 2; // Set the value to be compare with TCNT1 value
  bitSet(TCCR1B,WGM12); // set as CTC mode
  bitSet(TCCR1B, CS12); // Setup register TCCR1B
  bitSet(TCCR1B, CS11); //
  bitSet(TCCR1B, CS10); // Clock Source from external clock
  bitSet(TIMSK1, OCIE1A); // enable timer compare interrupt (should I activated this ? )
  //bitSet(TIFR1, OCF1A); // enable timer1 flag compare A (should I activated this ? )
  count = TCNT1;
  interrupts(); // enable all interrupts
}

ISR(TIMER1_COMPA_vect){ // interrupt Service Routine
  count = TCNT1; 
  TCNT1 = 0; 
  lastCount = count + lastCount;  
}

void loop() {
  // put your main code here, to run repeatedly: 
  Serial.print(count);
  Serial.print("     ");
  Serial.println(lastCount);
  delay(100);
}

What I see in Serial monitor is merely 0 (for count and lastCount).
Would you help me to show where in the code that I make mistake?
Thank you.

Regards,
Handy

handy_mosey:
I want to count pulses that occurred in pin D5 from a Hall Effect sensor with hardware counter using Timer/Counter1. I'm using Arduino Promini At328 5V/16MHz, with 3,3V supply

So you will not be using Input Capture. Correct?