Calculating time between two rising of pulse -is it my code correct?

Hi! Having carried out the investigation with the ready-made programs for measuring the pulse time, I decided to write my program for measuring the meander from 20 to 10000 Hz. I'm not sure that everything was written correctly. But the program works. Although there are some jumps in the lower digit. The program measures the time between two edges of the input pulses at the INT0 Arduino Nano input. I ask experienced to check my code. Especially the part of the code that works with the timer.

volatile boolean first = true;
volatile boolean dataForCopy = true;
volatile unsigned int Time;
volatile unsigned int timerCounts;
unsigned int timerCountsForLoop = 0;

void setup()
{
  Serial.begin(1200);
  attachInterrupt(0, isr, RISING);
}

void loop()
{
  if (dataForCopy == false)  //if isr was coping data from timer1
  {
    timerCountsForLoop = timerCounts;
    dataForCopy = true;   //loop() was take data and ready for new one from isr
  }
  Serial.print ("T=");  Serial.println (timerCountsForLoop);
  delayMicroseconds (5000);
}
void isr ()
{
  if (first == true)
  {
    first = false;  //reset trigger for copy Timer1 Counter in next rising of pulse
    TCCR1A = 0;     //reset Timer1 Control Register
    TCCR1B = 0;     //reset Timer1 Control Register
    TIMSK1 = bit (TOIE1);   // enable Timer1 Interrupt overflow
    TCNT1 = 0;      //reset Timer1 Counter
    TCCR1B =  bit (CS11);  //set clk/8 prescaling, start Timer1
  }
  else
  {
    Time = TCNT1;  //copy Timer1 Counter
    first = true;  //set trigger for reset Timer1 Counter in next rising of pulse
  }

  //for send "atomic" data from isr to loop
  if (dataForCopy == true)   //if loop() was send data out and ready for take new one from isr
  {
    timerCounts = Time;     //copy data from timer to loop()
    dataForCopy = false;
  }
}  // end of isr

// timer overflows (every 65536 counts), will reset timer on next front
ISR (TIMER1_OVF_vect)
{
  first = true; //set trigger for reset/start Timer1 Counter;
}  // end of TIMER1_OVF_vect

Thanks!

Gennady

I would move as much code as possible out of the ISR but the only real mistake I see is no turning off interrupts while copying a multi-byte variable that is set by the ISR (timerCounts). The problem is that the ISR could change the value between the time the first byte is fetched and the time the second byte is fetched.

Rather than resetting the timer on overflow you could keep a counter of overflows to extend the timer to 32 or even 48 bits. Then you could set the prescale to 1 and get 8 times the timer resolution.

In electronics and timings, a pulse is defined as the occurrence of one of the following events: 1. Active Low : _ //this is good enough; but, sample and hold time must be valid 2. Rising Edge __| // this is good enough 3. Active High - //this is good enough 4. Falling Edge -| //this is good enough

When we say pulse width; we mean that the pulse contains some energy, and it must be bounded by Rising Edge and Falling Edge.

When you say Calculating time between two rising of pulse - , does it mean that the pulse is bounded by two rising edges? If so, by definition it is not a pulse; it is a 'cycle'.

Do you want to compute period of a cycle? OR Do you want to compute the width of a pulse?

What is the expected width of your pulse? If your pulse width is within 10us to 3 min, you can use pulseIn() function. (See here)

GolamMostafa: Do you want to compute the width of a pulse?

What is the expected width of your pulse? If your pulse width is within 10us to 3 min, you can use pulseIn() function. (See here)

Yes, width of a pulse. I hope take error not more 0,5us =1/2000000Hz Thank you!

johnwasser: I would move as much code as possible out of the ISR but the only real mistake I see is no turning off interrupts while copying a multi-byte variable that is set by the ISR (timerCounts). The problem is that the ISR could change the value between the time the first byte is fetched and the time the second byte is fetched.

Rather than resetting the timer on overflow you could keep a counter of overflows to extend the timer to 32 or even 48 bits. Then you could set the prescale to 1 and get 8 times the timer resolution.

To preserve the integrity of the data, I use the dataForCopy trigger, which is reset to Loop () after saving the variable timerCounts as a timerCountsForLoop variable. Then in the ISR the trigger dataForCopy is again set after saving the value of Timer1 as the timerCounts variable. So I use the timerCounts variable to exchange data between the ISR and Loop ().I hope this will work with out stop interrupts.

As for the prescale to 1 setting, in this case, about eight ISRs (TIMER1_OVF_vect) will occur at the maximum pulse period (approximately 60,000 for prescale =CLK/8), the processing of which will introduce an additional error.

Please clarify whether I wrote the procedure for programming and resetting the timer correctly? Thank you!