Como usar a função Millis com Arduino
Você já deve ter ouvido falar no millis, uma função muito utilizada em programas mais avançados envolvendo Arduino, mas para que serve o millis?
O millis() é uma função do Arduino que retorna o número de milisegundos que se passaram desde que o programa atual começou a rodar, ou seja: rodou o programa, o “millis” começa a contar.
Até aí ok, mas por qual motivo eu deveria usar o millis nos meus programas?
Comparativo Millis x Delay
A função delay() é a forma mais comum de se aguardar algum tempo nos programas envolvendo Arduino para realizar alguma tarefa. Exemplo: Quero manter um led aceso por 5 segundos e depois desligar. Então no programa eu ligo o led, aguardo 5 segundos (usando a função delay) e depois desligo. Nesse intervalo de 5 segundos, praticamente toda a execução do programa pára aguardando o final desse tempo, ou seja, não consigo fazer nada nesse intervalo.
Seria como se, por exemplo, eu acordasse as 9 da manhã e tivesse uma reunião marcada para as 14 h. Se eu usasse o “delay” na minha vida, eu olharia o relogio as 9 h e ficaria sentado no sofá sem fazer nada até as 14 h, quando seria a hora da minha reunião. Aí sim eu poderia sair e fazer as minhas tarefas.
Se por outro lado eu usasse o “millis”, isso significa que eu poderia acordar as 9 h, olhar o relógio de vez em quando para ver se já são 14 h e continuar realizando as minhas tarefas normalmente até esse horário. Percebeu a diferença?
O millis() no Arduino
No Arduino então eu posso usar o millis para checar se o tempo desejado já foi atingido, sem que eu precise parar as outras atividades. Posso por exemplo piscar um led em intervalos de 5 segundos sem deixar de ler os dados de um sensor, ou enviar dados para um display durante uma contagem de tempo qualquer.
Vamos usar esse exemplo do led com o circuito abaixo, onde usamos um Arduino Uno e um led conectado na porta digital 4:
O nosso programa com delay ficaria assim, piscando o led em intervalos de 1 segundo:
//Programa: Pisca led usando delay //Autor: Arduino e Cia //Pino do led int pinoLed = 4; //Estado do led: aceso ou apagado int estadoLed = LOW; //Intervalo de tempo entre acionamentos do led (em milisegundos) const long intervalo = 1000; void setup() { //Define o pino do led como saida pinMode(pinoLed, OUTPUT); } void loop() { //Inverte o estado do led if (estadoLed == LOW) { estadoLed = HIGH; } else { estadoLed = LOW; } //Acende ou apaga o led digitalWrite(pinoLed, estadoLed); //aguarda o intervalo especificado para continuar o programa delay(intervalo); }
No caso de usarmos millis, temos uma variável que armazena o valor do tempo atual (currentMillis) e outra que é alterada conforme o intervalo é atingido (previousMillis). Essa variável é atualizada constantemente conforme o led é aceso:
//Programa: Pisca led usando millis //Autor: Arduino e Cia //Pino do led int pinoLed = 4; //Estado do led: aceso ou apagado int estadoLed = LOW; //Armazena o valor (tempo) da ultima vez que o led foi aceso unsigned long previousMillis = 0; //Intervalo de tempo entre acionamentos do led (em milisegundos) const long intervalo = 1000; void setup() { //Define o pino do led como saida pinMode(pinoLed, OUTPUT); } void loop() { unsigned long currentMillis = millis(); //Verifica se o intervalo já foi atingido if (currentMillis - previousMillis >= intervalo) { //Armazena o valor da ultima vez que o led foi aceso previousMillis = currentMillis; //Inverte o estado do led if (estadoLed == LOW) { estadoLed = HIGH; } else { estadoLed = LOW; } //Acende ou apaga o led digitalWrite(pinoLed, estadoLed); } }
Apesar do programa com millis ter ficado maior (e um pouco mais complexo), temos a opção de realizar outras tarefas enquando o tempo não é atingido, ou seja, o loop continua funcionando durante o intervalo de 1 segundo que nós colocamos.
Mais uma aplicação com millis()
Nesse outro exemplo, vamos usar dois leds, com cada um piscando em um intervalo: o vermelho a cada 2 segundos e o verde a cada 1 segundo. Adicionei ao circuito um led verde na porta digital 6.
Usei o programa anterior como base e dupliquei as variáveis de intervalo e de armazenamento do tempo em que o led foi acionado:
//Programa: 2 Leds com millis //Autor: Arduino e Cia //Pinos dos leds int pinoLedVermelho = 4; int pinoLedVerde = 6; //Armazena o estado dos leds int estadoLedVermelho = LOW; int estadoLedVerde = LOW; //Armazena o valor (tempo) da ultima vez que o led foi aceso unsigned long previousMillisLedVermelho = 0; unsigned long previousMillisLedVerde = 0; //Intervalo de tempo entre acionamentos do led (em milisegundos) const long intervaloLedVermelho = 2000; const long intervaloLedVerde = 1000; void setup() { //Define o pino do led como saida pinMode(pinoLedVermelho, OUTPUT); pinMode(pinoLedVerde, OUTPUT); } void loop() { unsigned long currentMillis = millis(); //Verifica se o intervalo do Led Vermelho já foi atingido if (currentMillis - previousMillisLedVermelho >= intervaloLedVermelho) { //Armazena o valor da ultima vez que o led foi aceso previousMillisLedVermelho = currentMillis; //Inverte o estado do led if (estadoLedVermelho == LOW) { estadoLedVermelho = HIGH; } else { estadoLedVermelho = LOW; } //Acende ou apaga o led digitalWrite(pinoLedVermelho, estadoLedVermelho); } //Verifica se o intervalo do Led Verde já foi atingido if (currentMillis - previousMillisLedVerde >= intervaloLedVerde) { //Armazena o valor da ultima vez que o led foi aceso previousMillisLedVerde = currentMillis; //Inverte o estado do led if (estadoLedVerde == LOW) { estadoLedVerde = HIGH; } else { estadoLedVerde = LOW; } //Acende ou apaga o led digitalWrite(pinoLedVerde, estadoLedVerde); } }
O único inconveniente da função millis() é que ela “só” dura 50 dias. Depois disso, o contador é zerado.
Gostou dos exemplos de uso da função millis com Arduino? Então confira outros posts sobre Arduino aqui mesmo no blog!
[…] First viewed here […]
boa postagem. Agradeço. Mas como colocar o millis para contar tempo? Por exemplo, num sensor de presença,ou LDR, eu passo a mão cai a luz, tempo depois passo a mão de novo e interrompo a iluminação. Como calcular este intervalo de tempo? Obg
Oi Marcelo,
Pelo que estou entendendo você quer, no caso do LDR, que ele só desligue se realmente estiver escuro, é isso? Para evitar uma acionamento “acidental”?
Abraço!
Adilson
Olá! Boa Tarde! Excelente matéria sobre funções diferentes no “Millis”. Sou iniciante em arduino e estou sempre criando aplicações, mas tenho tido dificuldades em encontrar literatura sobre o “Millis”. Por acaso vocês possuem apostilas com exemplos para serem vendidas? Grato. Lincoln.
Oi Lincoln,
Obrigado. No momento não temos apostilas para venda, mas fique de olho no site pois em breve teremos novidades.
Abraço!
Adilson
Desculpe meu último comentário incompleto… após armazenar os valores de millis e subtraí-los, eu preciso fazer isso sucessivamente, ou seja, a cada momento que meu pino fica no estado high, recalcula uma nova diferença entre o último millis lido com o novo millis.
O projeto é medir vazão de um hidrômetro, que emite um pulso a cada 100 litros de água, então minha ideia é medir o tempo entre os pulsos para calcular a vazão.
Obrigado.
Oi Ivan
Vc já resolveu a questão acima apresentada?. Espero que sim. Resolvi um problema parecido faz algum tempo. Felicidades…