Para escapar dos problemas gerados pelo uso da função delay(), uma possível solução é a usar função millis(). Desde a primeira utilização do Arduino, a função delay() é empregada para gerir as instruções em função do tempo, mas o seu maior problema é que ela bloqueia a execução do resto do código. Isso pode ser muito limitante quando se trabalha com diversos componentes (gestão de vários LEDs ou sensores). Veremos neste tutorial como utilizar a função millis() para substituir a função delay().
Descrição da função millis()
A função millis() não toma parâmetros e devolve um valor que representa o número de milissegundos transcorridos desde que o Arduino foi ligado. O valor é do tipo unsigned long (unsigned long, 4-bytes ou 32-bits). O valor máximo a que pode chegar é 4.294.967.295 ou 49 dias.
Obs: Existe também a função micros(), que funciona com o mesmo princípio, mas devolve em microssegundos.
void setup() {} void loop() { Serial.print("Milliseconds since ignition: "); Serial.println(millis()) delay(200); }
Substituir a função delay()
Nos primeiros exemplos do Arduino, usamos a função delay() para executar um bloco de código periodicamente. Contudo, esse não é exatamente o seu propósito, já que a função bloqueia a execução do código. A função millis() é muito mais apropriada para esse objetivo.
Voltemos ao exemplo Blink. Usamos a função delay() para piscar um LED a cada 200 milissegundos.
void setup() { pinMode(13,OUTPUT); } void loop() { digitalWrite(13,HIGH); delay(200); digitalWrite(13,LOW); delay(200); }
Para substituir este código por uma estrutura com milis(), a ideia é criar uma variável para guardar na memória, a cada iteração, o valor de tempo decorrido e depois compará-lo com o valor de tempo atual. A cada intervalo, invertemos o estado do LED com o operador “! “.
unsigned long currentTime=0; unsigned long previousTime=0; bool ledState=LOW; void setup() { Serial.begin(9600); pinMode(13,OUTPUT); } void loop() { currentTime=millis(); if((currentTime-previousTime)>200){ previousTime=currentTime; ledState=!ledState; digitalWrite(13,ledState); Serial.print(F("LED State : "));Serial.println(ledState); } }
Recriamos o exemplo Blink acrescentando a capacidade de executar o código ainda que o intervalo de tempo não tenha transcorrido. Neste código, o LED liga e desliga a cada 200ms.
Definir diferentes intervalos de tempo
Caso queira criar ciclos ON e OFF com diferentes durações, é possível alterar o intervalo de tempo em função do estado do LED.
unsigned long currentTime=0; unsigned long previousTime=0; unsigned long interval,interval1=200, interval2=1000; bool ledState=LOW; void setup() { Serial.begin(9600); pinMode(13,OUTPUT); } void loop() { currentTime=millis(); if(ledState){ interval=interval2; }else{ interval=interval1; } if((currentTime-previousTime)>interval){ previousTime=currentTime; ledState=!ledState; digitalWrite(13,ledState); Serial.print(F("LED State : "));Serial.println(ledState); } }
Este código permite acender o LED durante 200ms a cada segundo.
Para ir além
Vale observar que a função millis() utiliza temporizadores internos do microcontrolador e pode ser perturbada pelo uso de interrupções ou de outras bibliotecas.
Para uma programação mais avançada, é possível usar bibliotecas de gestão de temporizadores (Timer.h,Timer2.h, TimerOne.h, etc.)
Também é possível manipular os registros do microcontrolador para configurar os temporizadores internos.
Fontes
- Referência Arduino sobre a função millis()
- O famoso exemplo Blink without delay
- Programar com o Arduino
Retrouvez nos tutoriels et d’autres exemples dans notre générateur automatique de code
La Programmerie