No Artigo de hoje que mostrar à vocês um sketch (programa) para Arduino UNO que desenvolvi com objetivo de não utilizar mais a função delay() em meus programas; vamos utilizar a função micros(). Note que não há nada de errado com a função delay(), somente que ela deixa o programa “preso” até que o tempo termine de passar, impedindo de fazer qualquer outra coisa no microcontrolador.

   Desenvolvi um programa utilizando a função micros() com o objetivo de controlar várias coisas ao mesmo tempo, como por exemplo piscar um Led, escrever num LCD e girar um servo-motor, tudo isso sem o programa “se perder”.

  •    O código é baseado no programa/sketch “blinkWithoutDelay.ino“, que vem junto á IDE oficial do Arduino e faz piscar um LED sem utilizar delay().

   Porém antes eu tenho que te alertar: Programação não é copiar-colar, programação não é receita de bolo, programação não é “aqui funcionou ali vai funcionar também”, especialmente em sistemas embarcados. Criei uma forma de eliminar o delay() em meus programas específicos, não quer dizer que vai funcionar em todas as aplicações ou nem mesmo que vá funcionar com você, certo?.

   Outro detalhe: utilizar micros() ou millis() é a melhor forma ou a forma mais segura de programar multi-tarefa no Arduino? certamente NÃO. O melhor de dois mundos seria utilizar interrupções por timer (ex: biblioteca timer1), onde um temporizador interno do ATMEGA328 (chip do Arduino) controla um temporizador que interrompe e chama ações no tempo exato em que elas devem acontecer. Mas não é de interrupções por timer que vamos tratar neste artigo.


   Eu batizei meu sketch de “Delay Function Substitute Arduino”, algo como “Substituto da função delay para Arduino”; o código está hospedado na minha página do GitHub, aqui. Abaixo está o código completo, que eu programei para executar até três (3) tarefas independentes.

O program funciona da seguinte forma:

  • A cada ciclo de máquina o tempo atual (em micros()) é armazenado na variável timet:

  • Cada uma das tarefas a serem executadas está dentro um IF (condicional) controlado por uma variável chamada enterFunction; se enterFunction for false a tarefa não é executada (não chegou seu tempo ainda), e se enterFunction for true a tarefa é executada. Caso seja entrada na função, a variável previousTime pega o valor do tempo atual (em micros()) para reiniciar a contagem.

  • Abaixo é visível o mecanismo que decide por entrar ou não na função (verifica se já chegou a hora). sendo timet o tempo corrente e previousTime o tempo da última entrada na função, subtraindo-se as duas é possível saber se o tempo desejado (escrito na mesma linha) já chegou ou não. Note que 999.990 microssegundos é igual á 0,9999 segundos.

  • Quando o tempo chegar e a variável enterFunction for verdadeira (true), será executada a função desejada, no tempo desejado. O seu código (qualquer que seja) vai entre “”//- – – – – ” e “//- – – – – “.

 

   Rodei alguns testes para ver quanto tempo demora a execução de algumas rotinas simples no Arduino UNO, utilizando meu código (LED em uma tarefa, Serial.Print em outra tarefa e PWM de motor e outra tarefa). Os resultados estão na imagem abaixo.

 

Perceba que ligar/desligar um LED demora 12uS, enquanto usar (setar) PWM demora 336uS e imprimir algo na porta serial demora pouco mais de 1,05mS.

   O que quero ilustrar com isso é que você deve ter cuidado com os processos que coloca em cada tarefa, pois se um processo demorar demais você vai atrasar todos os outros processos.

Isso mostra que tarefas que dependam estritamente do tempo (realimentação/feedback, comunicação WiFi, Bluetooth ou Serial, interrupções, entre outras) devem ser evitadas neste sketch.

   Abaixo eu deixo um vídeo de exemplo, onde programei um sistema físico pêndulo-hélice utilizando esta técnica. A primeira tarefa (1) faz o controle liga-desliga do motor, a segunda tarefa (2) pisca o LED do pino 13 do Arduino e a terceira tarefa (3) mostra informações no console serial da IDE do Arduino.

   O Código completo deste exemplo está disponível neste link no meu GitHub. Este exemplo básico (porém complexo) demonstra a utilização com sucesso de um “multi-tarefa” com Arduino UNO, executando controle de motor, piscando LED e comunicando serial sem utilizar delay() nem interrupções.


Caso você queira comprar materiais e peças para Arduino e eletrônica, utilize um dos links postados aqui. São links de lojas com Aliexpress, eBay, Banggood e ICStation, das quais eu sou parceiro. A cada compra que você faz eu ganho créditos, que ajudam a manter este blog no ar.

Função micros() – controlando várias coisas ao mesmo tempo

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Solve : *
11 + 25 =