Timer 2 - Clear counter without adding delay to the count

Hi all,

I need to set timer 2 in such a way that it can generate an overflow if no pulse has been detected.

Generally speaking what I do is clear TCNT2 when a pulse is detected, so that it never overflows as long as a signal with a valid period is present.

Now the issue I am facing is that i need to keep the counter synchronous to the clock frequency and some clock cycles are lost while reseting TCNT2.

Any suggestions on how to avoid this?

casemod:
Now the issue I am facing is that i need to keep the counter synchronous to the clock frequency and some clock cycles are lost while reseting TCNT2.

Which clock? The MCU system clock? The pulse that's being detected? I don't understand this requirement, the first two sentences seem a good solution to the problem.

The timer clock is the CPU frequency/256

Whenever I clear TCNT2 I loose about 24 clock cycles for the interrupt to be executed and the counter cleared and this is causing issues with my program at high frequencies. Basically i need an overflow interrupt only if no pulse is detected within the counter count range, so that i can increment a variable in software and say

total time = ([timer 2 value] + (number of overflows*65536))

Post your code. It will be more clear what you are doing if we have something concrete to read.

CTC (Clear Timer on Compare Match) mode sounds like what you are looking for. Look for that in the datasheet.

What is the nature of the pulse? What is its frequency or period? Does it vary? Within what range? How is "pulse not detected" defined, when a certain amount of time elapses? How much time?

By definition the timer is synchronous with the system clock. What we have is a phase delay, caused by the processing needed to handle the interrupt. However, this should be perfectly determinate, so perhaps the problem is not one of synchronicity but rather the time lag is the issue?

It is indeed.

But Think about this:
An event is generated on an external pin, so an interrupt is called. By the time the interrupt saves TCNT2 and clears it a few clock cycles have passed and this time is lost as the timer restarts from 0.

Sure this could be avoid with input capture, but only timer one has this feature and it is already being used.

casemod:

[quote author=Jack Christensen link=topic=260135.msg1836809#msg1836809 date=1407629703]
By definition the timer is synchronous with the system clock. What we have is a phase delay, caused by the processing needed to handle the interrupt. However, this should be perfectly determinate, so perhaps the problem is not one of synchronicity but rather the time lag is the issue?

It is indeed.

But Think about this:
An event is generated on an external pin, so an interrupt is called. By the time the interrupt saves TCNT2 and clears it a few clock cycles have passed and this time is lost as the timer restarts from 0.

Sure this could be avoid with input capture, but only timer one has this feature and it is already being used.
[/quote]

Indeed, but without some answers to the questions I asked as to the requirements, we're at a bit of a loss.

pepe:
Hi

Basically, you don't have to reset TCNT2. You can let it run freely all the time, and just increment a software counter when an overflow occurs.

In return, the time between two events (pulses ?) has to be calculated in a different manner, that is something like that :

total time = 65536*( (counter value) - (starting counter value) ) + (TCNT2 value) - (starting TCNT2 value)

Depending on how interrupts are managed, an additional adjustment may be required when one or both of these TCNT2 values are too low, meaning the Timer 2 interrupt has not incremented the counter yet.

That describes my problem perfectly. Let me explain:

I set up a counter. if no event occurs I have an overflow. therefore i know that

total time = ([timer 2 value] + (number of overflows*65536))

But check out what happens when the event does happen:

I save the old time and deduct it from the current time, giving me a correct reading. Meanwhile, timer 2 is free running and it will overflow at some point. When this happens the software gives me the following reading:

total time = ((timer2_value - timer2_old_value) + (number of overflows*65536))

And the result is 65536+the actual time that was measured.

So my output will be something like this

2048
2048
2048
2048
2048
67584
2048
2048
2048
2048
2048
67584
....

Take this example using timer 1

/* 
  * InputCapture 
  * uses timer hardware to measure pulses on pin 8 on Mega328 
  */ 

 const int inputCapturePin = 8;     // input pin fixed to internal Timer 
 
 volatile unsigned int r; 
 volatile unsigned int results; 
 //volatile unsigned int previous = 0;
 volatile unsigned int old_results = 0;
 volatile int i=0;    // Timer 1 overflow counter 
 volatile int a=0;
 volatile int temp=0;
 unsigned int PulseCount=0;
 #include <SPI.h> 

 void setup() 
 
 { 
   Serial.begin((16/4.194304)*9600);// 9600bps at 4.194304MHz
   TIMSK0 &= ~_BV(TOIE0);           // disable timer0 overflow interrupt 
   pinMode(inputCapturePin, INPUT); // ICP pin (digital pin 8 on Arduino) as input 
   TCCR1B = (1<<CS10);              // Set timer 1 Clock source = FOsc
   TCCR1A = 0 ;                     // Normal counting mode 
   //TIMSK1 |= _BV(TOIE1);            // enable timer 1 overflow flag 
   TIMSK1 |= _BV(ICIE1);            // enable input capture interrupt for timer 1
   
  pinMode (10, OUTPUT);
  PORTB |= _BV(2);                  //Turn Shift register CS PIN high
  SPI.begin();
 } 

 //Print timer 1 total counts since last pulse 
 void loop() 
 { 
   
  //Disable interrupts to make sure global variables stay static during local copy
  cli ();
  unsigned int PulseCount =r; 
  unsigned int temp1=temp;
  unsigned int temp2=results;
  //unsigned int oresult=old_results;
  //unsigned int p=previous;
  //int oflow=a;
  sei(); //Re-enable the interrupts
   
  //Check the overflow flag and use it to calculate the actual frequency output
  
    
  
   //Debug only! Data to be transfered via SPI to the modulator. Add routine here.
   //Serial.println(output); // print the value to be sent to the modulator
   Serial.print(temp2); // print the value to be sent to the modulator
   Serial.print("  ");
   Serial.print(a);
   Serial.print("  ");
   Serial.println(temp1);
   
   PORTB &= ~_BV(2);                      //Turn Shift register CS PIN LOW); // connects to RCLK
   SPI.transfer (highByte (PulseCount));  // send out upper 8 bits MSB first 
   SPI.transfer (lowByte (PulseCount));   // send out lower 8 bits
   PORTB |= _BV(2);                       //Turn Shift register CS PIN high - data output changes on this rising edge
 } 

 //**********Interrupts************************************************************ 

  //ICR interrupt vector 
 ISR(TIMER1_CAPT_vect) 
   { 
     //TCNT1 = 0; 
     a=i;                               //Save the Value of i into a variable a, so that calculations can be made outside the ISR  
     i=0;                               //Clear the overflow variable
   
   //Assign the value of the ICR1 Register to the variable results
   //Add 24 clock cycles that are lost waiting for the interrupt to clear the TCNT1 register
     //results = (ICR1+24);      
     old_results = results;
     results = ICR1;     
     
     
  /*if (a<1)
    {
    r = (4194304/((results-old_results)-(65536*a)));
    }
  else */
    {
    r = (4194304/((results-old_results)+(65536*a)));
    temp=(results-old_results);
    }
    
   } 

    //Overflow interrupt vector 
   ISR(TIMER1_OVF_vect) 
   {    
     i++;    //Increment timer 1 overflow counter 
   }

I could not sort the issue, so I disabled the overflow and was trying to make an overflow counter using timer 2, but came to the same problem. Check the previous post with a description of the problem

Sorry, just not seeing the big picture here.

Timer2 is 8 bits, yes? Wouldn’t the overflow multiplier therefore be 256, instead of 65536?

The intent is to overflow every 65536 clock cycles.

The example posted was for timer 1 with no prescaller.
If it were to timer 2 it would overflow at 255, but I would use a 256 prescaller, so it would overflow after 65536 clock cycles.

pepe:
Given the formula, the prescaler has nothing to do with that. The counter value has to be multiplied by 256 when using Timer 2, and by 65536 when using Timer 1.

No the counter value is always multiplied by 65536 as that is the period I wish to have.
However prescaller for timer 2 is 256 (256*256 = 65536, so an overflow happens here) and not 1024 as I mistakingly said earlier.

pepe:
Given the formula, the prescaler has nothing to do with that. The counter value has to be multiplied by 256 when using Timer 2, and by 65536 when using Timer 1.

Yes.

casemod:
Hi all,

I need to set timer 2 in such a way that it can generate an overflow if no pulse has been detected.

Generally speaking what I do is clear TCNT2 when a pulse is detected, so that it never overflows as long as a signal with a valid period is present.

Now the issue I am facing is that i need to keep the counter synchronous to the clock frequency and some clock cycles are lost while reseting TCNT2.

Any suggestions on how to avoid this?

Forget timers, forget clocks, just explain what you actually want to achieve at
a high level - there may be better ways to achieve what you want.

MarkT:
Forget timers, forget clocks, just explain what you actually want to achieve at
a high level - there may be better ways to achieve what you want.

Repply #9 has a detailed explanation regarding the problem

casemod:

MarkT:
Forget timers, forget clocks, just explain what you actually want to achieve at
a high level - there may be better ways to achieve what you want.

Reply #9 has a detailed explanation regarding the problem

Reply #9 has somewhat of an explanation of the current solution, which evidently leaves something to be desired. Explain the original goal, not the problem with the current implementation. In fact, leave details of the current implementation out completely.

The original goal is to measure a frequency ranging from 1 to 2048Hz in steps of 1Hz.

In order to achieve such precision the minimum sampling period must be 2048 cycles, therefore as time between each consecutive pulse doubles I need to count a total of 2048^2 = 4194304 pulses per second.

casemod:
The original goal is to measure a frequency ranging from 1 to 2048Hz in steps of 1Hz.

In order to achieve such precision the minimum sampling period must be 2048 cycles, therefore as time between each consecutive pulse doubles I need to count a total of 2048^2 = 4194304 pulses per second.

Excellent, that is the problem statement that we were looking for. I would not have guessed that to be the goal from all the conversation thus far.

There are several frequency counter sketches around, I assume you've looked into them?

[quote author=Jack Christensen link=topic=260135.msg1837280#msg1837280 date=1407678957]

casemod:
The original goal is to measure a frequency ranging from 1 to 2048Hz in steps of 1Hz.

In order to achieve such precision the minimum sampling period must be 2048 cycles, therefore as time between each consecutive pulse doubles I need to count a total of 2048^2 = 4194304 pulses per second.

Excellent, that is the problem statement that we were looking for. I would not have guessed that to be the goal from all the conversation thus far.[/quote]

Each time I describe my application i have people giving pointless solutions and or arguments in things I don't really see as relevant. So I find it quite pointless to describe the whole application. In fact I did before and have obtained no answers, people ask me to use mili functions or Google for frequency libraries or that I don't need that much resolution.

Don't take the above as being direct to you, Jack. I just want to make a point in which I appreciate the help and if I chosen a certain method it is because I did my research and found it to be the best for my particular application. I am trying to find help for my particular issue, hence being posted in the programming section and not in the project guidance section.

Do you know anything about the output compare module? I was thinking in setting it up to to schedule a future interrupt in case a pulse wasn't received within the counting range of the counter, but I am having trouble doing so.