Boa tarde.
Escrevi 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 e executa uma rotina
Obs: 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 fazendo da forma abaixo:
void loop() {
if (condição1){
unsigned long previous_millis = millis();
while(millis() - previous_millis <= interval1);
if (condição2){
unsigned long previous_millis = millis();
while(millis() - previous_millis <= interval2);
if (condição3){
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 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.
Acredito que 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.
A dúvida é justamente sobre isso. Existe alguma correção para esse erro?
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?
Agradeço qualquer ajuda.
O teu problema é que cada passo espera pela condição do millis (estás a usar ciclos while). Isto empanca o processador e o que tu notas é o acumular do processamento das instruções.
As tuas condições são sinais externos? A condição tem de ficar sempre presente durante esse tempo ou basta que aconteça momentâneamente para iniciar a contagem?
Eu achava que usando dessa forma seria como aquele exemplo de blink without delay que não empacasse o processador.
Existe uma forma de fazer sem empacar o processador?
As condições são externas e precisam ficar sempre presentes.
A função delay é literalmente um ciclo while como o que tu programaste.
A maneira de conseguir fazer isto é através de if's em vez do while. Para tal vais precisar de ter variáveis que guardam o estado da funcionalidade que queres.
unsigned char condicao = 0;
unsigned char condicao_anterior = 0;
unsigned long condicao_tempo = 0;
if ((condicao != condicao_anterior) && (condicao == TRUE)) { // se o sinal mudou de estado.
condicao_tempo = millis();
}
if (condicao == TRUE && millis()-condicao_tempo >= interval1) {
//faz o que pretendes...
}
A função loop é um ciclo (como um while) e como tal vai correndo todas as condições ao mesmo tempo. Se quiseres, podes criar um bit de temporização para indicares que a temporização está a correr.
Escrevi o código assim:
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);
}
}
}
}
}
}
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.
PS.: desculpe se não entendi direto a última sugestão do bubulindo.
Boa tarde.
Dando um feedback.
Consegui meu intento através da referência abaixo:
Obrigado a todos.