Changing Global Variables From WIthin an ISR

Hi, I'm trying to change the value of a global variable from within the timer's ISR, and for the life of me I can't get it to stick.

The variable is declared: volatile int var;

Then in setup() I initialize it to 0: var = 0;

and in the ISR I increment it: var++;

It will increment it in the ISR, but it really seems like it's incrementing a local copy of the variable, because as soon as it returns from the timer's handler, the value returns to zero, so incrementing it this way simply makes it toggle between 0 and 1. If I increment it in the loop() function, the changes stay, but just not in the handler. Does anyone know why this is happening? Thanks!

It would help a lot to see the full source.

Be sure to post code using the [#] button :)

Well that's how I declare a variable in a optical encoder program I use that has a ISR to increment or decrement the global variable, and it works fine. Perhaps if you posted your code.


Awesome, thanks. I didn’t want to innundate y’all if this was a standard thing in the language. I’ve cut out some stuff trying to isolate the problem, so that’s why there are a might be a few random variables floating around that don’t really do anything… Also this is obviously not the final goal, but just distilled down to just the problem.

volatile unsigned int timeInDutyCycle;

void setup() {

  // Enable Timer/Counter 1 Overflow interrupt pg 139
  TIMSK1 |= (1<<TOIE1) | (1<< OCIE1A);
  // Setting the prescalar to 8 pg 137
  TCCR1B |= (1<<CS11);
  TCCR1B &= ~((1<<CS10) | (1 << CS12));
  // Normal operation (no funny buisness)
  TCCR1A = 0x00;
  timeInDutyCycle = 0;

void loop() {

ISR(TIMER1_OVF_vect) {

So I got it working, but I have no idea why it worked.

When I deactivated the Compare A interrupt, it just started working like a charm. I don't suppose anyone knows why this might happen? I didn't have a ISR for the compare A interrupt, so I wouldn't have thought it would reset it...

So I got it working, but I have no idea why it worked.

All interrupt vectors are by default assigned to a BADISR service routine and the default implementationn for this routine is to restart the application. So whenever the CompareA interrupt was triggered, your sketch would restart and never get beyond 0/1.

Awesome, thank you VERY much. That's good to know.