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

