Página 1 de 1

Algoritmo Timer

MensagemEnviado: 08 Dez 2012 08:46
por daniel.sloczynski
Bom dia pessoal.

Venho pedir ajuda de vocês para o seguinte questão:


Código: Selecionar todos

if(Struct_Cfg.tm2_on.v[0]==rtc_hora && Struct_Cfg.tm2_on.v[1]==rtc_minuto && Struct_Cfg.tm2_on.v[2]==rtc_segundo)//contador 2 do timer 1 (T ON)


if(Struct_Cfg.tm2_off.v[0]==rtc_hora && Struct_Cfg.tm2_off.v[1]==rtc_minuto && Struct_Cfg.tm2_off.v[2]==rtc_segundo)//contador 2 do timer 1 (T OFF)



Onde:

Struct_Cfg.tm2_on.v[0] = Hora programada para ligar timer
Struct_Cfg.tm2_on.v[1] = Minuto programada para ligar timer
Struct_Cfg.tm2_on.v[2] = Segundo programada para ligar timer

Struct_Cfg.tm2_off.v[0] = Hora programada para desligar timer
Struct_Cfg.tm2_off.v[1] = Minuto programada para desligar timer
Struct_Cfg.tm2_off.v[2] = Segundo programada para desligar timer

rtc_hora = hora RTC
rtc_minuto = minuto RTC
rtc_segundos = segundos RTC

Uso estes if's para testar se está na hora de ligar ou desligar o timer. A questão é, se eu desligar o equipamento ou ele for ligado depois que passou do horário programado ele não vai ligar ou desligar pois não entrará mais no if.

Como eu poderia testar que ele ficasse ligado no intervalo de tempo entre Timer ON e Timer OFF?


Desde já agradeço pela atenção e qualquer dica/ajuda.

MensagemEnviado: 08 Dez 2012 10:35
por KrafT
Duas coisas...

- O uso do índice numérico dentro da estrutura é estranho para caramba... Parece uma má forma de utilizar a estrutura.

- Eu não compararia com "==" mas sim com ">", pois por exemplo se passar do tempo por um segundo, ainda vai atuar.

Basta fazer esses testes periodicamente, enquanto o sistema estiver ativo.

MensagemEnviado: 08 Dez 2012 18:34
por ze
pensei melhor neste fds. nem dormi direito.
eu criaria uma variável só. algo como:
tempo_em_minutos=hora*60+minuto
e faria só uma comparação com >. Mais visualizável 'programaticamente' prum jegue = eu. Acho que ninguém em sã conciência programaria os segundos para acionar um evento.

MensagemEnviado: 08 Dez 2012 19:35
por Red Neck Guy
Mais estiloso seria:

digamos, time_date.h
Código: Selecionar todos

#ifndef _TIME_DATE_H_
#define _TIME_DATE_H_

typedef struct{
  unsigned char hora,minuto,segundo,dia,mes;
  unsigned int ano;
}DateTime;

// 0 iguais,
// 1 diferentes
char cmp(DateTime *dt1,DateTime *dt2);

#endif// __TIME_DATE_H_


time_date.c
Código: Selecionar todos

char cmp(DateTime*dt1,DateTime*dt2){

   if(dt1->hora == dt2->hora &&
      dt1->minuto== dt2->minuto &&
      dt1->segundo==dt2->segundo &&
      dt1->dia == dt2->dia &&
      dt1->mes == dt2->mes &&
      dt1->ano == dt2->ano)
      return 0;
     
   return 255;
}




código cliente

Código: Selecionar todos
#include "time_date.h"

#define LIGAR                  0
#define DESLIGAR            1
#define INVERTER             2


typedef struct{
  DateTime  hora;
  unsigned char comando;
}sComando;

void main(void){ 
  DateTime hora_local;
  sComando programacoes[10];// Digamos que aqui estão as programações
  unsigned char i;

  for(;;){
       GET_CURRENT_TIME(&hora_local); // pega o rtc e joga o valor aqui

       for(i=0;i<10;i++)
         if(!cmp(&hora_local,&programacoes[i].hora)){
           switch(programacoes[i].comando){
              case LIGAR:
                      BOBINA_RELE = 1;
                      break;
              case DESLIGAR:
                      BOBINA_RELE = 0;
                      break;
              case INVERTER:
                      BOBINA_RELE^=1;
                      break;
            }
         }

  }

}





É importante que a chamada da iteração sobre o vetor das programações ocorre no mínimo uma vez a cada segundo, pois caso não ocorra, pode acontecer de no momento onde a comparação for verdadeira os parametros não serem testados.
Bá, eu adoro um açúcar sintático.

MensagemEnviado: 08 Dez 2012 19:38
por Red Neck Guy
KrafT escreveu:Duas coisas...

- O uso do índice numérico dentro da estrutura é estranho para caramba... Parece uma má forma de utilizar a estrutura.

- Eu não compararia com "==" mas sim com ">", pois por exemplo se passar do tempo por um segundo, ainda vai atuar.

Basta fazer esses testes periodicamente, enquanto o sistema estiver ativo.


Com a lógica que ele criou, se utilizar o ">", vai ficar dando aquele barulinho muito massa de bobina dos contatos do relé comutando loucamente ou, caso seja um ciclo rápido, vai ficar sempre travado e tal.
Creio eu, mas eu sei lá.

MensagemEnviado: 08 Dez 2012 21:24
por Silvio51
Concordo com o Aquino... incluiria também uma verificação (testes dos if) por interrupções em tempos curtos... 200ms talves... aí não iria correr o risco de estouros passarem despercebidos...

MensagemEnviado: 08 Dez 2012 22:38
por Red Neck Guy
Temos o seguinte:
-Fazer o pooling do relógio do sistema apenas uma vez por segundo não é seguro, pois devido a algum jitter podemos perder esse evento.
-Se formos realizar o pooling do relógio mais de uma vez por segundo, estaremos gastando ciclos de CPU para realizar o mesmo teste.

Então, já que a primeira forma - uma checagem por segundo - não é segura, teríamos em tese que utilizar a segunda. Mas já que a segunda forma gasta ciclos a mais da CPU rodando o teste mais de uma vez, podemos então gastar alguns desses ciclos inserindo o stamp em uma lista e e removendo eles no loop de teste. Aí, dependendo da implementação ainda ganhamos uns ciclos e tal...


Ficaria assim:

relógio
Código: Selecionar todos

List<DateTime> lista_timeStamp;

void RTI_timer_1_segundo(void){
  DateTime timestamp;
 
  GET_RTC(&timeStamp);
  lista_timeStamp.push_back( timestamp);
}

void thread_timer(void){
 DateTime hora_local;
  sComando programacoes[10];
  unsigned char i;

  for(;;){
 
    while(lista_timeStamp.size()){

      hora_local = lista_timeStamp.front();
      for(i=0;i<10;i++)
      if(!cmp(&hora_local,&programacoes[i].hora)){
           switch(programacoes[i].comando){
              case LIGAR:
                      BOBINA_RELE = 1;
                      break;
              case DESLIGAR:
                      BOBINA_RELE = 0;
                      break;
              case INVERTER:
                      BOBINA_RELE^=1;
                      break;
            }
         }
        lista_timeStamp.pop_front();
    }
    THREAD_SLEEP(1000);
  }
}




Assim, está meio C++ aí acima, mas dá pra criar a lista na munheca em C... Pra ficar 100%, teria que cuidar o acesso nas regiões concorrentes em relação a lista...
Mas uma solução séria é por aí.

MensagemEnviado: 09 Dez 2012 13:01
por KrafT
Aquino escreveu:
Com a lógica que ele criou, se utilizar o ">", vai ficar dando aquele barulinho muito massa de bobina dos contatos do relé comutando loucamente ou, caso seja um ciclo rápido, vai ficar sempre travado e tal.
Creio eu, mas eu sei lá.


Ha-ha-ha-ha... Tá me chamando de gonorântio? :lol:

Minha intenção não é dar o peixe não...

Mas já que eu não fui suficientemente claro, lá vai:

- Se voce vai testar um intervalo, não use o operador "==", mas sim "< e > ".

Não vou entrar no mérito de quem programa melhor ou pior, pq esse desfile de vaidades é coisa de moleque que fica medindo o pinto para comparar com os amigos .

MensagemEnviado: 09 Dez 2012 15:40
por Red Neck Guy
KrafT escreveu:
Aquino escreveu:
Com a lógica que ele criou, se utilizar o ">", vai ficar dando aquele barulinho muito massa de bobina dos contatos do relé comutando loucamente ou, caso seja um ciclo rápido, vai ficar sempre travado e tal.
Creio eu, mas eu sei lá.


Ha-ha-ha-ha... Tá me chamando de gonorântio? :lol:

Minha intenção não é dar o peixe não...

Mas já que eu não fui suficientemente claro, lá vai:

- Se voce vai testar um intervalo, não use o operador "==", mas sim "< e > ".

Não vou entrar no mérito de quem programa melhor ou pior, pq esse desfile de vaidades é coisa de moleque que fica medindo o pinto para comparar com os amigos .


Tô chamando não...
Quando aparecem essas coisas básicas que eu posso responder, eu também quero ajudar. Pô!

MensagemEnviado: 11 Dez 2012 09:14
por daniel.sloczynski
Obrigado pela ajuda pessoal.

Foi de grande valor mesmo. Já consegui implementar e testei a aplicação. Funcionou certinho.


Por isso que eu sempre penso: Trocar idéias com outras pessoas expande teus conhecimentos. Tava quebrando a cabeça antes de postar a dúvida aqui.

Abraço.

MensagemEnviado: 06 Jan 2013 10:53
por future
Esse RTC nao tem alarme? Mantenha uma lista ordenada de eventos e sempre espere pelo proximo a ocorrer.

Se o RTC tiver alarme, espere pela interrupcao ou flag...