Your ISR is not counting the elapsed milliseconds. Instead, it just sets
a flag and lets the main program do the counting when it sees the flag.
Here:
while(digitalRead(PUSHBUTTON) == HIGH)
{
}
you are waiting for the user to press the button. The program does
nothing else during the wait. It doesn't event count the time. Here:
if (int_flag==1){
millisecs++;
int_flag=0;
}
you increment once the millisecond count after the wait.
The obvious solution is to count the milliseconds while waiting for the
button press:
millisecs = 0; // don't forget to reset the stopwatch!
while (digitalRead(PUSHBUTTON) == HIGH) { // button not pressed
if (int_flag) {
millisecs++;
int_flag = false;
}
}
(side note: int_flag
should be a bool
).
There are still many issues with this program. First of all, it should
check that the user did not press the button before the LED came up.
Then, the interrupt period is not one millisecond, because the interrupt
takes some time to be processed by the CPU and to go through its
prologue. By the time you do TCNT1=timer1_counter;
you are at least
several tens of cycles late. You should instead configure the timer to
keep the correct period by itself, typically using CTC mode.
Also, there is no point in letting the main program count the
milliseconds when the ISR could do it. E.g.
ISR(TIMER1_OVF_vect)
{
millisecs++;
}
// Avoid a race condition when reading millisecs.
static inline unsigned int getMillisecs()
{
noInterrupts();
int millisecsCopy = millisecs;
interrupts();
return millisecsCopy;
}
Note that the time keeping variables should be unsigned in order to
avoid undefined behaviour on overflows.
Finally, it may be a good learning experience for working with
interrupts, but in the end just using millis()
or micros()
would be
the easiest way to achieve what you want.