Como piscar dois Led’s simultaneamente com tempos diferentes sem usar delay no Arduino
Fala pessoal, tudo certo? Bom, neste post eu vou colocar a resposta do desafio postado no instagram @blogdarobotica (Link: https://www.instagram.com/p/CNdW3hyjQ-f/). Se você não viu, então deixo logo abaixo o vídeo do desafio:
Existem diversas formas de conseguir o resultado mostrado acima e o mais interessante desse desafio foi olhar as respostas em que foram sugeridas formas diferentes de como programar. E sim, cada pessoa pensa e programa de uma forma diferente e o bacana da programação é justamente isso: Diferentes formas de se chegar a um objetivo, no entanto, vale ressaltar que algumas formas vão ser mais eficientes que outras.
Abaixo vou mostrar a forma que eu programei, não significa que seja a melhor, porém deixo aí para vocês estudarem e compararem com o código de vocês e a partir daí novas soluções (melhores) podem sair.
Código Fonte:
/*
----------- Resposta do #Desafio 1 --------------
=================================================
== BLOG DA ROBOTICA - www.blogdarobotica.com ==
=================================================
Autor: Kleber Bastos
E-mail: contato@blogdarobotica.com
Fanpage: facebook.com/blogdarobotica
YouTube: youtube.com/user/blogdarobotica
Instagram: instagram.com/blogdarobotica
*/
//Definições de variáveis
#define led_1 5 //pino em que o led 1 ficará
#define led_2 6 //pino em que o led 2 ficará
//Declaração de variáveis
unsigned long tempoAtual; //variável que irá receber o tempo em que o arduino está ligado em milissegundos. Long armazenam valores maiores que o tipo int e o unsgined significa que estamos desconsiderando valores negativos, fato que aumenta a capacidade de armazenamento do tipo long
long tempoDecorrido = 0; //variável que contará o tempo decorrido para o led 1
long tempoDecorrido2 = 0; //variável que contará o tempo decorrido para o led 2
long tempoLed_1 = 1000; //tempo em milissegundos que quero que o led 1 pisque. Pode ser alterado para o tempo que desejar
long tempoLed_2 = 100; //tempo em milissegundos que quero que o led 2 pisque. Pode ser alterado para o tempo que desejar
//Condições iniciais do programa
void setup() {
pinMode(led_1, OUTPUT); //seto a porta do led 1 como saída
pinMode(led_2, OUTPUT); //seto a porta do led 2 como saída
}
//Loop
void loop() {
tempoAtual = millis(); //atribuo o tempo (em milissegundos) que o arduino está ligado na variável tempoAtual
efeito1(); //chamo a função efeito1() que é responsável pelo piscar do led 1
efeito2(); //chamo a função efeito2() que é responsável pelo piscar do led 2
}
//Construção da função 1 - Função que faz o led piscar 1000 milissegundos
void efeito1() {
if (tempoAtual - tempoDecorrido > tempoLed_1) { //verifica se passou 1000 milissegundos e se sim
tempoDecorrido = tempoAtual; //subsitui o valor que já passou pelo tempo atual
digitalWrite(led_1, !digitalRead(led_1)); //escreve em led_1 o estado inverso em que ele se encontra, ou seja, se está ligado ele desliga e se estiver desligado o led ligará
}
}
//Construção da função 2 - Função que faz o led piscar 100 milissegundos
void efeito2() {
if (tempoAtual - tempoDecorrido2 > tempoLed_2) { //verifica se passou 100 milissegundos e se sim
tempoDecorrido2 = tempoAtual; //subsitui o valor que já passou pelo tempo atual
digitalWrite(led_2, !digitalRead(led_2)); //escreve em led_2 o estado inverso em que ele se encontra, ou seja, se está ligado ele desliga e se estiver desligado o led ligará
}
}
Algumas observações:
A função millis() é responsável por contar quanto tempo a placa está ligada (em milissegundos) executando aquele sketch (programa) e ela tem um limite, ou seja, depois de 50 dias de programa executando sem que a placa desligue haverá um overflow da variável (vai exceder o limite que ela suporta) e quando isso acontecer o tempo voltará a ser contado do zero. Por esse motivo não usamos millis() como um relógio para contar tempos longos que ultrapasse o limite dos 50 dias. Para fazer isso a solução ideal para tempo é a utilização do módulo RTC.
No nosso caso precisamos apenas contar o tempo decorrido de 1000 milissegundos e 100 milissegundos, logo podemos utilizar a função millis() tranquilamente que mesmo que o arduino fique ligado mais de 50 dias não afetará a execução porque a variável tempoAtual vai zerar e consequentemente as outras variáveis tempoDecorrido e tempoDecorrido2 serão atualizadas.
Por que não usar delay?
Pelo que vi tiveram pessoas que resolveram o desafio usando delay, mas quando nós utilizamos o delay significa que o programa fica parado naquela linha esperando até que o tempo definido dentro do delay passe, ou seja, se você tiver outras coisas para serem executadas posteriormente não vai acontecer porque o programa fica parado. Já com millis não, o programa executa de maneira sequencial e fica verificando se já passou o tempo que eu defini e se não passou ele segue fazendo as coisas que estão nas linhas abaixo. Só depois de já ter decorrido o tempo especificado é que vai entrar no condicional e fazer o que tá lá dentro. Então sempre que possível use millis() no lugar de delay. =)
Ah, outra coisa bem legal nesse código é essa parte:
digitalWrite(led_2, !digitalRead(led_2)); //escreve em led_2 o estado contrário em que ele se encontra
E essa linha acima substitui isso:
if ( digitalRead(led_2) == HIGH){ //se o led estiver ligado
digitalWrite(led_2, LOW); //desligue
}
else { //se não
digitalWrite(led_2, HIGH); //ligue
}
Tá vendo como existem formas diferentes de fazer a mesma coisa? Legal né =P
Obrigado a todos que participaram do desafio e espero que tenham aprendido coisas novas.
Até a próxima! Att. Kleber Bastos.
Você precisa fazer log in para comentar.