Algoritmo Timer

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Algoritmo Timer

Mensagempor daniel.sloczynski » 08 Dez 2012 08:46

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.
daniel.sloczynski
Bit
 
Mensagens: 47
Registrado em: 28 Abr 2011 09:13

Mensagempor KrafT » 08 Dez 2012 10:35

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.
"..."Come to the edge," he said. And so they came. And he pushed them. And they flew."― Guillaume Apollinaire
Avatar do usuário
KrafT
Dword
 
Mensagens: 2228
Registrado em: 11 Out 2006 14:15
Localização: Blumenau -SC

Mensagempor ze » 08 Dez 2012 18:34

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.
Editado pela última vez por ze em 10 Dez 2012 07:46, em um total de 1 vez.
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Mensagempor Red Neck Guy » 08 Dez 2012 19:35

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.
Avatar do usuário
Red Neck Guy
Dword
 
Mensagens: 1968
Registrado em: 12 Out 2006 22:24

Mensagempor Red Neck Guy » 08 Dez 2012 19:38

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á.
Avatar do usuário
Red Neck Guy
Dword
 
Mensagens: 1968
Registrado em: 12 Out 2006 22:24

Mensagempor Silvio51 » 08 Dez 2012 21:24

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...
Silvio51
Byte
 
Mensagens: 383
Registrado em: 02 Nov 2006 14:04
Localização: Brasil

Mensagempor Red Neck Guy » 08 Dez 2012 22:38

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í.
Avatar do usuário
Red Neck Guy
Dword
 
Mensagens: 1968
Registrado em: 12 Out 2006 22:24

Mensagempor KrafT » 09 Dez 2012 13:01

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 .
"..."Come to the edge," he said. And so they came. And he pushed them. And they flew."― Guillaume Apollinaire
Avatar do usuário
KrafT
Dword
 
Mensagens: 2228
Registrado em: 11 Out 2006 14:15
Localização: Blumenau -SC

Mensagempor Red Neck Guy » 09 Dez 2012 15:40

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ô!
Avatar do usuário
Red Neck Guy
Dword
 
Mensagens: 1968
Registrado em: 12 Out 2006 22:24

Mensagempor daniel.sloczynski » 11 Dez 2012 09:14

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.
daniel.sloczynski
Bit
 
Mensagens: 47
Registrado em: 28 Abr 2011 09:13

Mensagempor future » 06 Jan 2013 10:53

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...
future
Bit
 
Mensagens: 24
Registrado em: 06 Mai 2007 00:38


Voltar para PIC

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x