Problem with timer2 and sleep mode

Hi!!! I'm having a problem using sleep mode and timer2 at the same time. I've tested timer2 and it works, and I've tested sleep mode using a blinking led and it works, is sleeping, but when I add the timer2 config:

MsTimer2::set(5000, flash); // 5s period MsTimer2::start();

the led is always blinking with a 1s period, so Is no sleeping (led fixed) I don't know what to do. Can anybody help me??

Thanks.

It may save some time (both your's and the folks who are willing to help) if you post the code.

  • Brian

You have reason. The code is easy, just 2 leds, the timer2 make blink the onboard led, and the loop a led on pin 9, so commenting the two lines of timer2 the led 9 is fixed, but with timer2 working the led 9 is blinking… I think the maximum time on timer2 delay is shorter and there’s several interrupts at one second, so interrupts make wake from sleep in the loop and led on pin 9 is blinking. Here is the code:

#include <avr/sleep.h>
#include <MsTimer2.h>

void flash() {
static boolean output = HIGH;

digitalWrite(13, output);
output = !output;

}

int led = 9;
int state = LOW;

void setup() {
pinMode(13, OUTPUT);
pinMode(9, OUTPUT);

MsTimer2::set(5000, flash); // 2s periodo hace la funcion “flash”
MsTimer2::start();

//Power Save Mode
SMCR=(0<<3)|(1<<2)|(1<<1)|(0<<0);
}

void loop() {
state = !state;
digitalWrite(led, state);
delay (500);
sleep_mode();
}

Some observations…

  1. You should use set_sleep_mode instead of modifying the SMCR register directly

  2. This…

// Power Save Mode
SMCR=(0<<3)|(1<<2)|(1<<1)|(0<<0);

…sets the mode to Standby. If I remember correctly, the only sleep mode where timers continue to run is Idle. Try Idle mode.

  • Brian

Thanks very much!!! I modified the programm as you told me, but is still working in the same way. I post the code:

#include <avr/sleep.h>
#include <MsTimer2.h>

void flash() {
static boolean output = HIGH;
digitalWrite(13, output);
output = !output;
}

int led = 9;
int state = LOW;

void setup() {
pinMode(13, OUTPUT);
pinMode(9, OUTPUT);

MsTimer2::set(5000, flash); // 2s periodo hace la funcion “flash”
MsTimer2::start();

set_sleep_mode(SLEEP_MODE_IDLE); // sleep mode is set here
sleep_enable();
}

void loop() {
state = !state;
digitalWrite(led, state);
delay (500);
sleep_mode();
}

Hi again. I’ve tried using the sleep sampes on the playground, but it doesn’t work:

#include <avr/sleep.h>
#include <MsTimer2.h>

void flash() {
static boolean output = HIGH;
digitalWrite(13, output);
output = !output;
}

int led = 9;
int state = LOW;

void setup() {
pinMode(13, OUTPUT);
pinMode(9, OUTPUT);

MsTimer2::set(5000, flash); // 2s periodo hace la funcion “flash”
MsTimer2::start();

}

void loop() {
state = !state;
digitalWrite(led, state);
delay (500);

set_sleep_mode(SLEEP_MODE_IDLE); // sleep mode is set here

sleep_enable(); // enables the sleep bit in the mcucr register
// so sleep is possible. just a safety pin

sleep_mode(); // here the device is actually put to sleep!!
// THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP

}

Try this…

  • Close the Arduino IDE
  • Locate and open MsTimer2.cpp
  • At line #99, add the following…
#else
  #error Put definitions for your processor / board here.

…including a few lines before and after, it should look like this…

    TCCR2 &= ~((1<<CS21) | (1<<CS20));
    prescaler = 256.0;
  }
#else
  #error Put definitions for your processor / board here.
#endif
      
  tcnt2 = 256 - (int)((float)F_CPU * 0.001 / prescaler);
      
  if (ms == 0)
  • Close and save MsTimer2.cpp
  • Locate and delete MsTimer2.o
  • Open the Arduino IDE
  • Load your Sketch
  • Compile

Any compiler errors?

  • Brian

Hi, I found and added the lines you told me:

TCCR2 &= ~((1<<CS21) | (1<<CS20));
prescaler = 256.0;
}
#else
#error Put definitions for your processor / board here.
#endif

tcnt2 = 256 - (int)((float)F_CPU * 0.001 / prescaler);

if (ms == 0)
msecs = 1;

There’s no errors at the compiling, and a new MsTimer2.o was created.
I don’t understand what is the meaning of this things, but I thank you your efforts.

Thanks and greetings!!!

I don't understand what is the meaning of this things, but I thank you your efforts

It's to eliminate one obvious potential problem. MsTimer2 is coded for a specific set of processors. If you are using a processor that isn't supported, the library still compiles, the Sketch still runs, but the MsTimer2 stuff does not work at all. The bit I had you add ensures you are using a supported processor.

We can now move on to the less obvious things...

  • Brian

Thank you for your answer. In always, now sleep is not working good using “set_sleep_mode(SLEEP_MODE_IDLE)”, I tested it using sleem mode and pushbutton interrupt and the fast blinking led in the loop is always blinking!!! I changed it to “set_sleep_mode(SLEEP_MODE_PWR_DOWN)” and now the loop led is sleeping till I press the pushbutton:

#include <avr/sleep.h>

int led = 13;
int interled = 9;
int button = 2;
int state = LOW;
int state2 = LOW;

void setup()
{
pinMode(led, OUTPUT);
pinMode(interled, OUTPUT);
pinMode(button, INPUT);
digitalWrite(button, HIGH); // turn on pullup resistors
attachInterrupt(0, temperatura, FALLING);
}

void loop()
{
state = !state;
digitalWrite(led, state);
delay (500);

set_sleep_mode(SLEEP_MODE_PWR_SAVE); // sleep mode is set here

sleep_enable(); // enables the sleep bit in the mcucr register
// so sleep is possible. just a safety pin

sleep_mode(); // here the device is actually put to sleep!!
// THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP
}

void temperatura()
{
state2 = !state2;
digitalWrite(interled, state2);
}

I think the problem you're having is...

SLEEP_MODE_PWR_DOWN This sleep mode essentially shuts off everything except the watchdog timer and very basic I/O. None of the timers (including Timer 2) runs in this mode. In addition, the timers are not automatically restarted when the processor wakes from this mode. So even if the processor wakes back up, Timer 2 will not be running.

SLEEP_MODE_IDLE In this mode the timers do continue running including the timer that drives millis / delay. The processor will only sleep a very short time before an interrupt from one of the timers wakes it back up.

I currently only have a Teensy for testing and MsTimer2 doesn't work with it. So, I won't be able to provide much more help. Hopefully, if this problem continues, someone else will be able to assist.

  • Brian

I'm pretty sure MsTimer2 isn't doing what you think it's doing. What it actually does is hard code timer 2 to overflow and interrupt at 1ms. It is these 1 ms interrupts that wake up sleep mode. MsTimer2 is just telling you when, for example, 1000 interrupts occur (for 1 second).

Thank you very much for your help, so I cant use arduino for build an battery operated device due to this problem with sleep mode and timer.

Thanks again and greetings!!