Measuring a frequency using ATmega timer & counter

Hello,
I am currently trying to build an LC meter that I want to use to measure the capacity of capacitors or inductance of coils / HF throttles.
For this, my basic idea is to have a resonating circuit with a capacitor and a HF throttle:

Currently, I am using 720 pF and 311 uH which should result in a frequency of ~ 332 kHz.
When measuring with an oscilloscope, the frequency is 337.8 kHz (I don’t know how to export from the oscilloscope) and looks like that:

So everything should be fine. I connected the output of the comparator (LM311) to pin 5 (T1) of an ATmega 168 running at 16 MHz.

Now for the programming part.
My first idea was to use the pulseIn() functionality.
However, because I have an input of 338 kHz which is 2.96 us but pulseIn() only gives full us (return value type long) so it is way too unprecise to use.

So I am currently attempting to measure the frequency by counting the “ticks” in a known gate time.
For this, I set the atmega’s timer 1 to trigger on rising edge, and timer 2 to tick every 4.096 ms:

#define LED 8

// Interrupt interval in us
// iinterval = prescale * (ocr2aval + 1) / (F_CPU / 1.0e6);

void setup() {
  Serial.begin(9600);
  pinMode(LED, OUTPUT);
  
  cli();

  // Timer 1 counter mode
  TCCR1A = 0;
  TCCR1B = (1 << ICES1) | (1 << CS12) | (1 << CS11) | (1 << CS10);
  TCCR1C = 0;

  // Set Timer 2 CTC mode
  // WGM22:0 = 010: CTC Mode
  // WGM2 bits 1 and 0 are in TCCR2A,
  // WGM2 bit 2 is in TCCR2B
  //
  TCCR2A = (1 << WGM21);

  // Set Timer 2  prescale 1024
  //
  // CS22:0 = 101: prescale = 1024
  // CS2 bits 2:0 are all in TCCR2B
  TCCR2B = (1 << CS22) | (0 << CS21) | (1 << CS20);
  
  // Enable Compare-match register A interrupt for timer2
  TIMSK2 = (1 << OCIE2A);

  // This value determines the interrupt interval
  OCR2A = 64-1;

  // Enable global interrupts: Ready to run!
  sei();

}

volatile uint16_t count = 0;

void loop() {
  delay(1000);
  
  Serial.println(count);
  // freq [kHz] = ticks [Hz]/1.024 ms
}

// ISR For Timer 2 Compare-match interrupt
ISR(TIMER2_COMPA_vect) {
  
  count = TCNT1;
  TCNT1 = 0;

}

But whatever which prescaler I use, I get wrong values for the frequency. Here are my results:

prescaler gate frequency ~ time is ticks is frequency
210 CS with OCR 64-1 I am expecting 337.71 kHz
001 => clock/1 => 250 kHz ~ 0.004 ms got 1 tick
010 => clock/8 => 31.25 kHz ~ 0.032 ms got 10 ticks → 343.75 kHz
011 => clock/64 => 3.91 kHz ~ 0.256 ms got 43 ticks → 167.97 kHz
100 => clock/256 => 977 Hz ~ 1.024 ms got 86 ticks → 83.98 kHz
101 => clock/1024 => 244 Hz ~ 4.096 ms got 155 ticks → 37.84 kHz

The is frequency I calculated using
freq [kHz] = ticks / gate time [ms]

For another test, I connected an LED to pin 8 and switched it every time the ISR is called to test whether I calculated the gate time correctly. This turned out to be true, so the counting part has to have a mistake.

What am I doing wrong here? Can someone give me help on how to use the counter correctly?
Thanks for reading so far & any help in advance.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.