Micros timing and measurement of pulse

I have a simple sketch (below) running on a NANO to generate a square wave and measure its frequency.
I'm just wondering at the discrepancy between the values shown for the period of the generated wave ("period") and the measured period (tDiff).
08:30:17.778 -> : tFlashWait usec is 568: Period is usec 1136: tDiff is usec 1256
08:30:18.755 -> : tFlashWait usec is 568: Period is usec 1136: tDiff is usec 1256
08:30:19.775 -> : tFlashWait usec is 568: Period is usec 1136: tDiff is usec 1248
08:30:20.758 -> : tFlashWait usec is 568: Period is usec 1136: tDiff is usec 1256
I know 20us isnt long, and this isnt a "fast" processor.

Could the interrupt routine be interrupting the "flash" function? Or is the analogRead introducing the delay?

These wont be an issue in the final circuit as the pulse duration measurement will be done by a separate NANO.

/*
  Pulse generator micros timing: generate and time a square wave signal from D8 using a "rising" interrupt on D2
  pot from +5 to GND, slider to A7
  1k + LED from D7 to GND
  D8 to D2
  measure frequency on interrupt
*/

const int sensorPin = A7;     // select the input pin for the potentiometer
const int ledPin = 7;         // select the pin for the LED
const int outPin = 8;         //square wave signal out
const byte interruptPin = 2;  // detect pulses

volatile unsigned long tNow, tDiff, tPrev;           //measure period of incoming pulse in usec
unsigned long tPrint, tPrintOld, tPrintWait = 1000;  //only print once a second
unsigned long tFlash, tFlashOld, tFlashWait;         //generate pulses
boolean state;                                       //generate pulses

void freqP() {  //returns tDiff microseconds per output pulse
  tNow = micros();
  tDiff = tNow - tPrev;
  tPrev = tNow;
}

void flash() {  //toggle state of outputs: so period is 2 * "flash" time
  tFlash = micros();
  if ((tFlash - tFlashOld) > tFlashWait) {
    state = !state;
    digitalWrite(ledPin, state);
    digitalWrite(outPin, state);
    tFlashOld = tFlash;
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  pinMode(outPin, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(interruptPin), freqP, RISING);
  state = 0;
  //initialise "previous" values for timings
  tPrintOld = millis();
  tFlashOld = micros();
  tPrev = micros();
}

void loop() {

  // read the value from the sensor:
  int v = analogRead(sensorPin);
  int n = v;
  //prevent divide by zero and reduce range
  n += 5;  //new n value from 5 to 1028;

  tFlashWait = 102800 / n;  // tFlashWait value from 102800/1028 = 100 to 102800 / 10 = 1028 usec, 0.1 - 10.3 msec
  tFlashWait *= 2;          //make it so slowest flash is visible


  //TEST - fixed value for tFlashWait
  //tFlashWait = 562;  //a fixed value reduces the difference between 2* flashWait and tDiff

  //flash LED and generate signal
  flash();

  /*
  unsigned long freq = 1000000 / tDiff;  // 1 sec microseconds / tDiff microseconds gives freq in Hz
  int speed = (freq * sCal) / 600;       //sCal is
  analogWrite(speedoPin, speed);
  */

  //if its time to print
  tPrint = millis();
  if ((tPrint - tPrintOld) > tPrintWait) {
    //Serial.print("value from pot is ");
    //Serial.print(v);
    Serial.print(":  tFlashWait usec is  ");
    Serial.print(tFlashWait);
    Serial.print(":  Period is usec ");
    Serial.print(2 * tFlashWait);
    Serial.print(":  tDiff is usec ");
    Serial.print(tDiff);
    /*
    Serial.print(":  frequency is Hz ");
    Serial.print(freq);
    Serial.print(":  speed is ");
    Serial.print(speed);
    */
    Serial.println();
    tPrintOld = tPrint;
  }
}

A decent analysis of Arduino interrupts can be found >HERE<

I suspect most of the variation you’re seeing could be attributed to these factors.

Why use the slow analogRead and not the faster digitalRead?

I'm using an analog voltage from a pot to control the pulse rate.
I've seen here that an analog read takes 100usec

so that explains part of it anyway.

Okey. I see it now.

Hi @johnerrington ,

If you are interested in more accurate ways to produce and measure square waves you might use hardware timers.

There is a brilliant website that explains the use and provides examples

https://www.gammon.com.au/timers

Just another hint:

If you want to read or change variables in loop that are or may be changed in an interrupt you better use the ATOMIC_BLOCK macro.

For explanations read here

https://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html

It takes care that interrupts and loop don't interfere, e g. that parts of a variable are changed while loop tries to access the same value. This applies to data that a processor cannot read in one step.

Enjoy Arduino!
ec2021

P.S.:

This thread seems to have some similarities with yours and may be worth reading also...

https://forum.arduino.cc/t/calculating-periodic-time-using-micros-on-arduino-nano/1336853