Bóson Treinamentos em Ciência e Tecnologia

Como substituir a função delay() por millis() no Arduino

Substituir a função delay por millis no Arduino

Substituir a função delay() por millis() no Arduino

Uma das funções mais conhecidas e utilizadas em programação para Arduino é a função delay(), que permite pausar o programa por um período de tempo especificado, na forma de um parâmetro com o valor em milissegundos desejados.

A função delay() aceita um número inteiro como argumento, o qual representa o tempo em milissegundos que o programa deverá esperar até poder executar a próxima linha de código – ou seja, tempo de pausa.

Por exemplo, para criar uma pausa de 5 segundos você pode simplesmente escrever:

delay(5000);

Porém, apesar de ser muito popular, nem sempre a função delay() é a mais adequada para seu sketch. Um problema sério pode surgir com o emprego dessa função: o Bloqueio de Execução.

Bloqueio de Execução: Ao ser invocada, a função delay() bloqueia a execução do programa, pelo período de tempo especificado, e nenhuma outra instrução pode ser executada durante esse período. Desta forma, enquanto o programa espera o final do delay, ele fica totalmente ocioso.

Desta forma, durante uma chaamda à função delay(), o programa não consegue detectar entrada de sinais, processar dados e nem alterar o status de saída de pinos.

O problema é que muitas vezes precisamos executar rotinas específicas durante esse tempo de pausa.

Para evitar esses problemas, muitas vezes recomendamos empregar a função millis() em lugar da função delay().

A função millis() retorna o número de milissegundos decorridos desde que o programa foi iniciado (ou seja, desde que o Arduino foi ligado).

Esta função permite verificar o relógio do sistema regularmente, de modo que sempre é possível saber o tempo decorrido – e assim calcular intervalos de tempo que podemos pausar, mas sem bloquear a execução de códigos necessários no sketch.

Exemplos

1. Suponha que você queira pausar o programa por um certo período de tempo, como por exemplo 3 segundos. Para fazer isso com delay basta executar a instrução:

delay(3000);

Para realizar a mesma tarefa com millis(), você pode escrever algo como isto:

unsigned long agora = 0;

void setup() {
  Serial.begin(9600);
}

void loop() {

  Serial.println("Mensagem escrita a cada 3 segundos");
  // Criar a pausa de 3 segundos
  agora = millis()
  while(millis() < agora + 3000) {
    // Pausa de 3 segundos. Nada a fazer
  }
}

Como podemos ver, o código é maior e mais trabalhoso, porém realiza a pausa de 3 segundos com muita precisão.

2. Digamos agora que você deseja executar uma instrução por um período de tempo específico, mas sem bloquear a execução de outras funções no programa, como a detecção de interrupções. Por exemplo, acender um LED por 4 segundos e depois apagá-lo, mas ainda assim continuar executando outras tarefas durante esse tempo. Para tal, experimente o código a seguir:

/*
Adaptado do exemplo "Blink without Delay"
Código original em Domínio Público
http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
*/

const int LED = 9;
int estadoLED = LOW;

unsigned long tempoAnterior = 0; // Armazena o último momento em que o LED foi atualizado
const long PERIODO = 4000;

void setup() {
  Serial.begin(9600);
  pinMode(LED, OUTPUT);
}

void loop() {
  unsigned long tempoAtual = millis();

  if (tempoAtual - tempoAnterior >= PERIODO) {
    tempoAnterior = tempoAtual;

    if (estadoLED == LOW) {
      estadoLED = HIGH;
    } 
    else {
      estadoLED = LOW;
    }

    digitalWrite(LED, estadoLED);
  }

  Serial.println("Executado sem interferir no acendimento do LED");
}

Esse código resolve nosso problema de bloqueio do programa, pois é possível executar outras funções enquanto o LED estiver apagado ou aceso pelos 4 segundos determinados. O programa conta o tempo para alterar o estado do LED, e permite que outras rotinas sejam executadas enquanto isso.

Referências

Adafruit: Ditch the Delay

DZone – IoT Zone: Arduino: Using millis() Instead of delay()

 

Sair da versão mobile