How do I remove "jitter" when detecting frequency of Sine Wave Input: Sine wave of any frequency centred at 1.66V
Output: Square wave with a frequency equal to input
I have been working on implementing a common DSP problem -- Detect the frequency of a Sine Wave. I have used a handful of posts from stack exchange to get me started, and found This answer best suited for my problem. However, implementing the solution and measuring both the input signal (sine wave) and the output signal (square wave) with an oscilloscope, it appears I am getting some &quot;Jitter&quot; on my output signal.
Does anyone know what could be causing this? Or is this just... as accurate a detection I can get?


Here is the code I am using to detect the frequency of the sine wave:
volatile int period;             // equal to the number of samples taken between zero crossings
volatile float frequency;        // the calculated frequency of the sine wave
int numSamplesTaken = 0;         // used in frequency calculation formula

int currValue = 0;               // the current sampled value of sinewave input
int prevValue = 0;               // the previous sampled value of sinewave input

int zero_crossing = 32767;       // ADC range is 0v - 3.3v, so the midpoint of the sine wave should be 1.65v (ie. 65535 / 2 = 32767)
int threshold = 500;             // for handling hysteresis
int isPositive = false;          // whether the sine wave is rising or falling

// interupt occuring at 8000hz
void sampleSignal() {

  currValue = input.read_u16();   // convert analog voltage input (sine wave) to a 16 bit number
  

  if (currValue &gt;= (zero_crossing + threshold) &amp;&amp; prevValue &lt; (zero_crossing + threshold) &amp;&amp; isPositive) {

    output.write(0);               // write digital output pin LOW
    isPositive = false;

  } else if (currValue &lt;= (zero_crossing - threshold) &amp;&amp; prevValue &gt; (zero_crossing - threshold) &amp;&amp; !isPositive) {

    output.write(1);               // write digital output pin HIGH
    period = numSamplesTaken;      // how many samples have occurred between positive zero crossings
    frequency = 8000 / period;     // sample rate divided by period of input signal
    numSamplesTaken = 0;           // reset sample count
    isPositive = true;
  }
  
  prevValue = currValue;
  numSamplesTaken++;
}
Your interrupt seems to occur at 8 kHz. There are 2 obvious jitter causes that I can see.
First of all if $$\frac{f_s}{f} \neq N$$ where N is an integer, $f_s$ is the sampling frequency and $f$ the signal frequency, you will get jitter since the sampling instants will not be &quot;periodic&quot;. Try to set f to 80 Hz, you will have 100 samples per period, check if that fixes your jitter.
Secondly, there could be latency caused by your ADC (is it integrated to your microcontroller? SPI, I2C?), latency caused by the ISR, etc. that could cause the jitter.