Como 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()

 

Sobre Fábio dos Reis (1194 Artigos)
Fábio dos Reis trabalha com tecnologias variadas há mais de 30 anos, tendo atuado nos campos de Eletrônica, Telecomunicações, Programação de Computadores e Redes de Dados. É um entusiasta de Ciência e Tecnologia em geral, adora Viagens e Música, e estuda idiomas, além de ministrar cursos e palestras sobre diversas tecnologias em São Paulo e outras cidades do Brasil.
Contato: Website

7 Comentários em Como substituir a função delay() por millis() no Arduino

  1. Alexandre // 17/10/2019 em 8:23 // Responder

    Olá Fábio
    Preciso de ajuda para um projeto de uma biblioteca de Arduino para um motor bldc especial. Séria possível você dar uma consultoria? Obrigado

  2. Bom dia Fabio,
    Gostaria de saber se esses cursos são gratuitos.
    Pois não vi valores dos cursos no site.

    Atts,

    Dierlei

  3. David Augustus // 20/11/2020 em 9:43 // Responder

    irado, top ..

  4. Ola. o primeiro codigo o while esta me retornando o erro na compilacao deste scketh.

    exit status 1
    expected ‘;’ before ‘while’

    podes me dar uma dica do que ocorre?

    • Olá Miguel!
      Você copiou o código do site ou o digitou? Às vezes ocorre erro se for copiado, por conta de codificação de caracteres diferente entre a página web e o editor do Arduino.

  5. Cleyton dos // 29/07/2022 em 12:15 // Responder

    Consegue me ajudar? sou iniciante. Preciso apertar um botão contar 2 segundos e só depois deste tempo acender um led, apagando 2 segundos depois de soltar o botão. Apertar com menos de 2 segundos não acender.

Escreva um comentário

Seu e-mail não será divulgado


*