Veja neste rápido tutorial como controlar intervalos de tempo de forma simples com Arduino, executando tarefas de forma “paralela” sem interromper o processamento .
É muito comum em projetos com Arduino a necessidade de realizarmos certas tarefas em intervalos específicos ao mesmo tempo que executamos outras operações.
Por exemplo: Ler um sensor ou escrever um texto no LCD enquanto fazemos piscar um LED.
No entanto, sabemos que a plataforma Arduino não é boa nesse quesito pois não suporta o uso de threads. Dessa forma lançamos mão de artifícios usando a função millis ou então apelamos para o uso de interrupções.
A solução usando o millis funciona bem mas não é a ideal devido às conhecidas limitações desse comando, além de deixar o seu código pouco legível com muitas variáveis e controles.
Felizmente existem algumas bibliotecas que encapsulam em classes toda essa complexidade, oferecendo uma interface simples de ser utilizada. É o que vamos ver neste tutorial, deixando o conceito de interrupções para uma próxima oportunidade.
O projeto
Para os nossos testes, vamos realizar a seguinte experiência:
- Três LEDS (R – G – Y) ligados ao Arduino;
- O led verde vai piscar a cada 2 segundos, o amarelo a cada 4 segundos e o vermelho a cada 10 segundos;
- A mesmo tempo, ou seja, de forma “paralela”, vamos fazer uma contagem regressiva recursiva de 10 até 1 no monitor serial.
Material necessário
- Placa Arduino, ESP*, Attiny* ou qualquer outra compatível com a plataforma Arduino;
- 3 LEDS de cores variadas;
- 3 resistores 220 Ohms.
Software Necessário
Essa biblioteca permite, de forma transparente e simplificada, estabelecer intervalos de tempos para realização de tarefas sem poluir muito seu código. Ela utiliza o millis para seus cálculos e possui apenas dois métodos:
- begin → Inicializa o timer.
- onTimeout → Testa se o intervalo especificado foi atingido. Opcionalmente pode-se indicar uma função para ser executada.
Esquema de montagem
Vídeo demonstração
O Sketch
#include <Timing.h> //Definição dos pinos dos LEDs #define greenLed 5 #define yellowLed 6 #define redLed 7 // Um timer para cada LED e um para o contador Timing timerGreen; Timing timerYellow; Timing timerRed; Timing timerContador; int contador = 11; void setup(void) { //Inicializações pinMode(greenLed,OUTPUT); pinMode(yellowLed,OUTPUT); pinMode(redLed,OUTPUT); timerGreen.begin(0); timerYellow.begin(0); timerRed.begin(0); timerContador.begin(0); Serial.begin(9600); } void loop(void) { if (timerGreen.onTimeout(2000)) { // Acende/Apaga led Verde a cada 2 segundos digitalWrite(greenLed,!digitalRead(greenLed)); } if (timerYellow.onTimeout(4000)) { // Acende/Apaga led Amarelo a cada 4 segundos digitalWrite(yellowLed,!digitalRead(yellowLed)); } if (timerRed.onTimeout(10000)) { // Acende/Apaga led Vermelho a cada 10 segundos digitalWrite(redLed,!digitalRead(redLed)); } if (timerContador.onTimeout(1000)) { //Imprime a contagem regressiva no monitor serial a cada 1 segundo Serial.println((contador > 1) ? --contador : contador = 10); } }
Outras alternativas
- ArduinoThread – Simula ao uso de Threads permitindo “esquedular” tarefas com tempos variáveis entre elas;
- Timing Libraries – Uma lista de bibliotecas com o tema “Controle de Tempo”;
- SimpleTimer – Uma das primeiras libs nesse sentido.
- ElapsedMillis – Esta lib usa uma técnica interessante: Cria um tipo de variável que incrementa automaticamente. Dessa forma é só compará-la com o intervalo desejado. Dica do amigo Rui Viana do Laboratório de Garagem
Referências
- Tutorial Adafruit – Excelente tutorial sobre Multi-tasking e millis no Arduino;
- Blink sem delay – Sketch de exemplo do site oficial do Arduino
Conclusão
A biblioteca que analisamos é muito simples e apenas encapsula em uma classe o que já vimos em vários sites por aí . No entanto, sua vantagem é o pouco espaço em memória utilizado e a facilidade de uso.
Espero ter sido útil.
Até a próxima…
parabéns pelo post, material muito didatico
Muito Obrigado Uigor!
Cintra, muito bacana o tutorial, mas fiquei com uma duvida, como faço para alternar os intervalos de acionamento para o mesmo pino, tipo time_on/time_off
Tiago, obrigado!
Pelo que entendi, você quer ligar e desligar o timer.
Essa library é bem limitada e não possui uma opção para desabilitar o timer.
Você teria que improvisar e criar uma variável para testar se o timer está habilitado ou não.
Mas existe outra library que possui mais opções de controle
https://github.com/jrullan/neotimer
Com ela, você pode dar um stop e restart no timer
Espero ter ajudado.
Abraço
Cintra muito obrigado pela pela resposta, boa dica dessa biblioteca, mas na verdade estou tentando implementar um código usando millis(), para acionar uma bomba d’água por 2 minutos e aguardar 10 minutos por exemplo. Como vc mesmo disse, o millis() deixa o cogido meio sujo para implementar, gostei dessa lib Neotimer, pois posso limitar o numero de ciclos. mas ela não tem uma opção para se utilizar 2 timers por exemplo.
Até cogitei a possibilidade de inserir no arquivo.h essa opção, mas ainda não tenho tanto domínio.
Abraços
Muito bom o material, mas não estou conseguindo baixar essa biblioteca, teria outro link para mandar?
Olá Samuel, só tenho esse link mesmo. Use o botão CLONE OR DOWNLOAD.
Depois no Arduino: Incluir ZIP
Existe outra biblioteca muito boa para isso:
https://github.com/jrullan/neotimer