BLE HID Power Consumption
Posted: Tue Aug 25, 2020 10:20 pm
I'm trying to make a bluetooth keyboard/macropad based on the ESP32 and I'm wondering why my power consumption of it is so high, and if it's possible to lower it to a reasonable level. Now, I know there are better options out there for BLE HID devices (Nordic has some great little modules), but I already have several ESP32's and I'd rather not spend $20 and/or wait three months to get my project working, especially when the ESP32 should, I think, be perfectly adequate.
There are a ton of forum posts about the power consumption of the ESP32 while using BLE and why it's so high, the only reason I'm making this post at all is because they're all from years ago and most simply boil down to "the 'L' in BLE isn't a thing yet", but I can't find any follow up posts anywhere showing whether or not the BLE is still power hungry.
As far as things I've tried, I found this post: viewtopic.php?t=773 which suggests turning off the WiFi section of the radio module via, which doesn't seem to have any impact at all on the current consumption. Or via , which actually seems to prevent the bleKeyboard from working at all. This, along with the fact that running BLE without WiFi is never (as far as I was able to find) mentioned in the documentation (https://docs.espressif.com/projects/esp ... ement.html), makes me wonder if the WiFi and BLE sections can't be run individually, although the function block diagram found in this documentation https://lastminuteengineers.com/esp32-s ... nsumption/, would seem to indicate that they are largely independent.
I've powered off the ADC using
There is also the various power modes; hibernation, deep sleep, light sleep, modem sleep, and active. Hibernation, deep sleep, and light sleep turn off all radio functions, so they're not helpful, and active obviously doesn't save any power. That leaves modem sleep. According to the documentation by lastminuteengineers, modem sleep also turns off all radio functions, but according to the espressif documentation, WiFi connections will be maintained during modem sleep. Neither mention anything about BLE specifically. It should be a simple matter to test this out myself, but I can't seem to actually find any documentation on how to enter modem sleep or configure it in any way, as modem sleep was still not supported when most of the forum posts about it were written. I tried having it sleep in between key strokes, but deep sleep and light sleep both take way too long to wake up from, so even though the ESP can be woken by pressing any key, I'd have to hold that key down for several seconds before it registers it.
I changed the CPU frequency as suggested here https://www.savjee.be/2019/12/esp32-tip ... lock-speed via the command This made a significant difference in power consumption.
My exact setup and testing results so far:
My board is the TinyPico (https://www.tinypico.com/), which conveniently had a very efficient lipo battery management circuit on board. To measure power usage I've connected an INA260 current sensor (https://learn.adafruit.com/adafruit-ina ... r-breakout) between the external battery and the BAT pin of the board. I'm only interested in two keys at the moment, so I have pins 32 and 33 pulled low via external resistors.
Running the code below, the best average current consumption I was able to achieve was around 33mA, which is better than a lot of posts I've read, but still pretty terrible for a BLE HID device.
I also checked the current draw on an oscilloscope and noticed that it hovered around 23mA with spikes to around 115mA every 45mS or so. I don't see anything in my code that would cause activity every 45mS, so I assume this has something to do with BLE protocols or something.
All that to say, is there anything I can do to reduce the power consumption of the ESP32 while using BLE? Something else I can turn off? A way to turn off WiFi while leaving BLE on? An example of how to use modem sleep?
Example code would be awesome, but links to other resources, and even just ideas are welcome as well.
There are a ton of forum posts about the power consumption of the ESP32 while using BLE and why it's so high, the only reason I'm making this post at all is because they're all from years ago and most simply boil down to "the 'L' in BLE isn't a thing yet", but I can't find any follow up posts anywhere showing whether or not the BLE is still power hungry.
As far as things I've tried, I found this post: viewtopic.php?t=773 which suggests turning off the WiFi section of the radio module via
Code: Select all
esp_wifi_set_mode(WIFI_MODE_NULL);
Code: Select all
esp_wifi_stop();
I've powered off the ADC using
Code: Select all
adc_power_off();
I changed the CPU frequency as suggested here https://www.savjee.be/2019/12/esp32-tip ... lock-speed via the command
Code: Select all
setCpuFrequencyMhz(80);
My exact setup and testing results so far:
My board is the TinyPico (https://www.tinypico.com/), which conveniently had a very efficient lipo battery management circuit on board. To measure power usage I've connected an INA260 current sensor (https://learn.adafruit.com/adafruit-ina ... r-breakout) between the external battery and the BAT pin of the board. I'm only interested in two keys at the moment, so I have pins 32 and 33 pulled low via external resistors.
Running the code below, the best average current consumption I was able to achieve was around 33mA, which is better than a lot of posts I've read, but still pretty terrible for a BLE HID device.
Code: Select all
#include <TinyPICO.h> //for the TinyPico dev board
#include <BleKeyboard.h>
#include <driver/adc.h>
BleKeyboard bleKeyboard;
TinyPICO tp = TinyPICO();
//both pins are pulled low via external resistor
#define upButton 32
#define downButton 33
void setup() {
tp.DotStar_SetPower(false);
adc_power_off();
setCpuFrequencyMhz(80);
Serial.begin(115200);
Serial.println(getCpuFrequencyMhz());
bleKeyboard.begin();
pinMode(upButton, INPUT);
pinMode(downButton, INPUT);
Serial.print("Connecting...");
while(!bleKeyboard.isConnected());
Serial.println("Connected");
}
void loop() {
while(bleKeyboard.isConnected()) {
if(digitalRead(upButton)) {
bleKeyboard.press(KEY_UP_ARROW);
bleKeyboard.releaseAll();
delay(1000); //debouncing
}
if(digitalRead(downButton)) {
bleKeyboard.press(KEY_DOWN_ARROW);
bleKeyboard.releaseAll();
delay(1000);
}
delay(10);
}
delay(1000);
}
All that to say, is there anything I can do to reduce the power consumption of the ESP32 while using BLE? Something else I can turn off? A way to turn off WiFi while leaving BLE on? An example of how to use modem sleep?
Example code would be awesome, but links to other resources, and even just ideas are welcome as well.