Sparkfun Arduino Pro Micro 3.3V and SLEEP_MODE_PWR_DOWN

I am trying to work with the sleep mode pwr down example that is listed at

http://playground.arduino.cc/Learning/A … lock&num=5

with an Arduino Pro Micro. 3.3V that is hooked up via a USB cable. I plan to switch to a battery when the code is finalized… The sketch compiles up without any problems but the minute the sketch completes download, the Pro Micro turns into a usb device not recognized. At that point I have to monkey with it to get a simple sketch to download so that I can start using it again.

I have a ball switch hooked up between pin 2 and GRN which should give me the low transition to power the arduino back up

I am probably just missing something obvious but I can’t seem to figure it out.

Appreciate any guidance

Sounds like a short circuit somewhere. Does the “blink” sketch work?

Unless you have a resistor from Vcc to pin 2 (10K would be OK), or the internal pullup activated, the input would be floating and the switch would have an unpredictable effect.

Did you follow these instructions in the code? Again, 10K is OK.

 * use a resistor between RX and pin2. By default RX is pulled up to 5V
 * therefore, we can use a sequence of Serial data forcing RX to 0, what
 * will make pin2 go LOW activating INT0 external interrupt, bringing
 * the MCU back to life

I simplified the sketch and the problem seem to be with the attachinterupt in the setup function. WakeNow is just an empty function.

In the sample below, The code never gets to the Serial.println(“Test”) before the Pro Micro disconnnects

void setup()

{

pinMode(wakePin, INPUT_PULLUP);

Serial.begin(9600);

delay(10000);

Serial.println(digitalRead(wakePin));

attachInterrupt(0, wakeUpNow, LOW); // use interrupt 0 (pin 2) and run function

// wakeUpNow when pin 2 gets LOW

Serial.println(“Test”);

}

If you hold pin 3 to ground then interrupt 0 is being continuously triggered and the empty wakeUpNow function is being continuously run and rerun. You’'ll never get to the print function. The pin-to-interrupt number mapping is different for a 32U4 (ProMicro, Leonardo) powered system than it is for a 328p (Uno) based one. See the mapping here.

http://arduino.cc/en/Reference/AttachInterrupt

Thanks you. I had just started looking at that as a possibility (but just a stab in the dark on my part ) but had not got to the point where I really knew what I was doing. Appreicate the kickstart,

It seems that on the Pro Micro, Interrupt 0 is on Pin3. With that, the sketch seems to put the Pro Micro to sleep successfully. Unfortunately I can’t seem to wake it up. At this point, I am just shorting pin 3 to ground to try to wake it up. I must still be missing something obvious (although not to me)

#include <avr/sleep.h>
int wakePin = 3;                 // pin used for waking up
int sleepStatus = 0;             // variable to store a request for sleep
int count = 0;                   // counter

void wakeUpNow()        // here the interrupt is handled after wakeup
{
  // At this point do nothing
}

void setup()
{
  pinMode(wakePin, INPUT_PULLUP);
  Serial.begin(9600);
  delay(10000);
  Serial.println("Immediately before attachInterupt");
  attachInterrupt(0, wakeUpNow, LOW); 
  Serial.println("Immediately after attachInterupt");
}

void sleepNow()         // here we put the arduino to sleep
{
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    sleep_enable(); 
    attachInterrupt(0,wakeUpNow, LOW);
    sleep_mode();
    sleep_disable(); 
    detachInterrupt(0); 
}

void loop()
{
  Serial.print("Awake for ");
  Serial.print(count);
  Serial.println("sec");
  count++;
  delay(1000);  
  if (count >= 10) {
      Serial.println("Timer: Entering Sleep mode");
      delay(100); 
      count = 0;
      sleepNow(); 
  }
}

The code you’re using appears to have been sourced from the example code here …http://playground.arduino.cc/Learning/arduinoSleepCode

Did you notice this ?

Note to the author #2: The attachInterrupt function is being called in the setup routine (line 68) and the sleepNow function (line 118). From the comments in the sleepNow function, I suspect that the call in the setup routine should be removed.

Not sure if that is your problem, but it might be worth a quick try.

No I did not notice that. Will check it out tomorrow evening.

So removed the attach interrupt statement from setup but get the same behavior. Goes to sleep as last text is immediately before the call to SleepNow. Unfortunately I can’t get it to wait up

I haven’t read all the sleep modes in the 32U4 spec nor have I really understood the code you’ve posted but …

What stops the MCU from going back into sleep mode shortly after it’s awakened via an interrupt ? If the registers haven’t changed, that’s what I’d expect. Shouldn’t there be a “WakeNow” code that runs to reset the appropriate registers ?

When I was looking thru the code, the only other thing I thought about was the use of LOW on the attachInterrupt, Unless you want it to re-trigger constantly, you want to consider using FALLING instead.

As I understand it LOW is the only choice that works for all the sleep modes except IDLE. I am just trying to get SLEEP_MODE_PWR_DOWN to work. I just used the example at http://playground.arduino.cc/Learning/arduinoSleepCode as a starting. Should I be using a different starting point.

The notes from Nick Gammon has this mention …

15/Dec/2013 : We now believe that all external interrupts (not just LOW ones) will wake the processor from sleep. This seems more consistent with the fact that pin change interrupts can wake the processor.

[http://www.gammon.com.au/forum/?id=11488](http://www.gammon.com.au/forum/?id=11488)

I’m not positive that FALLING will resolve this, but I think it’s worth a shot. Meanwhile I’ll stare at your code a bit more to see if anything else jumps up.

I disagree w/some of the code, I don’t see any need to detach the “wake up” interrupt (nor to re-attach it in the sleepNow() function) but that’s not your problem. I would take, as a test, the code after the sleep_mode(); statement out of the sleepNow() function. Then in the empty wakeUpNow() function put the sleep_disable(); statement and a println("Awake !); statement. This way we can see if the interrupt is running or not when pin 3 is brought to LOW and how many times it runs.

I assume you deduce that it sleeps because you see the print statements which then stop, as expected, after 10 secs.

Mee-n-Mac

You are correct. I deduced that the Pro micro goes to sleep since the text output stops. That might not be a good assumption.

I will try the suggested changes tonight and post back.

cosmicray

Will try FALLING tonight. and post back

I tried the code below and I believe I’m getting the same results on an Arduino Micro (also 32U4 based).

#include <avr/sleep.h>
int wakePin = 3;                 // pin used for waking up
int sleepStatus = 0;             // variable to store a request for sleep
int count = 0;                   // counter

void wakeUpNow()        // here the interrupt is handled after wakeup
{
  // At this point do nothing
  sleep_disable();
  delay(100);
  Serial.begin(9600);
  delay(100);
  Serial.println("I am awake !");
}

void setup()
{
  pinMode(wakePin, INPUT_PULLUP);
  Serial.begin(9600);
  delay(10000);
  Serial.println("Immediately before attachInterupt");
  attachInterrupt(0, wakeUpNow, LOW);
  Serial.println("Immediately after attachInterupt");
}

void sleepNow()         // here we put the arduino to sleep
{
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  //attachInterrupt(0, wakeUpNow, LOW);
  sleep_mode();
  //sleep_disable();
  //detachInterrupt(0);
}

void loop()
{
  Serial.print("Awake for ");
  Serial.print(count);
  Serial.println(" sec");
  Serial.print("WakePin state is ");
  Serial.println(digitalRead(wakePin));
  count++;
  delay(1000);
  if (count >= 10) {
    Serial.println("Timer: Entering Sleep mode");
    delay(100);
    count = 0;
    sleepNow();
  }
}

What I see in the serial monitor window is …

Immediately before attachInterupt

Immediately after attachInterupt

Awake for 0 sec

WakePin state is 1

Awake for 1 sec

WakePin state is 1

Awake for 2 sec

WakePin state is 1

Awake for 3 sec

WakePin state is 1

Awake for 4 sec

WakePin state is 1

Awake for 5 sec

WakePin state is 1

Awake for 6 sec

WakePin state is 1

Awake for 7 sec

WakePin state is 1

Awake for 8 sec

WakePin state is 1

Awake for 9 sec

WakePin state is 1

Timer: Entering Sleep mode

So it appears it's going to sleep. When I ground pin 3 I see the Tx LED come on but no further com via the USB. I figured the "sleep" library being used isn't reseting/restarting the USB COM port code so I added the *Serial.begin(9600)* to the code above but nope, no difference. I'll have to look at the "sleep" library and the 32U4 sleep registers and see what's missing. It appears that the Micro does respond to the wakePin going LOW (Tx LED) but doesn't get the COM port back up and working.

I may also add a blinking LED during the count down to see if that code is running after “waking” (and if so, indicating that it’s just a COM port - USB problem). I note the COM port is AFU after sleeping and it takes some creative timing of the reset switch to get the Micro rebooted and still be awake when the Arduino IDE goes to U/L the code. I also note resetting does not bring back the serial monitor so there may be some Windows (7) issue as well ?? :?

I added a blinking LED to the code (modified version below) and I see that the LED does blink but it’s blinking at a 14-15x slower rate. That is instead of being on for 1 sec, off for 1 sec (as it is pre-sleep) … it’s on for almost 15 secs (post-awakening) and off for the same. So upon awakening the clock divider register is AFU … and maybe more. In any case the baud rate certainly won’t be the expected 9600 so the COM port will be AFU.

#include <avr/sleep.h>
int wakePin = 3;                 // pin used for waking up
int ledPin = 13;                 //onboard LED pin
bool blinkState = false;          // variable to store a request for sleep
int count = 0;                   // counter

void wakeUpNow()        // here the interrupt is handled after wakeup
{
  // At this point do nothing
  sleep_disable();
  delay(100);
  Serial.begin(9600);
  delay(100);
  Serial.println("I am awake !");
}

void setup()
{
  pinMode(wakePin, INPUT_PULLUP);
  Serial.begin(9600);
  delay(10000);
  Serial.println("Immediately before attachInterupt");
  attachInterrupt(0, wakeUpNow, LOW);
  Serial.println("Immediately after attachInterupt");
}

void sleepNow()         // here we put the arduino to sleep
{
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  //attachInterrupt(0, wakeUpNow, LOW);
  sleep_mode();
  //sleep_disable();
  //detachInterrupt(0);
}

void loop()
{
  Serial.print("Awake for ");
  Serial.print(count);
  Serial.println(" sec");
  Serial.print("WakePin state is ");
  Serial.println(digitalRead(wakePin));
  Serial.print("Blink state is ");
  Serial.println(blinkState);
  count++;
  blinkState = !blinkState;
  digitalWrite(ledPin, blinkState);
  delay(1000);
  if (count >= 10) {
    Serial.println("Timer: Entering Sleep mode");
    delay(100);
    count = 0;
    sleepNow();
  }
}

Thanks for digging into this with me. I am glad it isn’t just me Since I am learning this as I go, My first inclination is that I am doing something wrong.

So is this an issue with the way the Pro micro is laid out, the 32U4, or an issue with the sleep.h interface? What can I do to help?

Ian

ijourneaux:
So is this an issue with the way the Pro micro is laid out, the 32U4, or an issue with the sleep.h interface?

My GUESS is that there's some other 32U4 specific command that we're not using ... and should. That or the library doesn't include the proper registers for the 32U4. Somewhere there's an article on sleeping a 32U4 that will explain all. meanwhile look at the current draws vs power_state here ...

http://harizanov.com/2013/02/power-savi … tmega32u4/

EDIT : According to the comments here (down near the bottom), the recent version of this library supports the 32U4. So if you want, D/L and install the library and redo the code to use it. Give it a try. I’m going to have to reread the 32U4 datasheet to get familiar w/the registers and their names.

http://www.rocketscream.com/blog/2011/0 … o-library/

https://github.com/rocketscream/Low-Power

Ok. Now that I am starting to understand what is going on, the fact that the serial/usb port is AFU is not surprising as after the device goes to sleep, and then wakes up, it is nolonger enumerated correctly under windows. That is probably why I am nolonger getting anything out the serial port after it wakes up. That probably doesn’t explain the other issues you observed.