please help with sleep code not staying asleep

hi there,
im trying to have my bare bones arduino go into sleep and then woken up with an interrupt, sounds typical i know!

the following is sample code that is not working for me

#include <avr/sleep.h>

int wakePin = 2;
int changeThisPin = 1;

void setup() {
  pinMode(wakePin, INPUT);
  pinMode(changeThisPin, OUTPUT);
  digitalWrite(changeThisPin, HIGH);
}

void loop() {
  delay(3000);
  sleep();
}

void sleep()
{
  sleep_enable();
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  attachInterrupt(0, wakeUpNow, LOW);
  digitalWrite(changeThisPin,LOW);
  delay(2000);
  sleep_mode();
  sleep_disable();
  detachInterrupt(0);
  digitalWrite(changeThisPin,HIGH);
}


void wakeUpNow()
{
// wake up code here if needed
}

basically, pin 1 it set to high. then in loop i wait 3 seconds, then call sleep. there i am turning the pin to low, settings the sleep mode, attaching an interrupt to ping 2 (0 = pin 2 in interrupt params)), then i am waiting 2 seconds before actually putting the cpu to sleep.

at this point, what i am expecting is to not see pin1 go back to a high state until pin 2, the interrupt, is placed to ground. but this is not the case, what actually is happening is the code just simply continues right past the sleep mode and goes right back into loop.

i have a 4.7k resistor between pin 2 and the power rail on the bread board, which is being supplied 5v, so the pin is in a high state, the interrupt requires a low state to continue. my intention is to then have a button between pin 2 and ground to bring it to the low state, and waking the cpu back up.

i am using the following link for reference:
http://playground.arduino.cc/Learning/ArduinoSleepCode

any ideas on why the chip is not staying in sleep mode?

thanks

bare bones arduino

Did you make a custom board yourself? It may not be the programming, it might be hardware...

But looking at your code... This is cute,

I don't really see the loop sleep_enable should that be wakeUpNow();?

Lets debug this code, copy and paste what the serial monitor says when you upload this.

#include <avr/sleep.h>
int wakePin = 2;
int changeThisPin = 1;

void setup() {
Serial.begin(9600);
  pinMode(wakePin, INPUT);
  pinMode(changeThisPin, OUTPUT);
  digitalWrite(changeThisPin, HIGH);
Serial.println("Setup complete");
}

void loop() {
Serial.println(millis());
Serial.println("delay 3000");
  delay(3000);
Serial.println("end delay3000");
  sleep();
}

void sleep()
{ Serial.print("stage1 is ");
  Serial.println(millis());
  sleep_enable();
  Serial.print("stage2 is ");
  Serial.println(millis());
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  Serial.print("stage3 is ");
  Serial.println(millis());
  attachInterrupt(0, wakeUpNow, LOW);
  Serial.print("stage4 is ");
  Serial.println(millis());
  digitalWrite(changeThisPin,LOW);
  Serial.print("stage5 is ");
  Serial.println(millis());
  Serial.println("Delay2000");
  delay(2000);
  Serial.print("Delay2000 end ");
  Serial.println(millis());
  sleep_mode();
  Serial.print("stage6 is ");
  Serial.println(millis());
  sleep_disable();
  Serial.print("stage7 is ");
  Serial.println(millis());
  detachInterrupt(0);
  digitalWrite(changeThisPin,HIGH);
  Serial.print("stage8 is ");
  Serial.println(millis());
}

yes bare bones ardunio, based off the micro using atmega32u4.
i could have a mistake sure, but what would cause sleep not to stay asleep? the setup works with lots of other things, neopixels, sd card, TX/RX communication, USB, so im fairy confident in the hardware, unless you know something that could specifically cause sleep to not sustain via hardware besides the interrupt pin being hooked into ground.,
essentially i have the VCC's AVCC's VUSB connected to the power line, and all the GNDs connected to ground, 16mhz crystal osc with 22pf caps, and a 1uf cap between gnd and pin 6 based on atmega32u4 datasheet (not arduino pin 6), and now the usb to talk to serial as requested

can you clarify your question about loop sleep_enabled should be wakeUpNow?
it looks like in your code you took out the void wakeUpNow, it wouldnt compile, so i had to add it again

this is the serial output, it looks like it keeps looping?
you are calling sleep_mode after delay2000 end, time in millis is 6003, as you see stage 6 and 7 is at the same time, then after changing the pin to high it goes to 6004, so it looks like the code just continues

end delay3000
stage1 is 6002
stage2 is 6002
stage3 is 6003
stage4 is 6003
stage5 is 6003
Delay2000
Delay2000 end 6003
stage6 is 6003
stage7 is 6003
stage8 is 6004
6004
delay 3000
end delay3000
stage1 is 9005
stage2 is 9006
stage3 is 9006
stage4 is 9006
stage5 is 9006
Delay2000
Delay2000 end 9006
stage6 is 9006
stage7 is 9006
stage8 is 9007
9007
delay 3000
end delay3000
stage1 is 12007
stage2 is 12007
stage3 is 12008
stage4 is 12008
stage5 is 12008
Delay2000
Delay2000 end 12008
stage6 is 12008
stage7 is 12008
stage8 is 12009
12009
delay 3000
end delay3000
stage1 is 15009
stage2 is 15010
stage3 is 15010
stage4 is 15010
stage5 is 15010
Delay2000
Delay2000 end 15010
stage6 is 15010
stage7 is 15010
stage8 is 15011
15011
delay 3000
end delay3000
stage1 is 18013
stage2 is 18013
stage3 is 18013
stage4 is 18013
stage5 is 18013
Delay2000
Delay2000 end 18013
stage6 is 18013
stage7 is 18013
stage8 is 18014
18014
delay 3000
end delay3000
stage1 is 21014
stage2 is 21014
stage3 is 21015
stage4 is 21015
stage5 is 21015
Delay2000
Delay2000 end 21015
stage6 is 21015
stage7 is 21015
stage8 is 21016
21016
delay 3000
end delay3000
stage1 is 24017
stage2 is 24017
stage3 is 24017
stage4 is 24017
stage5 is 24017
Delay2000
Delay2000 end 24017
stage6 is 24017
stage7 is 24017
stage8 is 24018
24018
delay 3000

my multimeter shows pin 2 (interrupt 0, and pin 19 on atmega32u4 datasheet) being sustained at 5v, so should be high, therefor the code should not keep continuing correct?

i just built the code onto an actual arduino micro with a 4.7k resistor between 5v and pin 2 and im getting the same looping behavior.

See: Gammon Forum : Electronics : Microprocessors : Interrupts

Interrupt 0 is pin 18 on the TQFP package and D3 (digital output 3) on the Leonardo.

You have it as pin D2.

  attachInterrupt(0, wakeUpNow, LOW);

Personally I would use FALLING rather than LOW. The LOW interrupt keeps firing as long as the pin is low, conceivably slowing the code down considerably.

yes bare bones ardunio, based off the micro using atmega32u4.

Interesting, did you design it yourself? I have a prototype working, but I want to shrink it down and put the whole thing on an Eagle board. I am looking for someone who can help do that. Would that be something you are interested in? I have the schematics for all the parts I am using.

I am confused about the serial readout you provided.

stage4 is 6003
stage5 is 6003
Delay2000
Delay2000 end 6003

It is my understanding, that millis() should increase by at least one each time, and by 2000 between stage5, and Delay2000 end... Why is not?

What I suspect is happening here is the use of the LOW external interrupt. That has a higher priority than the Timer 0 interrupt. The LOW interrupt fires continuously (not just once) on a LOW signal, and thus overrides the timer interrupts (hence millis() does not increment). When you finally detach the interrupt the timer can increment again, so you find that the figures jump until the next time you attach the interrupt. When I used a FALLING interrupt I did not get the results you got. (However using LOW, I got similar results).

thank you this is some critical information! i tried to read this in the datasheet, i had a feeling i was on the wrong pin but i seemed to miss it. also FALLING is a great recommendation.

it looks like i can get the micro to sleep, then wake back up. but am having some issues still. after the micro goes to sleep once, i lose serial communication. i cant even upload new code unless i reset and upload before the first sleep.
when the serial is supposed to print again, im seeing the TX light stuck on.

any ideas on why this is happening?

below is my current testing code :

#include <avr/sleep.h>

int wakePin = 3;
int changeThisPin = 13;

void setup() {
  Serial.begin(9600);
  pinMode(wakePin, INPUT);
  pinMode(changeThisPin, OUTPUT);
  digitalWrite(changeThisPin, HIGH);
}

void loop() {
  digitalWrite(changeThisPin, LOW);
  delay(1000);
  digitalWrite(changeThisPin, HIGH);
  delay(1000);
  digitalWrite(changeThisPin, LOW);
  delay(1000);
  digitalWrite(changeThisPin, HIGH);
  delay(1000);
  digitalWrite(changeThisPin, LOW);
  delay(1000);
  digitalWrite(changeThisPin, HIGH);
  delay(1000);
  Serial.println("test");
  delay(1000);
  digitalWrite(changeThisPin, LOW);
  sleep();
}

void sleep()
{
  sleep_enable();
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  attachInterrupt(0, wakeUpNow, FALLING);
  sleep_mode();
  sleep_disable();
  detachInterrupt(0);
  digitalWrite(changeThisPin, HIGH);
}


void wakeUpNow()
{
  // wake up code here if needed
}

the code simply blinks the on board led a few times, then goes to sleep

my current setup has a 4.7k resistor between 5v and pin d3. to wake the arduino back up i tap together ground and pin 3.

after taping to ground, the led blinks again, then goes back to sleep, but Serial.println("test"); is not visible in the serial monitor,

My guess is -- and it is only a guess -- that going to sleep disrupts the USB interface. After all, if it is powered down you don't expect it to respond to the USB messages.

  Serial.begin(9600);

You are supposed to wait for Serial to become ready on the 32u4 chips, like this:

  Serial.begin(9600);
  while (!Serial) { }

You could try stopping Serial and restarting it, like this:

  Serial.flush ();
  Serial.end ();
  sleep ();
  Serial.begin(9600);
  while (!Serial) { }