uma função Arduino bem conhecida é delay()
que faz uma pausa no programa para uma quantidade de milisegundos especificados como parâmetro.
millis()
, por outro lado, é uma função que retorna a quantidade de milisegundos que passaram desde o início do programa.À primeira vista, pode duvidar da utilidade desta função. O fato é que é extremamente útil em muitos cenários, muitas vezes “substituindo” delay()
completamente. Vejamos primeiro como podemos usar millis()
quase exatamente como delay()
.
as questões de tempo estão frequentemente presentes na programação.
usando o atraso do tipo millis() ()
int period = 1000;unsigned long time_now = 0;void setup() {Serial.begin(115200);}void loop() {time_now = millis(); Serial.println("Hello"); while(millis() < time_now + period){//wait approx. ms}}
se você quer que seu código para apenas pausar para 1000 ms no final de cada iteração de loop, o código acima é um pouco bobo. Você pode apenas usar delay(1000)
em vez disso. A única diferença entre o código acima e um código com delay(1000)
no final é que o loop no código acima será executado com bastante precisão uma vez a cada segundo. O loop em um código com delay(1000)
será executado um pouco menos frequente, uma vez que também leva algum tempo para executar Serial.println("Hello")
.
por que utilizar millis() em vez de retardar()?
vamos agora olhar para duas vantagens com millis()
em comparação com delay()
.
Timing preciso
a primeira vantagem que discutiremos é o timing preciso. Em termos de código, abordámos isto no último capítulo. Com millis()
podemos garantir que o ciclo é executado tantas vezes quanto quisermos, independentemente do tempo de execução (obviamente, desde que o tempo de execução seja menos tempo o período desejado). Com delay()
isso não é possível uma vez que não sabemos quanto tempo é a execução em loop.
uma cronometragem precisa como esta é muito útil quando a amostragem em uma determinada frequência ou filtros de execução, entre outras coisas.
Non-bloqueing
The other advantage with millis()
is that it won’t prevent us from running code while “waiting”.Digamos que queremos imprimir ” Olá ” em série de vez em quando, enquanto fazemos outras coisas. Isto não é possível com delay()
uma vez que ele pára o código inteiro. Há uma maneira de fazermos isto.:
int period = 1000;unsigned long time_now = 0;void setup() {Serial.begin(115200);}void loop() {if(millis() >= time_now + period){time_now += period;Serial.println("Hello");} //Run other code}
este pedaço de código é muito semelhante ao primeiro pedaço, exceto que ele não bloqueia o resto do programa quando não imprime sobre Série.
exemplo: um Scheduler simples
vamos escrever um exemplo simples onde criamos um scheduler que imprime certos bits de texto em intervalos diferentes.
#define INTERVAL_MESSAGE1 5000#define INTERVAL_MESSAGE2 7000#define INTERVAL_MESSAGE3 11000#define INTERVAL_MESSAGE4 13000unsigned long time_1 = 0;unsigned long time_2 = 0;unsigned long time_3 = 0;unsigned long time_4 = 0;void print_time(unsigned long time_millis);void setup() {Serial.begin(115200);}void loop() {if(millis() >= time_1 + INTERVAL_MESSAGE1){time_1 +=INTERVAL_MESSAGE1;print_time(time_1);Serial.println("I'm message number one!");} if(millis() >= time_2 + INTERVAL_MESSAGE2){time_2 +=INTERVAL_MESSAGE2;print_time(time_2);Serial.println("Hello, I'm the second message.");} if(millis() >= time_3 + INTERVAL_MESSAGE3){time_3 +=INTERVAL_MESSAGE3;print_time(time_3);Serial.println("My name is Message the third.");} if(millis() >= time_4 + INTERVAL_MESSAGE4){time_4 += INTERVAL_MESSAGE4;print_time(time_4);Serial.println("Message four is in the house!");}}void print_time(unsigned long time_millis){Serial.print("Time: ");Serial.print(time_millis/1000);Serial.print("s - ");}
eis como se parecem os primeiros 60 segundos do monitor serial:
esta é uma maneira agradável e fácil de sincronizar as execuções em seu código. Você é capaz de executar outro código simultaneamente também.
micros() e transbordamento
assim como delay()
tem uma versão microssegundo chamada delayMicroseconds()
, millis()
tem micros()
. Se você precisar de uma melhor resolução, micros()
pode ser o caminho a seguir.
no entanto, esteja ciente de que micros()
irá transbordar após aproximadamente 70 minutos, em comparação com os 50 dias de millis()
. Isto significa que os valores de retorno das funções começarão de novo a partir de zero.
mais importante ainda: para saber como evitar a questão do transbordamento, leia este post no blog.
resumo
millis()
e micros()
são realmente funções úteis para usar quando se lida com tarefas de tempo. Se você não está ciente destes, você pode acabar usando delay()
em vez disso, o que nem sempre vai funcionar tão bem (se em tudo).
para mais dicas de Arduino & tricks, confira nossa categoria de blog Arduino tutoriais. Fique atento para mais conteúdo relacionado com o Arduino no futuro também!