13 de outubro de 2018

SleepMode - Reduzindo o consumo de energia do Arduino

Como reduzir o consumo de energia do projeto e aproveitar as baterias por muito mais tempo.

 
Um Arduino Pro Mini ligado sem nenhuma carga, caiu de 15 mA para apenas 3 mA. Uma redução de 80% do consumo.

Em algumas situações é necessário que o microcontrolador não fique executando nenhuma tarefa, apenas aguardando o sinal de um sensor, por exemplo.
Se deixarmos um arduino rodando em seu loop apenas verificando os sensores, o consumo de energia será o padrão do microcontrolador e, para casos que utilizamos baterias, isso pode ser um problema.

Existe uma forma de colocamos o microcontrolador para "dormir", desabilitando suas entradas analógicas, comunicação USB, temporizadores, etc.
Essa situação faz com que o tempo de vida útil das baterias passem de algumas semanas para vários meses.

No projeto, utilizei 4 leds e um botão tipo push-button normalmente aberto.
Conforme mostrado no vídeo, quando os leds estão piscando em forma sequencial, o consumo é de 20 mA. Quando temos todos os leds acessos, o consumo sobe para 49 mA. Com apenas um led, são 24 mA de consumo.

Com todos os leds apagados, sem carga, o circuito consome 16 mA. Entrando em modo sleep esse consumo cai para apenas 3 mA.

Para sair do modo sleep foi utilizado o recurso de interrupção externa.

Referências:
https://playground.arduino.cc/Learning/arduinoSleepCode
https://www.arduino.cc/reference/pt/language/functions/external-interrupts/attachinterrupt/

Segue o esquema elétrico e o código fonte:



/*--------------------------------------------------------------
  Programa : SLEEPMODE - REDUZIR O CONSUMO DE ENERGIA DO ARDUINO
  Autor    : Fellipe Couto [ http://www.efeitonerd.com.br ]
  Data     : 13/10/2018
  --------------------------------------------------------------*/

#include <avr/sleep.h>
#define INTERRUPT 2
int led[4] = {6, 7, 8, 9};
boolean flag = false;

/*--- SETUP ---*/
void setup() {
  //Configura o pull-up do pino 2, usado para interrupção externa
  pinMode(INTERRUPT, INPUT_PULLUP);

  //Configura os pinos dos leds como saída
  for (int i = 0; i < 4; i++) {
    pinMode(led[i], OUTPUT);
  }

  //Configura a interrupção externa (0 = pino 2) chamando a função SetFlag()
  attachInterrupt(0, SetFlag, FALLING);
}

/*--- LOOP PRINCIPAL ---*/
void loop() {
  if (flag == true) {
    //Ativa os leds
    BlinkLeds();

    //Seta a variável de controle
    flag = false;

    //Pisca o led uma vez
    digitalWrite(led[0], HIGH);
    delay(200);
    digitalWrite(led[0], LOW);

    //Seta o microcontrolador em modo sleep
    GoToSleep();
  }
}

/*--- PISCA OS LEDS ---*/
void BlinkLeds() {
  //Pisca os leds em sequencia
  for (int j = 0; j < 10; j++) {
    for (int i = 0; i < 4; i++) {
      digitalWrite(led[i], HIGH);
      delay(70);
      digitalWrite(led[i], LOW);
      delay(70);
    }
  }

  //Acende todos
  for (int i = 0; i < 4; i++) {
    digitalWrite(led[i], HIGH);
    delay(200);
  }
  delay(6000);

  //Apaga todos
  for (int i = 0; i < 4; i++) {
    digitalWrite(led[i], LOW);
    delay(200);
  }

  //Mantem somente um led acesso
  digitalWrite(led[0], HIGH);
  delay(6000);

  //Apaga o led
  digitalWrite(led[0], LOW);
  delay(6000);
}

/*--- MODO SLEEP PARA REDUÇÃO DO CONSUMO DE ENERGIA ---*/
void GoToSleep() {
  //Configura o tipo de sleep (power down)
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);

  //Habilita a função sleep para que possa ser usada
  sleep_enable();

  //Configura a interrupção externa (0 = pino 2) chamando a função SetFlag()
  attachInterrupt(0, SetFlag, FALLING);

  //Aciona o modo sleep, para adormecer o microcontrolador
  sleep_mode();

  //--> Microcontrolador em sleep nesse momento. Com interrupção externa executa a partir deste ponto

  //Desativa o modo sleep
  sleep_disable();

  //Desativa a leitura de interrupção
  detachInterrupt(0);
}

/*--- SETA A VARIÁVEL FLAG ---*/
void SetFlag() {
  flag = true;
}

Nenhum comentário:

Postar um comentário