system
January 23, 2014, 12:00pm
1
Hi guys,
i have a problem with my code.
#include <TimerOne.h>
unsigned int sec = 0;
unsigned int counter = 0;
void setup()
{
Serial.begin(9600);
Timer1.initialize(10);
Timer1.attachInterrupt(tick);
}
void tick()
{
if(counter++>100000){
counter = 0;
sec++;
}
}
void loop()
{
Serial.println(sec);
delay(1000);
}
The tick-function starts every 10µs and when the counter ist at 100000 one second has passed.
In my Serialmonitor the sec ist continously at 0. Why?
When I change the 100000 to 10000 the programm works and the seconds increase.
I can´t change the value in the Timer1.initialize(10) funktion because the Timer is need to create a PWM at 100kHz.
Could you please help me?
system
January 23, 2014, 12:06pm
2
tick() is an interrupt service routine. It diddles with sec.
loop() doesn't know that sec can be diddled with, so it caches the value, and never knows that it changes.
Add volatile to the definition of sec, so loop() knows that sec CAN be diddled with, and it won't cache the value.
westfw
January 23, 2014, 12:07pm
3
Counter needs to be a long. Int is only 16 bits on avr, which is always less than 100000.
It should also be "volatile"
system
January 23, 2014, 12:08pm
4
It should also be "volatile"
counter doesn't need to be volatile. It is accessed only in the ISR. sec does, though, since it IS accessed by the ISR and other code.
MarkT
January 23, 2014, 4:13pm
6
If counter is local to the ISR it could be declared in scope as static.
Anyway the counter as it stands is anti-useful, you could just write:
#include <TimerOne.h>
volatile unsigned int sec = 0;
void setup()
{
Serial.begin(9600);
Timer1.initialize(1000000L);
Timer1.attachInterrupt(tick);
}
void tick()
{
sec++;
}
void loop()
{
Serial.println(sec);
delay(1000);
}
Thereby reducing the burden of interrupt handling at a stroke by a factor of 100,000...