fbpx

Software Timer

Em várias situações, é necessário de certa forma, a manipulação do tempo em micro controladores. O jeito mais fácil é pelas funções básicas (delay e derivados), porém, normalmente, estas funções travam o micro controlador, e com isto, você é incapaz de ler botões ou algo do tipo enquanto o delay não acabar. Isto além de gerar terríveis problemas nos mais variados projetos, não é uma pratica saudável. Neste tutorial, vamos aprender sobre o OS_TIMER do ESP8266, este timer é baseado no software do ESP8266 e o limite inferior é 1mS e máximo de ~2 horas. Este software timer não é aconselhado para projetos em que o tempo é crítico. Apesar de nossos testes darem certa confiança, por ele ser baseado em software, alguns fatores podem atrasa-lo em alguns mS, tome cuidado.

 

Demonstrando a diferença

Neste exemplo apenas para comparação do Software Timer, usaremos um exemplo que acende 3 LEDs a cada 1 segundo e enquanto isso, ficaremos  enviando dados na Serial para mostrar o funcionamento do código. Antes de ir para o software timer, testem este código abaixo no ESP8266 e veja no Serial Monitor como é o recebimento de informações.

Neste código, estamos usando Delay para fazer o acionamento simples dos LEDs. Você perceberá que só irá aparecer mensagens a cada 4 Segundos.

long x;//Variavel para mostrar o desenvolvimento do codigo no Serial Monitor.

void setup()
{
   pinMode(D1, OUTPUT);//Define D1 como Saida.
   pinMode(D2, OUTPUT);//Define D2 como Saida.
   pinMode(D3, OUTPUT);//Define D3 como Saida.

   Serial.begin(9600);//Inicia a comunicaçao Serial para provar que o codigo nao trava.
}

void loop()
{
   led();//Sub rotina para acender os LED`s.

   Serial.println(x++);//Mostra no serial monitor o desenvolvimento do codigo.
}

void led()//Sub rotina para acender os LED`s.
{
   digitalWrite(D1, 1);//Acende o led 1.
   delay(1000);//Aguarda 1 segundo.
   digitalWrite(D2, 1);//Acende o led 2.
   delay(1000);//Aguarda 1 segundo.
   digitalWrite(D3, 1);//Acende o led 3.
   delay(1000);//Aguarda 1 segundo.
   digitalWrite(D1, 0);//-
   digitalWrite(D2, 0);//-
   digitalWrite(D3, 0);//-Apaga os 3 leds.
   delay(1000);//Aguarda 1 segundo.
}

Após ver que o ESP só pula para a linha debaixo da função led() a cada 4 segundos, percebe-se que o ESP fica travado durante 4 segundos apenas para acender os LEDs, inutilizando totalmente o seu uso para outras coisas.

Agora chega de papo e vamos ao Software Timer.

 

 

Normalmente, na maioria dos casos, as funções de delay travam o código até que o delay se acabe. Ao usar delay(60000), o micro controlador ficará travado por 1 Minuto nesta linha até que o tempo acabe e não fara mais nada. Se desejarmos acender um LED a cada 30 segundos, isto irá gerar muitos problemas usando delay, então, usaremos os Timer’s. O Timer gera uma interrupção no sistema a cada intervalo de tempo e voltara a fazer a sua rotina padrão após terminar suas instruções.

Lembre-se, A rotina de um timer (Interrupção) não pode conter comandos de Delay, Serial e vários outros. A rotina do ISR deve ser a mais breve possível e normalmente usamos flag’s armazenadas na RAM para agilizar o processo e evitar erros internos.

 

Mãos à obra

Componentes necessários

Montando o projeto

 

Veja como ficou nossa montagem:

 

 

Código do projeto

#include <user_interface.h>;//Biblioteca necessaria para acessar os Timer`s.

os_timer_t tmr0;//Cria o Timer. Maximo de 7 Timer's.

volatile byte status;//Variavel armazenada na RAM para Status do LED.
long x;//Variavel para mostrar o funcionamento do Codigo.

void setup()
{
   os_timer_setfn(&tmr0, led, NULL); //Indica ao Timer qual sera sua Sub rotina.
   os_timer_arm(&tmr0, 1000, true);  //Inidica ao Timer seu Tempo em mS e se sera repetido ou apenas uma vez (loop = true)
                                     //Neste caso, queremos que o processo seja repetido, entao usaremos TRUE.

   pinMode(D1, OUTPUT);//Define D1 como Saida.
   pinMode(D2, OUTPUT);//Define D2 como Saida.
   pinMode(D3, OUTPUT);//Define D3 como Saida.

   Serial.begin(9600);//Inicia a comunicaçao Serial.
}

void loop()
{
   leitura();//Sub rotina para processar os LED`s.

   //O codigo irá funcionar normalmente sem que haja delays e acendendo os LED`s no intervalo definido.
   //Para demonstraçao, abra o Serial monitor e voce vera que o codigo continua normalmente.

   Serial.println(x++);//Print para provar que o codigo nao trava. Abra o Serial monitor e veja
                       //que o codigo continua rodando enquanto os LED`s piscam a cada 1 Segundo.
}

void leitura()//Sub rotina para processar os LED`s.
{
   switch (status)
   {
   case(1)://Caso status seja 1, acenda o led 1.
      digitalWrite(D1, 1);
   break;

   case(2)://Caso status seja 2, acenda o led 2.
      digitalWrite(D2, 1);
   break;

   case(3)://Caso status seja 3, acenda o led 3.
      digitalWrite(D3, 1);
   break;

   case(4)://Caso status seja 4, Apague os 3 LED`s.
      digitalWrite(D1, 0);
      digitalWrite(D2, 0);
      digitalWrite(D3, 0);
   break;
   }
}

void led(void*z)//Sub rotina ISR do Timer sera acessada a cada 1 Segundo e mudara o status do LED.
{
   if (status == 4)//Verifica se o maximo foi alcançado para resetar a contagem.
   {
      status = 0;
   }

   status++;
}

 


Entendendo a fundo

Hardware

As ligações são simples, apenas sendo necessário ligar o pino de cada LED em sua correspondente porta, não esquecendo o uso de resistores para limitar a corrente/tensão e também não queimar o LED. O outro pino do LED no GND. Este é o básico para um LED funcionar.

Software

 

-Função os_timer_setfn()

os_timer_setfn(&tmr0, led, NULL);

Esta função atribui uma função sua à rotina do Timer. Neste caso, definimos a nossa função led() ao timer tmr0, que criamos anteriormente.

 

-Função os_timer_arm()

os_timer_arm(&tmr0, 1000, true);

Com esta outra, é definido o tempo do timer e também se irá se repetir (loop). Neste caso, definimos ao timer tmr0, que entre na função anteriormente atribuída, a cada 1000mS. Se você não precisa que isso seja repetido, troque true por false, desativando o loop.

 

Finalizando

Comparando os dois códigos, podemos perceber claramente a diferença entre fazer tarefas com um Timer ou Delay. Enquanto o primeiro código só mostra a mensagem a cada 4 Segundos, o segundo mostra a mensagem diversas vezes ao mesmo tempo que gerencia os LEDs. Você pode usar isso em vários projetos em que é preciso fazer tarefas em tempos definidos, sem travar o resto do sistema com Delay. Dúvidas? Sugestões? Críticas? Comente abaixo!

Privacy Preference Center