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.
Tags:
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...
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.
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 ?
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.
Bem-vindo a
Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)
© 2024 Criado por Marcelo Rodrigues. Ativado por