Hey all.
In the project I'm currently working on, I want the backlight of an lcd display to turn off after a few seconds of idling.
I figured I could use the internal 16 bit timer as this has a maximum period of approximately eight seconds which would be perfect.
I'm using an Arduino Duemilanove and the TimerOne library. Backlight is controlled by a transistor on a pin named backlightpin.
The code I've got so far to implement the timer:
void setup(){
Timer1.initialize(8388480); //Start timer, period 8.3 seconds (is maximum)
Timer1.attachInterrupt(lcdOff); //Interrupt function to call every period
...
}
void lcdOff() //Interrupt for turning backlight off
{
digitalWrite(backlightpin, LOW);
Timer1.stop(); //Stop counting until timer starts again
}
void lcdOn()
{
digitalWrite(backlightpin, HIGH);
Timer1.start(); //Start counting again
}
Function lcdOn is called every time the rotary encoder I use for input moves. The idea is that when the lcdOn function is called, the backlight turns on, timer is set to zero and started. When the timer reaches 8 seconds it should fire the interrupt function and stop counting to prevent it from firing again in 8 seconds.
The problem is that the interrupt just won't call after I use the Timer1.start function. I suspected that the interrupt enable flag was being cleared in that function so I looked in the TimerOne source:
void TimerOne::start() // AR addition, renamed by Lex to reflect it's actual role
{
unsigned int tcnt1;
TIMSK1 &= ~_BV(TOIE1); // AR added
GTCCR |= _BV(PSRSYNC); // AR added - reset prescaler (NB: shared with all 16 bit timers);
oldSREG = SREG; // AR - save status register
cli(); // AR - Disable interrupts
TCNT1 = 0;
SREG = oldSREG; // AR - Restore status register
do { // Nothing -- wait until timer moved on from zero - otherwise get a phantom interrupt
oldSREG = SREG;
cli();
tcnt1 = TCNT1;
SREG = oldSREG;
} while (tcnt1==0);
// TIFR1 = 0xff; // AR - Clear interrupt flags
// TIMSK1 = _BV(TOIE1); // sets the timer overflow interrupt enable bit
}
Upon uncommenting the last line TIMSK1 = _BV(TOIE1), the program freezes at TimerOne.start.
TIMSK1 &= ~_BV(TOIE1) disables the interrupt, comment says it's to prevent a phantom interrupt call.
What also seemed odd to me is that Sei() isn't called, if I want to keep using the interrupt after the start function
I should globally re enable interrupts, right?
Has anyone got any clues on how to solve this?
TimerOne library: Arduino Playground - Timer1