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);
2 Answers 2
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.
-
Thanks a lot, this solved my problem! Thanks also for the really nice write-up!Dakkaron– Dakkaron2022年05月09日 12:42:22 +00:00Commented May 9, 2022 at 12:42
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.
-
the ATmega32u4 on Micro has native USB peripheral2022年05月08日 17:50:41 +00:00Commented May 8, 2022 at 17:50
-
I added the requested information to the question.Dakkaron– Dakkaron2022年05月08日 18:52:06 +00:00Commented May 8, 2022 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.– Nick S.2022年05月09日 04:24:24 +00:00Commented May 9, 2022 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– Dakkaron2022年05月09日 07:27:34 +00:00Commented May 9, 2022 at 7:27
Explore related questions
See similar questions with these tags.
LowPower.idle(...);
?