Arduino e bateria: providências simples para reduzir o consumo

Uma bateria ou conjunto de pilhas podem manter seu Arduino funcionando por semanas ou meses, mas alguns detalhes no circuito e colocar o Arduino em modo de economia de energia contribuem para que a duração aumente muito.

Conectar o Arduino a algumas pilhas é bastante simples: basta respeitar os limites de tensão das especificações do seu Arduino1, e plugar o polo positivo das pilhas ao pino VIN, e o negativo ao pino GND2. O pino VIN (Voltage INput) conecta as pilhas ao regulador interno do Arduino, assim é possível ter algum grau de tranquilidade quanto às flutuações típicas das pilhas.

Estou aprendendo mais a cada dia, e resolvi experimentar a conexão do Arduino a baterias externas, plugando uma bateria de 9V aos pinos VIN e GND, conforme mencionei acima.

Para o experimento, recorri ao circuito do sensor de presença que montei na semana passada. Deixei tudo como estava, apenas desconectei o Arduino da fonte USB e o conectei à bateria.

Como esperado, o circuito continuou funcionando exatamente como antes: ao receber, em um pino digital, o sinal de que o gatilho do sensor infravermelho indicava movimento, o programa verificava o estado do sensor de luminosidade e, se estivesse escuro, acendia um led por 30 segundos.

Mas experimentos servem para fixar e aprender. Neste, eu fixei o que planejava: a ideia de que é fácil conectar o Arduino a uma bateria de 9V (ou a algumas pilhas AA, ou a outras combinações que estejam dentro da especificação).

Mas no processo eu também aprendi algo que não esperava: que aquele meu circuito e programa usavam bem mais energia do que poderiam, e assim gastaram a carga da bateria muito mais rapidamente do que eu esperava.

Identificando os culpados

Estou começando no mundo da eletrônica, e não conheço ainda alguma metodologia que me permitiria encontrar, de forma objetiva e otimizada, por onde estava ocorrendo a fuga acelerada da carga da bateria.

Talvez eu pudesse medir com um multímetro, em vários pontos do circuito, mas não me pareceu prático e nem preciso o suficiente. Resolvi, então, me debruçar sobre o esquema simplificado do meu circuito (detalhado no artigo anterior), e testar nele algumas hipóteses, já que o número de componentes é baixo:

Indo direto à conclusão, eis o que observei: meu sensor de luminosidade é um fotoresistor que, na forma que eu o montei, está permanentemente deixando passar alguma corrente (maior quando está claro, menor quando está escuro) entre o pino 5V do Arduino e o terra. O fato de haver ali um segundo resistor em série – fazendo o papel de pull-down – ajuda a desacelerar o consumo, mas não o impede.

Além disso, embora só precise realizar alguma tarefa nos períodos em que detecta movimento e baixa luminosidade, a forma como construí o programa mantém o Arduino em si consumindo energia durante todo o tempo.

Somados, esses 2 fatores certamente contribuem para que a bateria seja consumida bem mais rapidamente do que deveria. E eu consegui encontrar alternativas melhores para ambas.

Reduzindo o consumo de bateria no Arduino

Minha primeira linha de ataque foi contra o sensor que consumia energia permanentemente sem necessidade, e creio que uma solução igual ou similar valeria para outros sensores que conectem incondicionalmente os pinos 5V e GND (ou outras origens de corrente e acessos ao terra): tornar essa conexão condicional, por meio de uma chave, de outro sensor ou de alteração na lógica empregada.

Para evitar o consumo permanente, eu desconectei do pino 5V a entrada do fotoresistor, e conectei-a ao pino digital 13. Em seguida modifiquei levemente o programa para passar a deixar o pino 13 no estado LOW, colocando-o só brevemente em HIGH (e assim levando corrente significativa ao fotosensor) por períodos de menos de 1 segundo, sempre que o sensor infravermelho detecta movimento.

Assim fica preservada integralmente a funcionalidade de ambos os sensores, mas o consumo provocado pelo sensor de movimento cai drasticamente.

Colocando o Arduino em modo de economia de energia

Os microcontroladores que formam os cérebros dos Arduinos dispõem de um modo de economia de energia cujo mecanismo é similar ao que você já deve ter visto nos notebooks: ele fica aparentemente desligado, gastando pouquíssima energia e monitorando apenas as condições que o farão "acordar", como a abertura da tampa ou o pressionamento do botão liga/desliga.

No caso do Arduino, uma maneira fácil de ter acesso a essa funcionalidade é o uso da biblioteca Narcoleptic. Para usá-la é preciso fazer o download, descompactar e mover a sua pasta para dentro da pasta libraries do seu Arduino no computador (e ela só ficará acessível depois de a IDE do Arduino ser reiniciada).

A partir daí, quando o seu programa tiver a linha #include , ele poderá usar as várias funcionalidades da biblioteca Narcoleptic, incluindo a que eu usei no meu programa: a função Narcoleptic.delay().

Na aparência, a função Narcoleptic.delay() faz o mesmo que a função delay() da biblioteca básica do Arduino: provoca uma pausa de um certo número de milissegundos. Assim, se usarmos Narcoleptic.delay(500) teremos uma pausa de meio segundo, enquanto Narcoleptic.delay(8000) fará uma pausa de 8 segundos. Por uma particularidade da biblioteca, 8000 milissegundos (8 segundos) é o máximo que o Narcoleptic.delay() consegue pausar na mesma chamada; para pausas maiores, é necessário chamar a função várias vezes em sequência.

O que diferencia a Narcoleptic.delay() da simples delay() é que a primeira, enquanto faz a pausa, coloca o microcontrolador em modo de baixo consumo de energia, e a segunda mantém o microcontrolador em seu modo de consumo normal de energia durante todo o tempo.

Assim, nos casos em que é possível trocar o delay() pelo Narcoleptic.delay(), podemos – de grão em grão – reduzir bastante o consumo de energia. Vale recomendar atenção às observações do autor da biblioteca, que destaca as limitações físicas e lógicas da solução: por exemplo, ela suspende ou prejudica até mesmo o funcionamento de recursos como PWM e a função millis()3. Além disso, embora ela coloque o microcontrolador em estado de baixo consumo, ela não tem o poder de fazer o mesmo com o controlador USB (se o seu Arduino tiver um), ou com os leds que estiverem acesos, ou com resistores pelos quais houver corrente passando, etc.

Ainda assim, é significativo, e o próprio autor destaca: em um sistema bem otimizado, o uso da função pode fazer um par de pilhas AAA durarem alguns anos mantendo o seu sistema em funcionamento.

Como ficou o programa

Como de hábito, compartilho a íntegra do programa que usei:

/*  Sensor-acende-led: acende leds quando detecta movimento no escuro
  
    (c)  Augusto Campos 28.11.2014 - BR-Arduino.org
    Usage of the works is permitted provided that this instrument is retained 
    with the works, so that any entity that uses the works is notified of 
    this instrument. DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY. */

#include <Narcoleptic.h>

const int limite_claridade=5;  // sensor abaixo deste valor indica escuro
const int led_externo=2;       // pino do led externo
const int fonte_lum=13;        // pino que ativa o sensor de luminosidade
const int leitura_pir=A5;      // pino onde eh lido o sensor  digital de movimento

bool estaEscuro;

void setup() {
  pinMode(led_externo, OUTPUT);
  pinMode(leitura_pir, INPUT);
  pinMode(fonte_lum, OUTPUT);
  digitalWrite(fonte_lum,LOW); 
  // pisca uma vez para indicar que esta no ar
  digitalWrite(led_externo,HIGH); 
  delay(100);
  digitalWrite(led_externo,LOW); 
}

void loop() {
  Narcoleptic.delay(900);
  if (digitalRead(leitura_pir)==HIGH) {
    gerenciaLed();
  }
}

void gerenciaLed() {
  digitalWrite(fonte_lum,HIGH); 
  delay(50);
  estaEscuro=(map(analogRead(7),0,1023,1,10)<=limite_claridade);
  digitalWrite(fonte_lum,LOW);    
  if(estaEscuro) {
    digitalWrite(led_externo,HIGH); 
    for (int i=0;i<=6;i++) {
      Narcoleptic.delay(8000);
    }
    digitalWrite(led_externo,LOW); 
  }  
}    

A maior parte do código já foi explicada no experimento anterior, mas destaquei acima as mudanças, que vou explicar a seguir.

Destaquei em vermelho os trechos que fazem o novo controle do fotoresistor, que deixou de estar conectado ao pino 5V (de onde recebia corrente constantemente) e passou a estar conectado ao pino digital 13 (de onde só recebe corrente significativa quando o programa o coloca em modo HIGH).

É bem simples: na inicialização, o pino 13 é colocado em modo OUTPUT e recebe o valor LOW. Depois, quando chega a hora de gerenciar o led, o pino recebe brevemente o valor HIGH e, neste período, o fotoresistor recebe corrente, e seu efeito pode ser lido normalmente, indicando a luminosidade detectada.

Em verde, eu destaquei os trechos relacionados às funções da biblioteca Narcoleptic, que colocam o microcontrolador para dormir. Note que a função loop() (obrigatória, que o Arduino executa repetidamente enquanto estiver operando) agora começa com um Narcoleptic.delay(900);, o que significa que, a cada "volta" do programa, ele vai fazer uma pausa de baixo consumo por 0,9 segundo, antes de verificar o sensor de presença.

Quando ele verifica que o sensor de presença está com valor HIGH (indicando que detectou movimento), chama a função gerenciaLed(), definida logo a seguir, que – como vimos acima e no artigo anterior – ativa o sensor de luminosidade, verifica se está escuro e, se estiver, executa a sequência a seguir:

  1. Acende o led
  2. Repete 6 vezes uma pausa de 8 segundos (o intervalo máximo suportado pela pausa de baixo consumo)
  3. Apaga o led

Note que, na prática, a maior parte do tempo de funcionamento do sistema estará executando exatamente as pausas de baixo consumo de energia, sem prejudicar a funcionalidade. C. Q. D.

Para o futuro, pretendo revisitar este experimento, para usar interrupções do microcontrolador para "acordar" o sistema só quando o sensor indicar que houve movimento, sem ter de fazer delays cíclicos. Talvez eu tente usar PWM para reduzir o consumo de energia pelo led. E quem sabe até lá eu terei disponível para testes um Arduino sem controlador USB embutido.

 
  1.  No meu Nano, a recomendação é ficar entre 7V e 12V.

  2.  Existem outras formas de plugar, cada uma com suas aplicações, mas a que eu mencionei é a mais simples

  3.  Para a função millis() há alternativa, conforme a própria documentação explica

Comentar

Dos leds ao Arduino, ESP8266 e mais

Aprenda eletrônica com as experiências de um geek veterano dos bits e bytes que nunca tinha soldado um led na vida, e resolveu narrar para você o que descobre enquanto explora esse universo – a partir da eletrônica básica, até chegar aos circuitos modernos.

Por Augusto Campos, autor do BR-Linux e Efetividade.net.

Recomendados

Livro recomendado


Artigos já disponíveis

Comunidade Arduino

O BR-Arduino é integrante da comunidade internacional de entusiastas do Arduino, mas não tem relação com os criadores e distribuidores do produto, nem com os detentores das marcas registradas.

Livros recomendados