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:
- Acende o led
- Repete 6 vezes uma pausa de 8 segundos (o intervalo máximo suportado pela pausa de baixo consumo)
- 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.
Comentar