terça-feira, 29 de setembro de 2015

Adormecendo Arduino: Narcoleptic

Narcoleptic


   É logico que não seria útil usar o Arduino se não houvesse um mode de despertá-lo novamente! Há dois métodos para acordar um Arduino. Um é usando uma interrupção externa e outro é programando um temporizador para acordar o Arduino após um determinado tempo. A biblioteca Narcoleptic utiliza apenas o método do temporizador.

   A biblioteca Narcoleptic fornece uma função delay alternativa que coloca o Arduino para dormir por um período de tempo que é especificado como parâmetro da função delay. Como nada acontece enquanto o Arduino está em delay, esse método funciona muito bem.

    Uma versão Narcoleptic do blink seria essa: 

 #include <Narcoleptic.h>  
 void setup()   
 {  
  pinMode(13, OUTPUT);  
 }  
 void loop()   
 {  
  digitalWrite(13, HIGH);  
  Narcoleptic.delay(1000);  
  digitalWrite(13, LOW);  
  Narcoleptic.delay(10000);  
 }  

    A grande diferença do uso da biblioteca Narcoleptic e o uso da própria função delay. Ao medir o consumo de corrente verifica-se que usando o sketch blink normal, o consumo é de 17,2mA e o uso do blink Narcoleptic cai o consumo aos poucos 3,2 mA.


    OBS: Biblioteca Narcoleptic




    Despertando com interrupções externas:

    Se você precisar responder com mais repidez a um evento externo, então será necessário acordar o microcontrolador quando ocorrr uma interrupção externa.
    
    O exemplo abaixo usa o pino P2 como interrupção externa. Os resultados serão os melhores porque não há necessidade de periodicamente testar o pino de interrupção. O código nesse caso é bem complexo. Por isso,  é mostrado o código e então descreverei como tudo funciona.

 // sketch_05_06_sleep_external_wake  
 #include <avr/sleep.h>  
 const int ledPin = 13;  
 const int inputPin = 2;  
 volatile boolean flag;  
 void setup()   
 {  
  pinMode(ledPin, OUTPUT);  
  pinMode(inputPin, INPUT_PULLUP);  
  goToSleep();  
 }  
 void loop()   
 {  
  if (flag)  
  {  
   doSomething();  
   flag = false;  
   goToSleep();  
  }  
 }  
 void setFlag()  
 {  
  flag = true;   
 }  
 void goToSleep()  
 {  
   set_sleep_mode(SLEEP_MODE_PWR_DOWN);  
   sleep_enable();  
   attachInterrupt(0, setFlag, LOW); // pin D2  
   sleep_mode(); // sleep now  
   // Now asllep until LOW interrupt, then..  
   sleep_disable();  
   detachInterrupt(0);  
 }  
 void doSomething()  
 {  
  for (int i = 0; i < 20; i++)  
  {  
   digitalWrite(ledPin, HIGH);  
   delay(200);  
   digitalWrite(ledPin, LOW);  
   delay(200);  
  }  
 }  

    A primeira coisa a observar é que o exemplo usa algumas funções que estão definidas na biblioteca avr/sleep.h. Assim como a biblioteca avr/power.h que foi usada antes, essa biblioteca não faz parte do núcleo do Arduino. Trata-se de uma biblioteca destinada à família AVR de microcontroladores.

   Depois de definir os pinos que foi usado, é definido uma variável do tipo volatile para permitir que a ISR se comunique com o resto do sketch.

    A função setup configura os pinos e então chama a função goToSleep. Essa função define o tipo de modo de sono, que, no caso, é SLEEP_MODE_PWR_DOWN. Esse modo é o que economiza mais energia, e faz sentido portanto, usá-lo.

    A seguir, é necessário fazer a habilitação de dormir chamando sleep.enable. Ao chamá-la, o microcontrolador não adormece. Antes disso, é preciso associar uma rotina de serviço de interrupção (ISR) à interrupção 0 (pino D2) de modo que o Arduino possa acordar quando chegar o momento.

  Depois de definir a ISR, chamamos sleep_mode(), que realmente faz adormecer o microcontrolador. Quando ele volta a acordar, a ISR é executada e, em seguida, o sketch continua a partir da linha seguinte a goToSleep. Essa, por sua vez, faz a desabilitação de dormir chamado disable_sleep e desfaz a associação da ISR com a interrupção. Assim, a ISR não poderá ser chamada novamente até que o sketch cloque de novo o microcontrolador para dormir.

    Quando ocorre uma interrupção em D2, a ISR simplesmente ativa uma variável sinalizadora "flag" que é testada pela função loop. Lembre-se de que, em uma ISR, o uso da função delay e outras não funciona corretamente. Portanto, a função loop deve monitorar a variável flag até que ela seja ativada e então chamar a mesma doSomething que foi usada no exemplo Narcoleptic. Depois de realizar a ação, a variável flag é desativada e o Arduino é colocado de volta para dormir.

Fonte: Programação com Arduino Vol 2 - Simon Monk

Nenhum comentário:

Postar um comentário