ISR (TIMER1_OVF_vect) only starts running after 3-4 seconds

Hi all

building a very simple timer that only shows seconds 0-59 and restarts at 0. I choose to use Timer 1 overflow for more precision. Using delay() did not satisfy me.

The timing should startup immediately, but it doesn’t. At startup it displays 00, but it waits 3-4 seconds before proceeding.

Variables:

long preset = 49911; // ------------------------------65535 - (1 / (1024 / 16000000) -1)

Timer initialization:

void timer_init()
{

  TCNT1 = preset;                                // for 1 sec at 16 MHz
  TCCR1A = 0x00;
  TCCR1B = (1 << CS10) | (1 << CS12);            // Timer mode with 1024 prescaler
  TIMSK1 = (1 << TOIE1) ;                        // Enable timer1 overflow interrupt(TOIE1)
  sei();                                         // Enable global interrupts by setting global interrupt enable bit in SREG

}

The actual interrupt routine:

ISR (TIMER1_OVF_vect)    // Timer1 ISR
{

  TCNT1 = preset;
  sec++;
  if (sec > 59) {
    sec = 0;
  }


}

timer_init() is called from within setup, immediately followed by an instruction to display the timer.

void setup()
{

  Serial.begin(57600);
  Serial.println("timer gestart");
  mydisplay.shutdown(0, false);  // turns on display
  mydisplay.setIntensity(0, brt);

  timer_init();
  displayTeller(sec);    // routine to display the seconds, with Serial.print or with 2 digit-7-seg display
  prevSec = sec;
}

I am using a ‘barebones’ Atmega328 at 16MHz.

Running the sketch from an Arduino Uno with Serial.printing or running it from the AtMega328 with 7 segments display does not matter, the problem remains the same: at startup the sketch immediately displays the initial value of 00 and then waits 3-4 seconds to start counting up. It looks like the timer overflow needs more than 1 sec for the first cycle…?
Any ideas what I could do?

Thanks!

Jan

(edit after first comment)

Please note that I do not see any reason why the printing should make it hang.
This is a short version with Serial.print only:

long preset = 49911; // ------------------------------65535 - (1 / (1024 / 16000000) -1)

unsigned long startTijd;
unsigned int brt     = 15, // helderheid, max 15
             sec     =  0,
             prevSec     ;

ISR (TIMER1_OVF_vect)    // Timer1 ISR
{

  TCNT1 = preset;
  sec++;
  if (sec > 59) {
    sec = 0;
  }


}

void timer_init()
{

  TCNT1 = preset;                                // for 1 sec at 16 MHz
  TCCR1A = 0x00;
  TCCR1B = (1 << CS10) | (1 << CS12);            // Timer mode with 1024 prescaler
  TIMSK1 = (1 << TOIE1) ;                        // Enable timer1 overflow interrupt(TOIE1)
  sei();                                         // Enable global interrupts by setting global interrupt enable bit in SREG

}

void displayTeller(int v) {
  Serial.println(sec);
}

void setup()
{

  Serial.begin(57600);
  Serial.println("timer gestart");

  timer_init();
  displayTeller(sec);
  prevSec = sec;
}

void loop()
{

  if (prevSec != sec) {
    displayTeller(sec);
    prevSec = sec;
  }
}

…which still hangs for 3-4 seconds after printing the first 0.
I changed the variable type of preset to int, without any difference. BTW, I have used the same code in other sketches, with preset as a long, but those sketches only needed the ISR after a period of time. That is maybe why I never noticed the hanging.

Not enough information. Please post ALL the code, using code tags.
"preset" should be unsigned int, not long.

but it waits 3-4 seconds before proceeding.

Where in the code? Put in print statements to find out where it is hanging.

I don’t understand the actual reason for this, but in my testing when the setting of
TCNT was not the first timer instruction, the counter worked without delay.

void timer_init()
{

  //TCNT1 = preset;                                // for 1 sec at 16 MHz
  TCCR1A = 0x00;
  TCNT1 = preset; 
  TCCR1B = (1 << CS10) | (1 << CS12);            // Timer mode with 1024 prescaler
  TIMSK1 = (1 << TOIE1) ;                        // Enable timer1 overflow interrupt(TOIE1)
  sei();                                         // Enable global interrupts by setting global interrupt enable bit in SREG

}
unsigned int preset = 49911;
volatile byte sec = 0;
volatile boolean newData = true;

void setup() {
  Serial.begin(115200);
  Serial.println("timer gestart");
  Serial.print("before init() ");
  Serial.println(TCNT1);
  timer_init();
  Serial.print("after init() ");
  Serial.println(TCNT1);
}


void loop() {
  if (newData)
  {
    newData = false;
    Serial.print(sec);
    Serial.print('\t');
    Serial.println(millis());
  }
}

void timer_init()
{
  cli();
  TCNT1 = preset;                                // for 1 sec at 16 MHz
  Serial.println(TCNT1);
  TCCR1A = 0x00;
  TCNT1 = preset;
  Serial.println(TCNT1);
  TCCR1B = (1 << CS10) | (1 << CS12);            // Timer mode with 1024 prescaler
  TIMSK1 = (1 << TOIE1) ;                        // Enable timer1 overflow interrupt(TOIE1) 
  sei();
}

ISR (TIMER1_OVF_vect)    // Timer1 ISR
{
  TCNT1 = preset;
  sec++;
  newData = true;
  if (sec > 59) {
    sec = 0;
  }
}

Did an edit to my original post, with full code and more info.
TIA!

Tried Cattledog’s version, and it works perfectly! Great!

Looking into the sketch and trying out the changes, I found out that there is only 1 reason: the place of

TCNT1 = preset;

This is the right order:

void timer_init()
{

  cli();
  //TCNT1 = preset;                                // for 1 sec at 16 MHz
  Serial.println(TCNT1);
  TCCR1A = 0x00;
  TCNT1 = preset;
  Serial.println(TCNT1);
  TCCR1B = (1 << CS10) | (1 << CS12);            // Timer mode with 1024 prescaler
  TIMSK1 = (1 << TOIE1) ;                        // Enable timer1 overflow interrupt(TOIE1)
  sei();
}

I commented the first, it kept working. When uncommenting the first and commenting the second, it hung for a while. Guess the timer went to it’s maximum, returned to 0 and only then it was limited to preset?

Anyway, thank you, Cattledog!

Regards
Jan