I am powering down my arduino with SLEEP_MODE_PWR_DOWN and it randomly wakes and starts back at the setup loop. Any ideas on where to start? I hooked up a multimeter to the Vin pin to see if there were any random spikes but it didn't drop below 3.3v.
It wakes up from sleep with external interrupts.
Do you have the interrupts pulled high with the internal pullups, and have interrupt 0 or 1 attached and set to trigger low?
Here's all the pieces I found I needed, in IDE -0023 anyway. Have not tried it in 1.0 or 1.0.1
#include <avr/sleep.h> // powerdown library
#include <avr/interrupt.h> // interrupts library
int pin2 = 2; // Int0 interrupt pin
byte sleep_flag;
//***************************************************
// * Name: pin2Interrupt, "ISR" to run when interrupted in Sleep Mode
void pin2Interrupt()
{
/* This brings us back from sleep. */
}
//***************************************************
// * Name: enterSleep
void enterSleep()
{
/* Setup pin2 as an interrupt and attach handler. */
attachInterrupt(0, pin2Interrupt, LOW);
delay(50); // need this?
/* the sleep modes
SLEEP_MODE_IDLE - the least power savings
SLEEP_MODE_ADC
SLEEP_MODE_PWR_SAVE
SLEEP_MODE_STANDBY
SLEEP_MODE_PWR_DOWN - the most power savings
*/
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // setting up for sleep ...
sleep_enable(); // setting up for sleep ...
// Disable ADC
ADCSRA &= ~(1 << ADEN);
// Power down functions
PRR = 0xFF;
sleep_mode(); // now goes to Sleep and waits for the interrupt
/* The program will continue from here after the interrupt. */
detachInterrupt(0); //disable interrupts
// Power up functions
PRR = 0x00;
/* First thing to do is disable sleep. */
sleep_disable();
// then go to the void Loop()
}
// ***********************************************************************
// set up the pins as Inputs, Outputs, etc.
void setup()
{
/* Setup the pin directions, write inputs High to turn on internal pullups */
pinMode(pin2, INPUT); // our sleep interrupt pin
digitalWrite(pin2, HIGH);
} // end of void Setup()
// ***********************************************************************
// Main loop for reading the keypad and sending the button pushed out
// (with a unique address to be added eventually by reading 0-F from currently unused pins)
void loop()
{
// your code here to decide to go to sleep, lets say it sets a flag
if (sleep_flag == 1){
// Serial.println("Sleep"); // for debug only
enterSleep(); // call Sleep function to put us out
// THE PROGRAM CONTINUEs FROM HERE after waking up in enterSleep()
} // end of checking to go to sleep
} // end of void loop
Read this before posting a programming question
You would need to post your code and describe your wiring. Quite a few things will wake it up. Plus I doubt a multimeter would react quickly enough to show a voltage spike of a few microseconds.
CrossRoads:
It wakes up from sleep with external interrupts.
Do you have the interrupts pulled high with the internal pullups, and have interrupt 0 or 1 attached and set to trigger low?Here's all the pieces I found I needed, in IDE -0023 anyway. Have not tried it in 1.0 or 1.0.1
#include <avr/sleep.h> // powerdown library
#include <avr/interrupt.h> // interrupts library
int pin2 = 2; // Int0 interrupt pin
byte sleep_flag;
//***************************************************
// * Name: pin2Interrupt, "ISR" to run when interrupted in Sleep Mode
void pin2Interrupt()
{
/* This brings us back from sleep. */
}
//***************************************************
// * Name: enterSleep
void enterSleep()
{
/* Setup pin2 as an interrupt and attach handler. /
attachInterrupt(0, pin2Interrupt, LOW);
delay(50); // need this?
/ the sleep modes
SLEEP_MODE_IDLE - the least power savings
SLEEP_MODE_ADC
SLEEP_MODE_PWR_SAVE
SLEEP_MODE_STANDBY
SLEEP_MODE_PWR_DOWN - the most power savings
*/
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // setting up for sleep ...
sleep_enable(); // setting up for sleep ...
// Disable ADC
ADCSRA &= ~(1 << ADEN);
// Power down functions
PRR = 0xFF;
sleep_mode(); // now goes to Sleep and waits for the interrupt
/* The program will continue from here after the interrupt. */
detachInterrupt(0); //disable interrupts
// Power up functions
PRR = 0x00;
/* First thing to do is disable sleep. */
sleep_disable();
// then go to the void Loop()
}
// ***********************************************************************
// set up the pins as Inputs, Outputs, etc.
void setup()
{
/* Setup the pin directions, write inputs High to turn on internal pullups */
pinMode(pin2, INPUT); // our sleep interrupt pin
digitalWrite(pin2, HIGH);
} // end of void Setup()
// ***********************************************************************
// Main loop for reading the keypad and sending the button pushed out
// (with a unique address to be added eventually by reading 0-F from currently unused pins)
void loop()
{
// your code here to decide to go to sleep, lets say it sets a flag
if (sleep_flag == 1){
// Serial.println("Sleep"); // for debug only
enterSleep(); // call Sleep function to put us out
// THE PROGRAM CONTINUEs FROM HERE after waking up in enterSleep()
} // end of checking to go to sleep
} // end of void loop
Thanks for the input, it looks like this did it
// Disable ADC
ADCSRA &= ~(1 << ADEN);
// Power down functions
PRR = 0xFF;
This line was not in there but it needs to be turned back on also when it wakes.
ADCSRA |= (1 << ADEN);
I wasn't using ADC, so that didn't impact me. Will add it to my sleep code notes.
The issue has come back. I have disabled the reset fuse which has shown to clear up the issue. So I wonder if I can conclude that it is noise on the reset line.
The ATmega48PA/88PA/168PA/328P has four sources of reset:
• Power-on Reset. The MCU is reset when the supply voltage is below the Power-on Reset
threshold (VPOT).
• External Reset. The MCU is reset when a low level is present on the RESET pin for longer than
the minimum pulse length.
• Watchdog System Reset. The MCU is reset when the Watchdog Timer period expires and the
Watchdog System Reset mode is enabled.
• Brown-out Reset. The MCU is reset when the supply voltage VCC is below the Brown-out Reset
threshold (VBOT) and the Brown-out Detector is enabled.
#include <avr/sleep.h>
#include <avr/interrupt.h>
int counter;
void setup(void)
{
Serial.begin(9600);
Serial.println("Started");
counter = 0;
pinMode(2, INPUT); // our sleep interrupt pin
digitalWrite(2, HIGH);
}
void loop(void)
{
counter++;
Serial.println(counter);
GoToSleep();
}
void wakeUpNow()
{
}
void GoToSleep() // here we put the arduino to sleep
{
Serial.println("Sleeping");
Serial.println();
Serial.println();
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
sleep_enable(); // enables the sleep bit in the mcucr register
// so sleep is possible. just a safety pin
attachInterrupt(0,wakeUpNow,RISING);// Use pin 2 to wake up
delay(500);
sleep_mode(); // here the device is actually put to sleep!!
// THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP
sleep_disable(); // first thing after waking from sleep: disable sleep...
detachInterrupt(0); // disables interrupt 0 on pin 2 so the wakeUpNow code will not be executed during normal running time.
}
fnsnoop:
I am powering down my arduino with SLEEP_MODE_PWR_DOWN and it randomly wakes and starts back at the setup loop.
How frequently? Every millisecond? Minute? Hour?
Do you have a 10K pullup on the reset line?
It happens about 40 seconds after sleep. I do have a 10k resistor in between reset and Vcc. I have just ordered a picoscope to get some info on what is happening on this. But disabling reset did do the trick. Looking at this diagram below, it appears that the reset had to have been coming from that line. Please let me know if my think makes sense here.