TimerOne library: interrupt running at a higher frecuency

This is an intriguing issue I found yesterday.

I'm using Stoffregen's TimerOne library to schedule an interruption. The period is passed as unsigned long parameter to the "initialize" function (in microseconds).

If I define the period with a macro, like this:

#define PERIOD_IN_MILLIS 1000

void setup() {
  Timer1.initialize(PERIOD_IN_MILLIS * 1000);
  Timer1.attachInterrupt(myISR);
}

The interrupt should run each second, but instead is running at a much higher frecuency (almost constantly running).

However if i define the period as a magic number:

void setup() {
  Timer1.initialize(1000000);
  Timer1.attachInterrupt(myISR);
}

Then everything works as expected.

This is amazing. What kind of black magic is involved here?

The interrupt should run each second, but instead is running at a much higher frecuency (almost constantly running).

Why do you think that? What is 1000 * 1000? Keep in mind that 1000 is an int. So, the result of the multiplication will ALSO be an int.

You need to do this:

 Timer1.initialize(PERIOD_IN_MILLIS * 1000L);

PaulS:
Why do you think that? What is 1000 * 1000? Keep in mind that 1000 is an int. So, the result of the multiplication will ALSO be an int.

Now you mention it, with 1000*1000 there's this warning:

 warning: integer overflow in expression

But with the 1000000 magic number there are no warnings.

Why is this? Shouldn't 1000000 also be treated as int by the compiler unless I add the L suffix? This value is also greater than 32,767, which is int's max value in the Uno (16 bits).

Shouldn't 1000000 also be treated as int by the compiler unless I add the L suffix?

The compiler can see that that is not an int value. Adding the L suffix is a good idea, as it makes it obvious that YOU know that the value is a long.

Because the initialize function expects a long parameter.