Bom dia.

Preciso de ajuda na função millis.

Preciso fazer um código com as características abaixo:

- se condição 1 for satisfeita

- conta um intervalo de tempo 1 pré definido

- se condição 2 for satisfeita

- conta um intervalo de tempo 2 pré definido

- se condição 3 for satisfeita

- conta um intervalo de tempo 3 pré definido

- executa uma rotina (o tempo até chegar na execução dessa rotina, se satisfeita as 3 condições acima, deve ser a soma do tempo 1 + tempo 2 + tempo 3).

Estou tentando assim mas conta apenas um intervalo antes de executar a rotina.

unsigned long previous_millis1 = 0;
unsigned long previous_millis2 = 0;
unsigned long previous_millis3 = 0;
const long interval1 = 2000;
const long interval2 = 2000;
const long interval3 = 2000;

void loop() {


if (analogRead(condição 1) < comparação 1){

unsigned long current_millis1 = millis();
if (current_millis1 - previous_millis1 >= interval1) {
previous_millis1 = current_millis1;

if (analogRead(condição 2) < comparação 2){

unsigned long current_millis2 = millis();
if (current_millis2 - previous_millis2 >= interval2) {
previous_millis2 = current_millis2;

if (analogRead(condição 3) < comparação 3){

unsigned long current_millis3 = millis();
if (current_millis3 - previous_millis3 >= interval3) {
previous_millis3 = current_millis3;
}

}

}

}

if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
digitalWrite(saida1, ledState);
}
}
}

Agradeço quem puder ajudar.

Exibições: 608

Responder esta

Respostas a este tópico

Durante o intervalo de tempo seu programa executa algo e/ou verifica outras condições ou ele precisa esperar esse tempo ?

Se executa algo durante esse tempo:

if(condicao1)

{

     unsigned long previous_millis1 = millis();

     while(millis() - previous_millis1  <= interval1)  //Executa o bloco durante o período de interval1

     {

            //AÇÕES REFERENTES AO INTERVALO 1

     }

}

Se precisa apenas aguardar o intervalo:

if(condicao1)

{

     unsigned long previous_millis1 = millis();

     while(millis() - previous_millis1  <= interval1);  //Esperar o tempo do intervalo1

     //CONTINUAÇÃO DO COD

}

Agora apenas trata-se de concatenar os demais intervalos de forma adequada com o que desejas.

Obrigado pela resposta Joao Vitor.

Escrevi a sua sugestão e funcionou.

void loop() {


if (condição1){

unsigned long previous_millis = millis();
while(millis() - previous_millis <= interval1); //Executa o bloco durante o período de interval1


if (condição2){


unsigned long previous_millis = millis();
while(millis() - previous_millis <= interval2); //Executa o bloco durante o período de interval2

if (condição3){


unsigned long previous_millis = millis();
while(millis() - previous_millis <= interval3); //Executa o bloco durante o período de interval3


if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("tempo: ");
unsigned long tempo = millis();
lcd.println(tempo);
digitalWrite(saida_1, ledState);

}

}

}
}

Para o caso de interval1 =  interval2  =  interval3 = 2000, o intervalo de atraso ficou em 6000 (está certinho).

Porém reparei que na primeira passada o tempo medido é de 6021, na segunda passada é de 12030 e assim por diante abaixo:

18041

24051

30061

36071

42081

48091

54102

60113

Nota-se um erro em cada passada que tem a tendência de ir aumentando e prejudicar o funcionamento da aplicação. Vc sugere alguma correção para esse erro?

Obrigado.

Isso ocorre devido a duração das operações a serem realizadas e do tempo que a própria função leva para obter o valor da função millis() e efetuar a comparação.

Por exemplo, se a última ação do ultimo intervalo dura 500ms, se ela for iniciada em 5800ms, ela terminará em 6300ms. Dessa forma passa em 0,3s o estabelecido (6s totais), para então não atender mais as condições.


Você quer uma forma de interromper a atividade em execução caso atinja os 6s tendo ou não finalizado essa tarefa ? Um WatchDog Timer, talvez ?

Ou, pra ver se ameniza essa diferença de tempo, faça o teste usando micros(). Assim você terá uma comparação de tempo com maior precisão.

1s = 1.000.000 microsegndos

Usando o micros() o erro continua bem perceptível.

Não existe uma forma de após a conclusão das ações, "resetar" o contador? Daí a próxima vez que entrar na condição o tempo começaria do zero. É possível?

Digo usando o código com o recurso while.

Se refere ao valor printado no final (18041, 24051, 30061...) ?

Coloque pra printar a diferença entre o previous_millis1 , que é quando inicia o processo e verificação dos intervalos e um millis() assim que tudo termina de ser executado.

Exemplo:

Serial.print("Duração: ");

Serial.print(((millis() - previous_millis1)/1000),2);  //Convertido pra segundo e 2 casas decimais

Serial.println(" segundos");

O resultado será, em segundos, aproximadamente a soma dos 3 intervalos. Muito possivelmente poderá passar um pouco. Como 6.15 , 6.25 segundos...

Fiz assim:

void loop() {

if (condition1){

unsigned long previous_millis = millis();
while(millis() - previous_millis <= interval1);

if (condition2){

unsigned long previous_millis = millis();
while(millis() - previous_millis <= interval2);

if (condition3){

unsigned long previous_millis = millis();
while(millis() - previous_millis <= interval3);

if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("tempo: ");
unsigned long tempo = millis();
lcd.println(tempo);
digitalWrite(saida_1, ledState);

}
}
}
}

Para o caso de intervalo1 = intervalo2 = intervalo3 = 2000, o intervalo de atraso foi de 6000 (está certo).

Eu estou usando a função millis () junto com ciclos while. Isso bloqueia o processador?

Eu gostaria que não bloqueasse. Eu queria que fosse como o exemplo blink withou delay.

Obrigado.

Sim, bloqueia.

Durante esse tempo você quer que ele continue executando outras atividades?

As funções do final somente podem ser executadas após o término do(s) intervalos ?


Sobre a inversão de valor no ledState , você pode substituir seu if/else  por  ledState  = !ledState;

O Operador significa uma inversão do valor booleano, fazendo o papel de uma porta NOT. Por exemplo, se 0, passa para 1; se true, passa pra false; se LOW, vira HIGH e vice-versa.

Sim preciso executar outras atividades durante o intervalo de tempo.

Sim as funções serão executadas somente após transcorridos os intervalos de tempo.

Sobre o !ledState ok.

Como funcionam as suas condicionais ?

Elas podem acontecer em qlqr ordem ou possuem dependências entre si? Por exemplo, a 2 pode acontecer sem que a 1 ocorra ?  Ou a 2 somente pode acontecer se antes a 1 ocorrer e se manter verdadeira ?

As condicionais são iguais. Trata-se da verificação de duas entradas analógicas três vezes com um intervalo de tempo entre elas.

- Verifica uma vez, aguarda um tempo;
- Se verdadeiro verifica de novo e aguarda mais um tempo;
- Se verdadeiro verifica uma terceira vez;
- Se verdadeiro executa uns acionamentos.

Escrevi o código assim:

unsigned long previous_millis = 0;
const long interval = 2000;


void loop() {

 if (condition1){
                                                                              
   unsigned long current_millis = millis();
   if (current_millis - previous_millis > interval){
     previous_millis = current_millis;  
        
   if (condition2){

     unsigned long current_millis = millis();
     if (current_millis - previous_millis > interval){
       previous_millis = current_millis;  
   
     if (condition3){

                                  
       lcd.clear();
       lcd.setCursor(0, 1);
       lcd.print("tempo: ");
       unsigned long tempo = millis();
       lcd.println(tempo/1000);
       

     }
   }
   }
     }
 }

}

Como const long interval = 2000 e após satisfeita as condições 1, 2 e 3 não deveria ter um intervalo de 4 segundos?

Ocorre que está executando as ações após a terceira condição ser satisfeita em 2 segundos (contando apenas 1 intervalo).

Preciso que os intervalos sejam cumulativos.

Agradeço a ajuda.

Boa tarde.

Dando um feedback.

Consegui meu intento através da referência abaixo:

https://youtu.be/9gG_Vc2g6X8

Obrigado a todos.

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço