ESP32: dicas para aumentar a vida útil da bateria

Tempo de leitura: 6 minutes

Executar um ESP32 com bateria é uma operação complicada. O chip é uma usina de força e com o poder vem uma grande responsabilidade. Neste post, vou descrever como fiz um ESP32 funcionar por mais de 15 semanas (e contando) com uma única bateria de 1000mAh.

Antes de começarmos: os exemplos de código mostrados nesta postagem são para uso com a estrutura do Arduino. Isso não foi testado com esp-idf diretamente.

 

Dica 1: use a bateria e a placa certas

Quer aumentar a vida útil da bateria? Em seguida, escolha uma placa ESP32 que tenha um conector de bateria embutido. Essas placas provavelmente usam um regulador de tensão LDO muito mais eficiente.

Um dos meus favoritos é o LOLIN32 Lite. Essas placas possuem regulador ME6211 que consome apenas 40uA. Embora essas placas tenham sido descontinuadas, você ainda pode encontrar muitas alternativas online.

WEMOS LOLIN32 Lite. Descontinuado, mas muitas variantes disponíveis. Ainda é meu favorito!

 

Dica 2: use a bateria certa

O ESP32 precisa de uma tensão de entrada de cerca de 3,3 V, então escolha uma bateria que forneça uma tensão próxima a esta.

Um LiFePO4 seria perfeito, pois fornece 3.2V. Também testei algumas baterias LIPO com voltagem de 3,7 V, o que parece funcionar muito bem.

 

Dica 3: escolha a placa ESP32 certa (núcleo único)

A maioria dos dispositivos IoT são relativamente simples e não requerem muito poder de computação. No entanto, o ESP32 tem um processador dual-core.

Considere comprar uma placa que usa a versão single-core do ESP32 (ESP32-SOLO-1).

A diferença entre dual-core e single-core? Bem, um ESP32 normal consumirá entre 27-44mA quando executado a 160 MHz, enquanto o single-core consome cerca de 30% menos, chegando a 27mA-34mA.

Consumo de energia ESP32

Consumo de energia do ESP32 de acordo com Espressif

 

Dica 4: reduza a velocidade do relógio

Menos núcleos consomem menos energia. O mesmo pode ser dito para núcleos mais lentos. Se você conseguir se safar com um ESP32 de núcleo único, é provável que consiga rodar esse núcleo em velocidades de clock menores.

Reduzir a velocidade do clock padrão de 160 MHz para 80 MHz pode diminuir o consumo de energia em outros 20%!

No Arduino, é apenas uma linha:

setCpuFrequencyMhz(80);

 

Dica 5: desligue tudo durante o sono profundo

Ao usar um ESP32 com bateria, você deve mantê-lo em repouso profundo pelo maior tempo possível. Caso você não saiba como: você configura um despertador e, em seguida, inicia o modo de hibernação:

// Quantos minutos o ESP deve dormir
#define DEEP_SLEEP_TIME 15

// Configure o cronômetro para nos acordar!
esp_sleep_enable_timer_wakeup(DEEP_SLEEP_TIME * 60L * 1000000L);

// Vá dormir! Zzzz
esp_deep_sleep_start();

No entanto, descobri que isso não é suficiente para manter o consumo de energia ao mínimo. Já vi vários relatórios de bug alegando que isso nem sempre desliga o rádio WiFi ou Bluetooth antes de entrar em um sono profundo.

Portanto, em vez de chamar esp_deep_sleep_start() diretamente, faço alguns preparativos primeiro. Eu desconecto o WiFi, desligo o rádio WiFi e Bluetooth, desligo o ADC e, em seguida, desligo os rádios WiFi e Bluetooth novamente, mas com a API ESP:

#include "WiFi.h" 
#include "driver/adc.h"
#include <esp_wifi.h>
#include <esp_bt.h>

// Quantos minutos o ESP deve dormir
#define DEEP_SLEEP_TIME 15

void goToDeepSleep()
{
  Serial.println("Ir dormir...");
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
  btStop();

  adc_power_off();
  esp_wifi_stop();
  esp_bt_controller_disable();

  // Configure o cronômetro para nos acordar!
  esp_sleep_enable_timer_wakeup(DEEP_SLEEP_TIME * 60L * 1000000L);

  // Vá dormir! Zzzz
  esp_deep_sleep_start();
}

Observação: se você estiver usando o ADC integrado, não se esqueça de ligá-lo novamente antes de usá-lo:

adc_power_on();

O WiFi ou Bluetooth não precisa estar explicitamente ativado. O regular

WiFi.begin(NETWORK, PASSWORD); basta.

Outra dica: não se esqueça de colocar seus periféricos em modo de espera quando não os estiver usando. Muitos sensores possuem recursos integrados de economia de energia que você pode ativar. Portanto, verifique definitivamente as bibliotecas que você usa para fazer a interface com eles e verifique se eles têm isso.

 

Dica 6: adicione um tempo limite de conexão WiFi

O ESP32 é ótimo para projetos de IoT porque tem Wi-Fi integrado. Não há necessidade de sinais e protocolos sem fio proprietários. A única desvantagem é que o WiFi consome muita energia, então você deseja minimizar o tempo gasto com o rádio ligado.

Eu sempre adiciono um tempo limite para configurar uma conexão sem fio. Você não quer que o ESP32 continue procurando uma rede WiFi específica indefinidamente. A bateria descarregará se sua rede ficar inativa por apenas alguns minutos (reinicialização do modem, queda de energia …) ou temporariamente fora de alcance.

Eu geralmente implemento um tempo limite de 10 segundos. Se nenhuma conexão WiFi puder ser estabelecida neste período de tempo, o ESP32 voltará ao sono profundo (esperando que o WiFi esteja disponível quando ele voltar a funcionar):

#define WIFI_NETWORK “YOUR_WIFI_NETWORK_NAME”
#define WIFI_PASSWORD “YOUR_WIFI_PASSWORD”
#define WIFI_TIMEOUT 10000 // 10segundos em milissegundos

void connectToWiFi()
{
  Serial.print("Conectando ao Wi-Fi ...");
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_NETWORK, WIFI_PASSWORD);

  // Acompanhe quando começamos nossa tentativa de obter uma conexão WiFi
  unsigned long startAttemptTime = millis();

  // Continue em loop enquanto não estamos conectados E não atingimos o tempo limite
  while (WiFi.status() != WL_CONNECTED && 
          millis() - startAttemptTime < WIFI_TIMEOUT){
    delay(10)
  }

  // Certifique-se de que estamos realmente conectados, caso contrário, vá dormir profundamente
  if(WiFi.status() != WL_CONNECTED){
    Serial.println("FAILED");
    goToDeepSleep();
  }

  Serial.println("OK");
}

 

Dica 7: use a memória RTC para reduzir as conexões WiFi

Finalmente, a maior dica de todas: as conexões WiFi são extremamente duras para a duração da bateria, portanto, fazer menos aumentará drasticamente a duração da bateria.

Digamos que você queira construir um sensor de temperatura que faça uma nova medição a cada 15 minutos. Você realmente precisa saber a temperatura em tempo real? Ou posso enviar um lote de leituras a cada 6 horas, por exemplo?

Em caso afirmativo, considere usar a memória RTC do ESP para armazenar suas medições sem conectar-se ao WiFi. Muitos dos meus sensores empregam o seguinte algoritmo:

  • Acordar de um sono profundo
  • Meça algo
  • Armazene a medição na memória RTC
  • Se tivermos X leituras, conecte-se ao WiFi e envie-as todas para a nuvem
  • Se não, volte a dormir profundamente

Traduzido para o código Arduino, isso daria a você:

// Quantas leituras queremos armazenar antes de enviá-las por WiFi
// -> 20 leituras com 15 minutos entre cada leitura = conectando apenas a WiFi a cada 300 minutos (5 horas) em vez de a cada 15 minutos
#define MAX_OFFLINE_READINGS 20

// Coloque na memória RTC para armazenar as leituras offline (e quantas temos até agora)
RTC_DATA_ATTR unsigned char offlineReadingCount = 0;
RTC_DATA_ATTR unsigned int readings_temp[MAX_OFFLINE_READINGS + 1];

// Grave a temperatura (20,9°C) na memória do RTC. Você pode querer substituí-lo pelo seu código de medição real;)
readings_temp[offlineReadingCount] = 209;
offlineReadingCount++;

// Se coletarmos menos do que a quantidade máxima de leituras, volte a dormir profundamente!
if(offlineReadingCount <= MAX_OFFLINE_READINGS){
    goToDeepSleep();
    return;
}

// Se chegarmos aqui, temos que enviar as leituras por WiFi
sendReadings();

// Não se esqueça de zerar os contadores!
offlineReadingCount = 0;

Nota: Como apontado no Reddit, este código não lida com uma situação em que o ESP32 não pode se conectar ao WiFi quando o buffer de leituras offline está cheio. Você pode querer adicionar isso.

 

Dica 8: use IP estático e evite nomes de host

Esta dica vem do usuário romkey do Reddit: use um endereço IP estático e evite usar nomes de host (que precisam ser resolvidos com DNS).

Ao codificar um endereço IP em seu ESP32, você reduz o tempo que leva para obter um endereço por meio de DHCP.

Outra dica é evitar o uso de nomes de domínio ao se conectar a servidores remotos. Criar uma conexão MQTT com cloudmqtt.com, por exemplo, requer que seu ESP32 descubra o endereço IP por trás do nome. Isso acontece por meio de um resolvedor de DNS e pode levar de alguns milissegundos a várias centenas. Se possível, use o endereço IP dos servidores aos quais deseja se conectar. Isso permitirá que você desligue o WiFi mais cedo.

Embora essas dicas reduzam o tempo gasto com o rádio WiFi ligado, nem sempre são práticas. Um endereço IP estático é possível em sua rede doméstica, mas não quando você deseja enviar dispositivos aos clientes. Da mesma forma, evitar o DNS provavelmente não será possível se você usar um serviço como o AWS IoT.

 

Dica para o futuro

Outra dica que estou explorando atualmente é usar um módulo de criptografia de hardware para acelerar a criptografia. Para mim, isso seria útil porque eu uso o AWS IoT, que requer criptografia forte, e isso leva um tempo para fazer em um vanilla ESP32.

A Espressif também percebeu isso e anunciou o ESP32-S2, uma versão de núcleo único com criptografia acelerada por hardware integrada.

Eu não tenho minhas mãos em um destes ainda, então é para outra hora.

 

 

Conclusão

As dicas acima me renderam uma boa duração da bateria em vários dos meus projetos ESP32. Meus principais objetivos são sempre: reduzir o número de conexões WiFi e maximizar o tempo que você passa em sono profundo.

Deixe-me saber nos comentários abaixo se você tiver dicas e truques adicionais.