user-1: I would like to measure frequency with an Arduino 2560 board. The approach is to use a timer interrupt set to one second and pin interrupt to count interrupts in one second.
The problem I have is that I get the wrong frequency. On my frequency generator I set up a frequency of 1000 Hz in my program I get 1006 Hz instead of 1000 Hz.
What am I doing wrong?
Here is my program. In the stup method I have declared a timer. When the signal comes on pin 2, the counter is increased by 1. After one second passed the flag bData is raised. If the flag is true then I print out a frequency on serial port.
#include <SPI.h>
#include <Ethernet.h>
#include <Math.h>

byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 1, 177);
EthernetServer server(80);
const byte interruptPinTemp = 2;
const byte interruptPinSlanost = 3;
//konstante za SBE-3
const double g = 4.85442486e-003;
const double h = 6.77300393e-004;
const double i = 2.65502731e-005;
const double j = 2.06782794e-006;
const double f = 1000.0;
volatile int cnt = 0;
volatile int cnt1 = 0;
volatile double slanost = 0;
volatile double slanost1 = 0;
int timer1_counter;
boolean bData = false;
volatile int dvesek = 1;

void beriTemperatura() {
  cnt++;
}

void beriSlanost() {
  slanost++;
}

double calcTemp(double frekvenca) {
  double logRes = log(f / frekvenca);
  return 1.0 / (g + (h * logRes) + (i * pow(logRes, 2.0)) + (j * pow(logRes, 3.0))) - 273.15;
}

void setup() {
  Serial.begin(9600);       // inicializacija serijskega porta
  noInterrupts();           // disable all interrupts
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  pinMode(interruptPinTemp, INPUT_PULLUP);
  pinMode(interruptPinSlanost, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPinTemp), beriTemperatura, CHANGE);
  attachInterrupt(digitalPinToInterrupt(interruptPinSlanost), beriSlanost, CHANGE);
  TCCR1A = 0;
  TCCR1B = 0;
  timer1_counter = 34286;   // preload timer 65536-16MHz/256/2Hz
  TCNT1 = timer1_counter;   // preload timer
  TCCR1B |= (1 << CS12);    // 256 prescaler
  TIMSK1 |= (1 << TOIE1);   // enable timer overflow interrupt
  interrupts();
}

//Timer interrupt na 1 sekundo
ISR(TIMER1_OVF_vect) {
  // interrupt service routine
  TCNT1 = timer1_counter;   // preload timer
  cnt1 = cnt ;               // prepisemo vrednost v cnt1
  bData = true;             // postavimo flag
  cnt = 0;  // resetiramo counter
}

void loop() {
  // če je postavljen flag, da so podatki jih izpišemo ali naredimo karkoli drugega
  if (bData == true) {
    bData = false;
    Serial.println(calcTemp(cnt1), 3);
    Serial.println(cnt1);
  }
}

Here is the frequency from my generator:

And here is a frequency measured with my board:

What is wrong that I get 1006 Hz instead of 1000 Hz?
If I raise the frequency for example to 5 kHz then I get 5032 Hz in my program (32 Hz to0 much).
Thank you for any advice.

user30005: 
TCNT1 = timer1_counter;   // preload timer

When you load the offset (timer1_counter), there are some values in the timer1 prescaler (and potentially TCNT1 if the prescaler isn't sufficient large, or the input pulse train is fast). By assigning a value to TCNT1, you would have written over the values in the prescaler / TCNT1 -> read the datasheet on that.
The solution?

Optimal: use a timer with auto-reload function. a timer with output compare can be adopted here as well.
Increment the counter: TCNT1 += timer1_counter; // preload timer, if timer has a 1:1 prescaler.

Or to use the timer to count the pulse and another to provide the time base.

user7508: The Arduino Mega 2560 is clocked off a ceramic
resonator, which
should typically have about 0.5% frequency tolerance. Your readings are
off by 0.6%, which is slightly more than the typical resonator
tolerance. I would them assume there is something wrong with your code,
check dannyf's answer.
Now, if you want significantly better accuracy, I would argue than
relying on the Arduino's internal clock is not a good idea. Even if your
code is perfect you cannot expect good accuracy. You could have better
results if you calibrate that clock instead of just assuming it runs at
16 MHz. But even then, ceramic resonators are notorious for having
a very significant frequency drift. Or you may get an Arduino clocked
off a quartz crystal instead, as these are far more stable.

-1: <p>I would like to measure frequency with an Arduino 2560 board. The approach is to use a timer interrupt set to one second and pin interrupt to count interrupts in one second.</p>

<p>The problem I have is that I get the wrong frequency. On my frequency generator I set up a frequency of 1000 Hz in my program I get 1006 Hz instead of 1000 Hz.</p>

<p>What am I doing wrong?</p>

<p>Here is my program. In the stup method I have declared a timer. When the signal comes on pin 2, the counter is increased by 1. After one second passed the flag bData is raised. If the flag is true then I print out a frequency on serial port.</p>

<pre><code>#include &lt;SPI.h&gt;
#include &lt;Ethernet.h&gt;
#include &lt;Math.h&gt;

byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 1, 177);
EthernetServer server(80);
const byte interruptPinTemp = 2;
const byte interruptPinSlanost = 3;
//konstante za SBE-3
const double g = 4.85442486e-003;
const double h = 6.77300393e-004;
const double i = 2.65502731e-005;
const double j = 2.06782794e-006;
const double f = 1000.0;
volatile int cnt = 0;
volatile int cnt1 = 0;
volatile double slanost = 0;
volatile double slanost1 = 0;
int timer1_counter;
boolean bData = false;
volatile int dvesek = 1;

void beriTemperatura() {
  cnt++;
}

void beriSlanost() {
  slanost++;
}

double calcTemp(double frekvenca) {
  double logRes = log(f / frekvenca);
  return 1.0 / (g + (h * logRes) + (i * pow(logRes, 2.0)) + (j * pow(logRes, 3.0))) - 273.15;
}

void setup() {
  Serial.begin(9600);       // inicializacija serijskega porta
  noInterrupts();           // disable all interrupts
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  pinMode(interruptPinTemp, INPUT_PULLUP);
  pinMode(interruptPinSlanost, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPinTemp), beriTemperatura, CHANGE);
  attachInterrupt(digitalPinToInterrupt(interruptPinSlanost), beriSlanost, CHANGE);
  TCCR1A = 0;
  TCCR1B = 0;
  timer1_counter = 34286;   // preload timer 65536-16MHz/256/2Hz
  TCNT1 = timer1_counter;   // preload timer
  TCCR1B |= (1 &lt;&lt; CS12);    // 256 prescaler
  TIMSK1 |= (1 &lt;&lt; TOIE1);   // enable timer overflow interrupt
  interrupts();
}

//Timer interrupt na 1 sekundo
ISR(TIMER1_OVF_vect) {
  // interrupt service routine
  TCNT1 = timer1_counter;   // preload timer
  cnt1 = cnt ;               // prepisemo vrednost v cnt1
  bData = true;             // postavimo flag
  cnt = 0;  // resetiramo counter
}

void loop() {
  // če je postavljen flag, da so podatki jih izpišemo ali naredimo karkoli drugega
  if (bData == true) {
    bData = false;
    Serial.println(calcTemp(cnt1), 3);
    Serial.println(cnt1);
  }
}
</code></pre>

<p>Here is the frequency from my generator:</p>

<p><a href="https://i.stack.imgur.com/JHtkL.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/JHtkL.jpg" alt="enter image description here"></a></p>

<p>And here is a frequency measured with my board:</p>

<p><a href="https://i.stack.imgur.com/TsJLC.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/TsJLC.jpg" alt="enter image description here"></a></p>

<p>What is wrong that I get 1006 Hz instead of 1000 Hz?</p>

<p>If I raise the frequency for example to 5 kHz then I get 5032 Hz in my program (32 Hz to0 much).</p>

<p>Thank you for any advice.</p>
 30005: <blockquote>
  <p>TCNT1 = timer1_counter;   // preload timer</p>
</blockquote>

<p>When you load the offset (timer1_counter), there are some values in the timer1 prescaler (and potentially TCNT1 if the prescaler isn't sufficient large, or the input pulse train is fast). By assigning a value to TCNT1, you would have written over the values in the prescaler / TCNT1 -> read the datasheet on that.</p>

<p>The solution?</p>

<ol>
<li><p>Optimal: use a timer with auto-reload function. a timer with output compare can be adopted here as well.</p></li>
<li><p>Increment the counter: <code>TCNT1 += timer1_counter; // preload timer</code>, if timer has a 1:1 prescaler.</p></li>
</ol>

<p>Or to use the timer to count the pulse and another to provide the time base.</p>
 7508: <p>The Arduino Mega 2560 is clocked off a <a href="https://en.wikipedia.org/wiki/Ceramic_resonator" rel="nofollow noreferrer">ceramic
resonator</a>, which
should typically have about 0.5% frequency tolerance. Your readings are
off by 0.6%, which is slightly more than the typical resonator
tolerance. I would them assume there is something wrong with your code,
check dannyf's answer.</p>

<p>Now, if you want significantly better accuracy, I would argue than
relying on the Arduino's internal clock is not a good idea. Even if your
code is perfect you cannot expect good accuracy. You could have better
results if you calibrate that clock instead of just assuming it runs at
16&nbsp;MHz. But even then, ceramic resonators are notorious for having
a very significant frequency drift. Or you may get an Arduino clocked
off a quartz crystal instead, as these are far more stable.</p>
