Temporizador

Boas pll,
vamos ver se consigo explicar a minha dificuldade.
Pretendo criar um temporizador decrescente e para tal fiz:

void temporizador_retorno()
  {
          setFont(LARGE, 255, 255, 255, 0, 0, 0);
          minutos = 2;
          segundos = 59;
            myGLCD.print("0",220+10, 160);
            myGLCD.printNumI(minutos, 236+10, 160);
            myGLCD.print(":", 252+10, 160);
            myGLCD.printNumI(segundos, 268+10, 160);
            
            if(millis()-previousMillisContador>1000)
                {
                  segundos = segundos -1;
                  if(segundos <0)
                      {
                        segundos =59;
                        minutos = minutos -1;
                      }
                      myGLCD.print("0",220+10, 160);
                      myGLCD.printNumI(minutos, 236+10, 160);
                      myGLCD.print(":", 252+10, 160);
                  if(segundos<10)
                      {
                       myGLCD.print("0",268+10, 160);
                       myGLCD.printNumI(segundos, 284+10, 160);
                      }
                  else
                      {
                       myGLCD.printNumI(segundos, 268+10, 160);
                      }
                }
        }

no parte do touchsreen tenho:

if ((y>=menU[1]+42) && (y<=menU[3]+62) && (x>=menU[0]) && (x<=menU[2]))
      {//waitForIt(menU[0], menU[1]+42, menU[2], menU[3]+62); //pausa
        pausa_reposicao = true;
        Millis_pausareposicao = millis();

e finalmente no loop tenho:

if (myTouch.dataAvailable())  
  { 
    processMyTouch();  // Verifica se o LCD está sendo tocado e faz o processamento.
  }
if(pausa_reposicao ==true)
        contador_decrescente();
        previousMillisContador = millis();
        {if ((millis() - Millis_pausareposicao) < 180000)
                {
                 analogWrite(bombaReposicao, 255);            //bomba desligada
                 nivelRet = 0;
                }
            else
                {
                 analogWrite(bombaReposicao, 0);            //bomba volta a ligar
                 pausa_reposicao = false;
                 nivelRet = 6;
                }
        }

O temporizador até funciona, ou seja, o rele da bombaReposiçao quando pressionada a tecla pausa desliga-se por 3 minutos, e após os 3 minutos volta a ligar, a questão é que o print no ecrã do contador decrescente só decresce uma unidade, ou seja inicia com “02:59” passa para “02:58” e depois não sai daqui :frowning: presumo que o erro deve estar relacionado com isto:

if(millis()-previousMillisContador>1000)

mas já vi e revi o código e não dou com ele, alguém pode ajudar?

O problema não está nessa instrução em especifico... mas sim na instrução que falta (suponho eu), onde a variável previousMillisContador é actualizada. Normalmente, isso acontece dentro do if... ou seja:

if(millis()-previousMillisContador>1000){
   //faz alguma coisa....



   previousMillisContador = millis(); 
}

Eu não estou a ver o código todo, logo não sei se será este o problema... mas no código que mostras, não existe nada semelhante.

EDIT: depois de ver o que escreveu o bubulindo vejo que não reparei nisso e que o problema é maior que o que imaginei.

EDIT 2: Esqueça a alteração que apontei.

Sendo assim, depois do comentário anterior, tenho umas dúvidas e uns reparos:

Dúvida 1: O que é e para que serve a função contador_decrescente(); que está a ser chamada no loop()? Pensei que fosse ela a responsável pela parte de mostrar o contador decrescente no ecrã, mas olhando com mais atenção, vejo que essa função se chama temporizador_retorno().

Dúvida 2: O previousMillisContador = millis(); é o mesmo que está dentro da função? Ele devia estar mesmo dentro da função e dentro do if, como diz o bubulindo.

Reparo: Esta parde não devia estar a ser feita assim, e isto (que não reparei inicialmente) é que me induziu em erro na minha análise. Na linha:

       {if ((millis() - Millis_pausareposicao) < 180000)

o valor 180000 não devia ser constante. Aliás, isto não devia estar a ser feito com o millis() porque a outra função já está a fazer esse trabalho. Com o 180000 constante, não importa o que seja escrito no ecrã, que a espera vai ser sempre de 3 minutos! Isso não faz qualquer sentido. Como o tempo está a ser decrementado na outra função, e se quer fazer este bloco quando o tempo chegar a zero, o que devia ser feito é qualquer coisa como:

         if (minutos != 0 && segundos != 0)
                {
                 analogWrite(bombaReposicao, 255);            //bomba desligada
                 nivelRet = 0;
                }
            else
                {
                 analogWrite(bombaReposicao, 0);            //bomba volta a ligar
                 pausa_reposicao = false;
                 nivelRet = 6;
                }
        }

Pll, Começo por agradecer a vossa colaboração e desejar FELIZ NATAL a todos ;)

A informação já é muita, (nada que eu me importe), e postas as coisas assim têm-me que dar algum tempo para "dissecar" tudo...o meu ritmo é muuuuuuiiinto mais lento, (ritmo de maçarico).

Palpita-me que ambos têm razão, vou iniciar uns testes com aquilo que vocês mencionaram e já darei noticias!!

Só uma breve resposta ás perguntas do luis,

Sim Luis tens razão, a maneira como a "coisa" está estruturada não faz sentido, mas tem uma razão de ser...dada a minha limitação de conhecimentos, tenho estado a fazer as coisas "por fazes" e primeiro fiz um temporizador de 3 minutos, (em principio este valor será fixo, pode não ser os 3 minutos, mas não será alterável pelo touchsreen, uma vez que não há necessidade e para o alterar tinha de estar a criar mais variaveis, e a "memoria" do arduino mega já esta quase toda consumida).

Este "temporizador" está a funcionar como quero, resolvido isto estava agora a "escrever" no ecrã o tempo por ordem decrescente.

Quando consegui "escrever" os 3 minutos por ordem decrescente faz todo o sentido alterar o código para ficar apenas com "uma função"

NJPinheiro

luisilva: Sendo assim, depois do comentário anterior, tenho umas dúvidas e uns reparos:

Dúvida 1: O que é e para que serve a função contador_decrescente(); que está a ser chamada no loop()? Pensei que fosse ela a responsável pela parte de mostrar o contador decrescente no ecrã, mas olhando com mais atenção, vejo que essa função se chama temporizador_retorno().

lapso meu...corrigi no código fonte mas não corrigi aqui...onde se lê contador decrescente dever-se-á ler temporizador_retorno

Possivelmente, fazendo a alteração que o bubulindo aponta, resolve o problema da contagem não ser mostrada. Eu tinha sugerido outra alteração, mas estava a pensar que o código estava feito de forma diferente, por isso não fazia sentido e apaguei o comentário.

Pll, O erro está aqui:

void temporizador_retorno()
  {
          setFont(LARGE, 255, 255, 255, 0, 0, 0);
          minutos = 2;
          segundos = 59;
          bla, bla, bla, bla
          bla, bla, bla, bla

Como cada vez que ele entra no void faz-me minutos=2 e segundos =59, ele desincrementa uma unidade e depois torna a por minutos=2 e segundoa =59 :smiling_imp:

Por outro lado o Luis tem razão, não faz sentido ter duas funções para a mesma coisa:

  1. Que me temporiza a pausa de 3 minutos;
  2. O print da contagem decrescente dos 3 minutos

A minha duvida é que tenho 2 aparelhos que vou temporizar via pausa, (nunca os dois ao mesmo tempo) e assim sendo em termos de consumir menos "memoria" faz sentido manter a estrutura que tinha idealizado? ou qualquer coisa como o Luis sugeriu? ou seja:

O print da contagem dos 3 minutos e enquanto minutos & segundos diferentes de Zero relés desligados, (aparelho um ou aparelho dois)

Não percebi a questão. Quanto mais código consiga reaproveitar sem repetir, para fazer as duas temporizações, melhor.

luisilva:
Não percebi a questão.

Sim Luis, reconheço que a coisa não está muito bem explicada, e aproveitei para refazer tudo.
já tenho o temporizador a 90% só me falta ultrapassar uma questão.

o código está assim:

    boolean pausa_reposicao = false;
    unsigned long Millis_pausareposicao = 0;
    unsigned long Millis_Contador = 0;
    byte minutos = 0;
    byte segundos = 0;

    void temporizador_retorno()
  {
            setFont(LARGE, 255, 255, 255, 0, 0, 0);
            myGLCD.print("0",220+10, 160);
            myGLCD.printNumI(minutos, 236+10, 160);
            myGLCD.print(":", 252+10, 160);
            myGLCD.printNumI(segundos, 268+10, 160);
            
            if(millis()-Millis_Contador>1000)
                {
                  
                  segundos = segundos -1;
                  if (segundos > 200)
                      {
                        segundos = 59;
                      }
                  if(segundos<10)
                      {
                       myGLCD.print("0",268+10, 160);
                       myGLCD.printNumI(segundos, 284+10, 160);
                      }
                  else
                      {
                       myGLCD.printNumI(segundos, 268+10, 160);
                      }
                  if ( segundos ==0)
                      {
                       minutos = minutos -1;
                           if(minutos > 200)
                              {
                                minutos = 0;
                              }
                      } 
                  if(segundos <0)
                      {
                       segundos =59;
                      }
                  myGLCD.print("0",220+10, 160);
                  myGLCD.printNumI(minutos, 236+10, 160);
                  Millis_Contador = millis();
                }
        }

no touchScreen:

if ((y>=menU[1]+42) && (y<=menU[3]+62) && (x>=menU[0]) && (x<=menU[2]))
      {//waitForIt(menU[0], menU[1]+42, menU[2], menU[3]+62); //pausa
        pausa_reposicao = true;
        Millis_pausareposicao = millis();
        minutos = 2;
        segundos = 59;

e por fim no loop:

if (dispScreen == 49)
      {
        if(pausa_reposicao == true)
            {
              if (millis() - Millis_Contador > 1000)
                  {
                    temporizador_retorno();
                    Millis_Contador = millis();
                  }
              if ( minutos != 0 && segundos != 0 )
                    {
                      analogWrite(bombaReposicao, 255);
                      nivelRet = 0;
                    }
              if (minutos == 0 && segundos == 0)
                  {
                    analogWrite(bombaReposicao, 0);
                    pausa_reposicao = false;
                    nivelRet = 6;
                  }
            }
      }

ora como o temporizador é decrescente faz:
01:01 m:s »»»»»»OK
00:00 m:s »»»»»» condição verdadeira, rele activado , temporizador “desligado” mas só c/ 2 min. decorridos e não os 3
00:59 m:s »»»»»» Deveria continuar desligado o rele, ou seja temporizador activo


00:01 m:s »»»»»» Deveria continuar desligado o rele, ou seja temporizador activo
00:00 m:s »»»»»» Parava temporizador, accionava rele

dicas para contornar esta questão, é possível?

Na parte do loop(), o seguinte:

              if (millis() - Millis_Contador > 1000)
                  {
                    temporizador_retorno();
                    Millis_Contador = millis();
                  }

devia ser apenas:

                    temporizador_retorno();

porque o resto já está a ser feito dentro da função.

Também não gosto, de:

            myGLCD.print("0",220+10, 160);
            myGLCD.printNumI(minutos, 236+10, 160);
            myGLCD.print(":", 252+10, 160);
            myGLCD.printNumI(segundos, 268+10, 160);

dentro da função, porque os valores voltam todos a ser escritos dentro dos if's.

Também não gosto desta parte:

                  if (segundos > 200)
                      {
                        segundos = 59;
                      }

Se o valor de segundos, depois de decrementar for negativo, então volta com o valor de segundos a 59. Isto funciona bem se o valor de minutos for maior que zero, caso contrário depois de 00:00, passa a ser 00:59.

Também não gosto daquela representação de negativo. "> 200". poderia ter usado um tipo de variável que não fosse unsigned e já "tinha acesso" aos números negativos. Sugiro que troque o 'byte' por 'char'.

Não percebi a parte:

01:01 m:s »»»»»»OK 00:00 m:s »»»»»» condição verdadeira, rele activado , temporizador "desligado" mas só c/ 2 min. decorridos e não os 3 00:59 m:s »»»»»» Deveria continuar desligado o rele, ou seja temporizador activo ........ ........ 00:01 m:s »»»»»» Deveria continuar desligado o rele, ou seja temporizador activo 00:00 m:s »»»»»» Parava temporizador, accionava rele

Isto é a contagem que o contador faz? Passa de 01:01 para 00:00 e depois para 00:59?

luisilva: Não percebi a parte: Isto é a contagem que o contador faz? Passa de 01:01 para 00:00 e depois para 00:59?

Olá Luis, O problema é que o contador para nos 01:01 porque imediatamente a seguir seria 00:00 o que satisfaz a condição, mas como estamos numa contagem decrescente ainda faltam 60 segundos para o fim dos 3 minutos.

Vou analisar / testar o resto do seu ultimo post já digo qualquer coisa.

Obg NJPinheiro

luisilva: Se o valor de segundos, depois de decrementar for negativo, então volta com o valor de segundos a 59. Isto funciona bem se o valor de minutos for maior que zero, caso contrário depois de 00:00, passa a ser 00:59.

Não percebi a parte: Isto é a contagem que o contador faz? Passa de 01:01 para 00:00 e depois para 00:59?

Luis, é exactamente esse o problema com que estou :confused:

Pll, Problema resolvido....solução?

...simples, trocar a variavel do tipo byte para tipo char ;)

Obrigado aos colegas de forum, que muito têm contribuindo para que eu ainda continue a levar este projecto para a frente, pois tem havido fases que eu sozinho não teria conseguido ultrapassar as dificuldades.

Obg NJPinheiro

OK. Ainda bem que isso é assim.

E quando as pessoas perguntam porque é que eu detesto estes tipos inventados à pressa... este é um belo exemplo.

byte é tudo menos descritivo... e depois quem o usa corre o risco de não funcionar como se julga uqe funciona.