0

I am using an Arduino Pro Micro (basically a Leonardo in a smaller form factor) in a mobile application where power consumption is really important.

To reduce power consumption, I put the Arduino to sleep, but that disconnects USB. That's not really acceptable in this application, since reconnecting USB after the Arduino wakes takes pretty long (a second or two).

Is there some way to keep the USB connection alive while still conserving energy? E.g. by waking the ATMega32u4 frequently to keep the connection alive? Or is there some not-as-deep sleep moden where the USB connection stays alive?

Edits for clarification:

The device is an USB HID device. If the device goes to sleep after a few minutes of inactivity, having to reconnect after the user pressed a button causes quite a long delay between pressing the button and a reaction on the device.

I am using the ATMega32u4's native USB implementation, so no V-USB or anything similar.

I am putting the device to sleep like so:

Keyboard.end();
USBCON = 0;
LowPower.powerDown(SLEEP_120MS, ADC_OFF, BOD_OFF);

This is how I wake it up again:

USBDevice.attach();
delay(50);
Keyboard.begin(KeyboardLayout_en_US);
5
  • 1
    Did you try LowPower.idle(...);? May 8 at 20:14
  • No, not yet, I will try that, thanks!
    – Dakkaron
    May 9 at 7:26
  • @EdgarBonet That's exaclty what I needed, it works perfectly, thanks! Do you want to post this as an answer so I can accept it?
    – Dakkaron
    May 9 at 12:15
  • 1
    Removing the power LED can reduce power consumption also.
    – sa_leinad
    May 9 at 14:26
  • @sa_leinad Thanks for the input, I was planning to do that!
    – Dakkaron
    May 9 at 15:37

2 Answers 2

4

The Arduino has several sleep modes. They differ mainly by the clocks that are kept running, the peripherals that are enabled, and the possible wake-up sources. All these modes are described in the datasheet of the ATmega32U4 microcontroller, section 7: Power Management and Sleep Modes.

You may see here that “Power-down” is one of the deepest sleep modes: all clocks are disabled, the main oscillator is turned off, and only asynchronous wake-up sources are available. As you have experienced, the USB port is not functional in this mode.

In contrast, “Idle” is a somewhat shallow sleep: the CPU is halted but the peripherals remain clocked. Any enabled interrupt can be used as a wake-up source. This is a good option if you want the USB link to remain connected while sleeping, and you can get it with the LowPower.idle() function.

If you are worried about the sleep mode to be too “shallow” and not save enough energy, note that the parameters if LowPower.idle() let you specify which peripherals you want to keep running during sleep. If you keep running only those that are needed, this should limit the power consumption to what is strictly needed.

1
  • Thanks a lot, this solved my problem! Thanks also for the really nice write-up!
    – Dakkaron
    May 9 at 12:42
2

This would better serve as a comment, but I can't post comments (yet)...

  • What is your application doing? Is it supposed to be asynchronous? Why are 1-2 seconds too long?
  • By the "USB" connection, you mean the UART/Serial peripheral?
  • How are you putting the board to sleep? Are you using the Arduino Sleep Modes? If so, which one are you using?

I'll speculate a bit: if you are using the ASP, then you might have to change the source code for the functions you are using to accommodate for keeping that peripheral awake. Do note that it might make the application more power-hungry than you want it to be.

Waking up more often could be done, but ideally you would need a synchronization mechanism, because at least eventually you'll run into an issue where you might miss the data or you'll wake up the device so often, you'll lose your power savings.

4
  • the ATmega32u4 on Micro has native USB peripheral
    – Juraj
    May 8 at 17:50
  • I added the requested information to the question.
    – Dakkaron
    May 8 at 18:52
  • @Dakkaron thanks! I'll have to look at this more, this is not necessarily a trivial problem. I'd suggest trying out the standby mode and seeing if the USB is more responsive. Does your application require the powerdown mode? Also, why do you do "USBCON = 0" vs "USBDevice.detach()"?
    – Nick S.
    May 9 at 4:24
  • Thanks for the feedback, I will try that. The main reason I didn't try that, is because my solution is what Google turned up. Thanks for the input!
    – Dakkaron
    May 9 at 7:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.