Redução do consumo de energia

Bom dia pessoal,

Mais uma vez venho pedir ajuda para essa comunidade que já me ajudou bastante em outras vezes.

É o seguinte, tenho um projeto utilizando uma placa de Arduino Mega com módulos SDCard e RTC, para que sejam salvos, a cada uma hora, em um cartão SDCard, as informações de um sensor ultrassônico de distância e de um sensor de temperatura.

Componentes de hardware:
Modulo HC-SR04
Sensor DHT11
Modulo RTC DS3231
Modulo SDCard
Arduino Mega 2560

A programação que estou usando está funcionando corretamente. Vejam mais abaixo.

A questão é que esse equipamento deverá ser utilizado em um local sem fornecimento de energia elétrica. O sensor de distância deverá medir o nível da superfície da água de um rio.

Então pensei e utilizar uma bateria como fonte de alimentação. Mas preciso que a bateria dure pelo menos uns 20 dias com o equipamento ligado constantemente e sem troca de bateria nesse período.

Tentei inicialmente com uma bateria 9V e ela forneceu a energia necessária para o equipamento funcionar por algumas horas apenas. Depois tentei com uma bateria de motocicleta (12v - 5Ah) e ela durou cerca de 2 dias. Ainda muito aquém do que eu preciso. Pensei em usar uma bateria de carro, mas o custo é alto e o tamanho é muito grande.

Assim, queria saber se vocês tem alguma ideia, se eu poderia fazer alguma coisa, tipo alteração na programação para poder reduzir o consumo de energia do equipamento.

Abaixo segue a programação (código) que desenvolvi utilizando outros códigos como referência. Em anexo tem uma foto do equipamento montado e o esquema de ligação do hardware.

Qualquer informação adicional ou dúvida, avisem.

// Componentes de Hardware: Módulo RTC DS3231, Modulo SD Card, Sensor de Temperatura e Umidade, Sensor Ultrassonico de Distancia
// Placa: ARDUINO MEGA 2560

// Modulo RTC DS3231 - ligado nas portas SDA e SCL (Portas digitais 20 e 21) do Arduino Mega
// Modulo SD Card - ligado nas portas digitais CS-4, MOSI-11, MISO-12, SCK-13
// Sensor de Temperatura e Umidade DHT 11- ligado a Porta Analogica A1 com resistor de pull-up
// Sensor Ultrassonico de Distancia HC-SR04 - TRIG ligado a Porta Digital 5 e ECO ligado a Porta Digital 6


// Inclui as bibliotecas do módulo RTC DS3231 e Time
#include <DS3231.h>
#include <Time.h>
#include <TimeLib.h>

// Inclui a biblioteca do módulo SD Card
#include <SdFat.h>

//Inclui a biblioteca do sensor ultrassonico
#include <Ultrasonic.h>

//Inclui a biblioteca do sensor de temperatura e umidade DHT 11
#include <DHT.h>


// Inicia o modulo RTC DS3231
DS3231  rtc(SDA, SCL);



// Inicia modulo SD Card e nomeia variavel SdFile como meuArquivo
SdFat sdCard;
SdFile meuArquivo;

// Pino digital 4 ligado ao CS do modulo SD Card
const int chipSelect = 4;


//Define os pinos para o trigger e echo do sensor ultrassonico de distancia
#define pino_trigger 5
#define pino_echo 6
 
//Inicializa o sensor ultrassonico nos pinos definidos acima
Ultrasonic ultrasonic(pino_trigger, pino_echo);

//Define o pino Analogico 1 para o sensor de temperatura e umid. DHT 11
#define DHTPIN A1
#define DHTTYPE DHT11 // DHT 11
DHT dht(DHTPIN, DHTTYPE);

// Declara variáveis para o loop de tempo
Time hora_atual_time;
unsigned long hora_atual;
unsigned long hora_cheia_atual;
unsigned long proxima_hora_cheia;

void setup()
{

  // Configura Conexao Serial em 9600 Hz
  Serial.begin(9600);
  
  
  // Inicializa o objeto rtc
  rtc.begin();
  
  // As 3 linhas abaixo devem ser descomentadas para ajustar a data e hora
  // Depois de carregar o programa, comentar as 3 linhas e carregar novamente o programa
  
//  rtc.setDOW(FRIDAY);     // Set Day-of-Week to SUNDAY
//  rtc.setTime(20, 06, 30);     // Set the time to 12:00:00 (24hr format)
//  rtc.setDate(24, 3, 2017);   // Set the date to January 1st, 2014


//Inicia o sensor de temperatura e umid. DHT 11
dht.begin();



 // Inicializa o modulo SD Card
  if(!sdCard.begin(chipSelect,SPI_HALF_SPEED))sdCard.initErrorHalt();
  // Abre o arquivo LER_POT.TXT
  if (!meuArquivo.open("ler_pot.txt", O_RDWR | O_CREAT | O_AT_END))
  {
    sdCard.errorHalt("Erro na abertura do arquivo LER_POT.TXT!");
  }

  
// Envia para o Monitor Serial o título do projeto
  Serial.println(" ");
  Serial.println(" ");

  Serial.print("Iniciado em : ");

    // Envia para o Monitor Serial o Dia-da-Semana (Day-of-Week)
  Serial.print(rtc.getDOWStr());
  Serial.print(" ");
  
  // Envia para o Monitor Serial a data (date)
  Serial.print(rtc.getDateStr());
  Serial.print(" -- ");

  // Envia para o Monitor Serial a hora (time)
  Serial.println(rtc.getTimeStr());
  Serial.println(" ");


// Envia para o Arquivo TXT o título do projeto
  meuArquivo.println(" ");
  meuArquivo.println(" ");

  meuArquivo.print("Iniciado em : ");

    // Envia para o Monitor Serial o Dia-da-Semana (Day-of-Week)
  meuArquivo.print(rtc.getDOWStr());
  meuArquivo.print(" ");
  
  // Envia para o Monitor Serial a data (date)
  meuArquivo.print(rtc.getDateStr());
  meuArquivo.print(" -- ");

  // Envia para o Monitor Serial a hora (time)
  meuArquivo.println(rtc.getTimeStr());
  meuArquivo.println(" ");

//Fecha o arquivo TXT
    meuArquivo.close();

//Le as informacoes do sensor ultrassonico, em cm para estabilizar o sensor
  float cmMsecEstab;
  long microsecEstab = ultrasonic.timing();
  cmMsecEstab = ultrasonic.convert(microsecEstab, Ultrasonic::CM);
    
}

void loop()
{

//Define o delay para esperar o # de segundos ate a proxima hora cheia
hora_atual_time = rtc.getTime();
hora_atual = rtc.getUnixTime(hora_atual_time); //pega o tempo em segundos desde 1970 até a data/hora atual
hora_cheia_atual = hora_atual - hora_atual_time.min*60 - hora_atual_time.sec; //subtrai os minutos e segundos para se chegar até a hora cheia atual, tipo 11:00:00, 12:00:00, 13:00:00, etc (em segundos)
proxima_hora_cheia = hora_cheia_atual + 3600; //define que a proxima hora cheia será a hora cheia + 60 minutos
  
// Espera o # de segundos ate a proxima hora cheia
delay ((proxima_hora_cheia - hora_atual)*1000);// dorme o # de milisegundos necessários para chegar até a proxima hora cheia...


// Abre o arquivo TXT
  meuArquivo.open("ler_pot.txt", O_RDWR | O_CREAT | O_AT_END);
  

//Le as informacoes do sensor ultrassonico, em cm
  float cmMsec;
  long microsec = ultrasonic.timing();
  cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);


  //Le as informacoes do sensor de temperatura e umid. DHT 11
float h = dht.readHumidity();
float t = dht.readTemperature();
  
 
  // Envia para o Monitor Serial o Dia-da-Semana (Day-of-Week)
  Serial.print(rtc.getDOWStr());
  Serial.print(" ");
  
  // Envia para o Monitor Serial a data (date)
  Serial.print(rtc.getDateStr());
  Serial.print(" -- ");

  // Envia para o Monitor Serial a hora (time)
  Serial.print(rtc.getTimeStr());


  //Envia informacoes do sensor ultrassonico para o serial monitor
  Serial.print("  Distancia em cm: ");
  Serial.print(cmMsec);


//Envia informacoes do sensor de temperatura e umid. DHT 11 para o serial monitor
  Serial.print("  ---  Umidade: ");
  Serial.print(h);
  Serial.print(" %t");
  Serial.print("  Temperatura: ");
  Serial.print(t);
  Serial.println(" *C");


  // Envia para o Arquivo TXT o Dia-da-Semana (Day-of-Week)
  meuArquivo.print(rtc.getDOWStr());
  meuArquivo.print(" ");
  
  // Envia para o Arquivo TXT a data (date)
  meuArquivo.print(rtc.getDateStr());
  meuArquivo.print(" -- ");

  // Envia para o Arquivo TXT o hora (time)
  meuArquivo.print(rtc.getTimeStr());


  //Envia informacoes do sensor ultrassonico para o Arquivo TXT
  meuArquivo.print("  Distancia em cm: ");
  meuArquivo.print(cmMsec);


//Envia informacoes do sensor de temperatura e umid. DHT 11 para o serial monitor
  meuArquivo.print("  -----  Umidade: ");
  meuArquivo.print(h);
  meuArquivo.print(" %t");
  meuArquivo.print("  Temperatura: ");
  meuArquivo.print(t);
  meuArquivo.println(" *C");



//Fecha o arquivo TXT
    meuArquivo.close();    

//  ;)

}

Abraços,

Ricardo

Projeto Esquema.pdf (953 KB)

Não sei qual e o consumo dele em funcionamento, mas acredito q essa bateria de moto e um painel solar acho que dará conta disso, mas tem o problema dos dias sem sol....

Verifique primeiramente o consumo dele...

Completando a solução do tiagocamana, acho que a solução passará também por usar modos de baixo consumo (Sleep modes) no Arduino.

Terás talvez de controlar a alimentação dos diferentes componentes (ligando apenas quando necessário) e julgo que conseguirás melhorar isso. Outra coisa a ter em conta é que todo e qualquer LED que tenhas activo está a consumir energia e não é pouca.

Outra coisa a ter em atenção é o estado dos pinos, regra geral existe um estado (esquece-me se é input ou output) que torna o consumo menor.

O melhor projecto que vi realizado para estender o funcionamento de baterias foram os jeenodes (podes ver aqui http://jeelabs.net/projects/cafe/wiki).

Se apenas precisas de fazer leituras de hora a hora, podes poupar imensa bateria colocando o microcontrolador a dormir em ciclos de 8 segundos e verificando se já está na hora de fazer uma medição.
No teu caso, imagino que o sensor de nível seja o que consome mais... e poderá ajudar passares o código para um Arduino mais pequeno... se bem que a diferença, comparada a alguns dos componentes deve ser mínima.

Tens aqui mais informação sobre isto:

https://www.gammon.com.au/forum/?id=11497
https://openhomeautomation.net/arduino-battery/
https://learn.sparkfun.com/tutorials/reducing-arduino-power-consumption
http://www.home-automation-community.com/arduino-low-power-how-to-run-atmega328p-for-a-year-on-coin-cell-battery/

Oi tiagocamana, muito obrigado.

Em termos de consumo, segundo as especificações nos datasheets, são:

Modulo HC-SR04 = 15 mA
Sensor DHT-11 = 0,3 mA (medindo) e 60 microA (standby)
Modulo RTC DS 3231 = max. 0,3 mA
Modulo SD Card = não encontrei essa informação
Arduino (usando 9 pinos I/O) = 180 mA (20mA por pino)

Considerando que tudo esteja em funcionamento, o consumo total seria 15+0,3+0,3+180 = 195,6 mA.

( Esses são os valores especificados pelos fabricantes dos componentes, mas depois vou tentar medir com o multímetro para saber com mais certeza a corrente consumida, tanto nos momentos de standby como nos momentos de leitura dos sensores.)

Eu não sei dimensionar placas solares, mas talvez seja mesmo a saída. Se puderes me ajudar...

Mas primeiro vou tentar avançar mais com as orientações que o bubulindo passou. Pois mesmo se eu for usar placas solares será benéfico reduzir o consumo por meio da programação.

Bubulindo, me esclareça algumas coisas:

Você disse:

"Se apenas precisas de fazer leituras de hora a hora, podes poupar imensa bateria colocando o microcontrolador a dormir em ciclos de 8 segundos e verificando se já está na hora de fazer uma medição."

Colocar o microcontrolador para dormir, significa usar a função Delay ? Pergunto isso pois eu já estou usando o Delay por meio dessa parte do código:

//Define o delay para esperar o # de segundos ate a proxima hora cheia
hora_atual_time = rtc.getTime();
hora_atual = rtc.getUnixTime(hora_atual_time); //pega o tempo em segundos desde 1970 até a data/hora atual
hora_cheia_atual = hora_atual - hora_atual_time.min*60 - hora_atual_time.sec; //subtrai os minutos e segundos para se chegar até a hora cheia atual, tipo 11:00:00, 12:00:00, 13:00:00, etc (em segundos)
proxima_hora_cheia = hora_cheia_atual + 3600; //define que a proxima hora cheia será a hora cheia + 60 minutos
  
// Espera o # de segundos ate a proxima hora cheia
delay ((proxima_hora_cheia - hora_atual)*1000);// dorme o # de milisegundos necessários para chegar até a proxima hora cheia

Outra coisa bubulindo,

Como fazer isso que você disse:

"Terás talvez de controlar a alimentação dos diferentes componentes (ligando apenas quando necessário) e julgo que conseguirás melhorar isso."

Realmente tem alguns componentes que ficam ligados constantemente ao VCC, mas a maior parte do tempo estão em standby, então será que teria como reduzir o consumo de maneira significante ?

Por fim, bubulindo,

Tem dois leds acessos constantemente, o led da placa do Arduino indicando que está alimentada e o led do módulo RTC, também indicando a alimentação. Mas não sei como desativá-los.

Obrigado pessoal !

Pesquisa pela biblioteca narcoleptic. A função delay() está literalmente a contar carneirinhos e não poupa energia nenhuma.

Eu dessoldei os leds duma placa arduino que ia ter alimentada com uma bateria para poupar energia. Essa é a única maneira de o fazer mesmo. Esse consumo do RTC e DHT parece-me bastante baixo... duvido que seja mesmo assim.

Não sei bem certo como é o funcionamento dessas placas, ou se precisas de algum modulo para que ela funcione, ou se é simplesmente ligando as saídas direto.

encontrei essa

super barata e fornece 300ma a 5v

encontre uma bateria de 4~6V para manter junto com uma amperagem boa (quanto mais amperagem mais ela manterá)

ou ate mesmo essa de 12v ligando juntamente com sua bateria de moto

http://www.dx.com/p/sw1512-1-5w-12v-polysilicon-solar-panel-power-motor-diy-components-446462#.WRxOStQrIUQ

Lembrando que vc pode ligar mais que uma placa aumentando assim a amperagem fornecida para seu sistema e para manter a carga da bateria