Trocar de estado Pino_A1

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Trocar de estado Pino_A1

Mensagempor antonio » 31 Mar 2013 18:49

Pessoal tudo bem!

Pessoal faz tempo que estou aqui num programa que não tenho obtido resultado positivo que pertendo fazer!

Èh o seguinte ,o programa a baixo quero que faz o seguinte logo que ligo o PIC, duarante dois dias não faz nada no Pino_A1, passados dois dias desejo que no Pino_A1 fica trocando de estado de 5 em cinco horas, ou seja 5 horas em estado alto(1) e depois 5 horas no estado baixo(0), eh nesta parte do codigo que eu não tenho qualquer ideia de fazer esta troca de estado e jà là vai uma semana a pesquisar testar,e atè hoje nao tenho um resulatdo positivo!
por isso gostaria que o pessoal desse uma olhada no codigo para poder dar uma ajuda como devo resolveresta problema,pode ser facil mas os meus conhecimentos não voh là
O tempo não tem que ser muito preciso por isso estou a usar o TIMER1.
A parte que tenho duvida vai assinalada, caso algem tenha melhor ideia que quero fazer è bem vinda
Desde jà agradeço
O codigo
Código: Selecionar todos
#include <18F458.h>
#use delay(clock=20000000)
#fuses HS,NOWDT,NOLVP

int16 segundos=0;
int8 intt=0;

#int_TIMER1
void timer1_isr(void)
{
set_timer1(3036);
++intt;
  if(intt>=10)
  {
  Segundos++;
  intt=0;
  }
   if(segundos==3600)
    {
    hora=hora +1;
    Segundos=0;
    }
   If (hora==24)
    {
    Day=day+1;
    hora =0;
    }
}
void main(void)
{
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);

while(true)
{
while(day<=2);
//***************************************************[color]aqui èh onde tenho a maior difilcudade de realizar o codigo[/color]**********************************//
output_toggle(PIN_A1);
//********************************************************************************************************************************************************************************************//
}wihle( day<10)
output_low(PIN_A1);
}
}
}
antonio
Byte
 
Mensagens: 209
Registrado em: 15 Out 2006 12:34

Re: Trocar de estado Pino_A1

Mensagempor RobL » 31 Mar 2013 22:25

No primeiro while faça somente < 2 . Desta forma ele sai quando for 2.

Código: Selecionar todos
while (dia < 2)  // retardo de dois dias e entra no while eterno abaixo
{
  troca a saída();
  dia = 0 ;
}

while (1) // cai neste aqui e fica trocando de 5 em 5 dias
{
  if (dia >=5)
  {
    troca saída();
    dia = 0 ;
  }
}


Veja ai se deu pois estou com sono.
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Re: Trocar de estado Pino_A1

Mensagempor antonio » 01 Abr 2013 06:30

RobL escreveu:No primeiro while faça somente < 2 . Desta forma ele sai quando for 2.

Código: Selecionar todos
while (dia < 2)  // retardo de dois dias e entra no while eterno abaixo
{
  troca a saída();
  dia = 0 ;
}

while (1) // cai neste aqui e fica trocando de 5 em 5 dias
{
  if (dia >=5)
  {
    troca saída();
    dia = 0 ;
  }
}


Veja ai se deu pois estou com sono.


Brigado Robl por ajudar!

Bem o que eu quero não eh bem isso !! o primiros dois dias no Pino_A1 não faz nada por isso eu fiz isto ""while(day<=2);
Depois desse tempo (dois dias ) o Pino_A1 fica trocando de estado de 5 em 5 hoas (e não de 5 em 5 dias como vc escreveu em cima) e durante 10 dias
Dà pra dar uma ajuda a resolver isto??
Mais uma vez agradeço
antonio
Byte
 
Mensagens: 209
Registrado em: 15 Out 2006 12:34

Re: Trocar de estado Pino_A1

Mensagempor RobL » 01 Abr 2013 09:44

Ao sair do primeiro while acrescente hora = 0;
No segundo while, while(1) mude dia para hora .

Se você mantiver while ( dia <= 2) ele só vai sair no terceiro dia.
de 0 a 1 (um dia) ele fica no loop, de 1 a 2 ele fica no loop pois dia = 2 é true, vai sair somente quando dia = 3.
A nao ser que seu dia comece em 1 (dia = 1).


Acabei fazendo aqui:
while (dia < 2) // retardo de dois dias e entra no while eterno abaixo
{
troca a saída();
dia = 0 ;
}

hora = 0 ;

while (1) // cai neste aqui e fica trocando de 5 em 5 dias
{
if (hora >=5)
{
troca saída();
hora = 0 ;
}
}


Ahhh, tem ainda durante 10 dias ???!!! Não tinha isto lá em cima ou não vi ?
Aí esse código não vai parar depois de 10 dias, nem poderia zerar as horas, como fiz.
Tem várias formas.
Crie uma variável para horas que apos entrar no segundo loop comece a incrementar e teste a cada 5 horas e outro if dentro deste loop para 10 dias.
Vai tentando com este exemplo. Não pode zerar a hora como está ai.

Cuidado com o colesterol no cérebro . O meu tá cheio.
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Re: Trocar de estado Pino_A1

Mensagempor cfreund » 01 Abr 2013 13:32

Código: Selecionar todos
#include <18F458.h>
#use delay(clock=20000000)
#fuses HS,NOWDT,NOLVP

#define TIME_TO_START      48      // Aguarda 48 horas para inciar
#define TIME_TO_TOGGLE      5      // Alterna a cada 5 horas
#define TIME_TO_STOP      240      // Encerra depois de 240 horas

uint8  tick;
volatile uint16 hours, seconds;

#int_TIMER1
void isr_timer1(void){    // interrupção a cada 100mS
   if(++tick >= 10){
      tick = 0;
      if(++seconds >= 3600){
         seconds = 0;
         if(hours < 0xFFFF) ++hours;
      }
   }
}

void main(void){
   uint16 last_time;

   tick = hours = seconds = last_time = 0;
   
   output_high(PIN_A1);
   
   set_timer1(3036);
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
   
   for(;;){
      if( (hours >= TIME_TO_START) && (hours < TIME_TO_STOP) ){
         if( !(hours % TIME_TO_TOOGLE) && (last_time != hour) ){
            output_toggle(PIN_A1);
            last_time = hour;
         }
      }
   }
}
Cláudio F
Avatar do usuário
cfreund
Word
 
Mensagens: 672
Registrado em: 14 Out 2006 14:02
Localização: São Paulo

Re: Trocar de estado Pino_A1

Mensagempor RobL » 04 Abr 2013 17:41

Alo Antonio. Você viu a elegância com que o cfreund resolveu o seu problema ?

Código: Selecionar todos
for(;;){
      if( (hours >= TIME_TO_START) && (hours < TIME_TO_STOP) ){
         if( !(hours % TIME_TO_TOOGLE) && (last_time != hour) ){
            output_toggle(PIN_A1);
            last_time = hour;
         }
      }
   }
}


Tem na solução dele uma boa aula:
Nunca tente resolver um problema pelo código diretamente. Tente com fluxograma.

Perceba que ele testou do tempo mais longo para os mais curtos, do problema, veja os aninhamentos do if o maior tempo no if externo. if( (hours >= TIME_TO_START) && (hours < TIME_TO_STOP) ).

Observou que o teste das horas seria sempre em um múltiplo de 5.
Lançou mão da elegante solução "módulo de 5", aplicada neste caso.
if( !(hours % TIME_TO_TOOGLE) && (last_time != hour) )
O primeiro parenteses será zero em cada múltiplo de 5 (o resto da divisão de horas / 5).
A negação dele (do zero) tornará o primeiro lado do AND verdadeiro. O segundo será sempre verdadeiro fora do valor last_time = hora.
A cada múltiplo de 5, de hour, last_timer toma o valor de hour. Isto é usado como uma trava, enquanto hour não sair de um múltiplo de 5. Desta forma o teste é feito uma só vez dentro do múltiplo de 5.
Bacana.
Quem não pergunta c freunde !
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Re: Trocar de estado Pino_A1

Mensagempor cfreund » 05 Abr 2013 14:31

RobL,

Tem um bug neste código, mas vamos deixar como aprendizado para o Antonio.
Cláudio F
Avatar do usuário
cfreund
Word
 
Mensagens: 672
Registrado em: 14 Out 2006 14:02
Localização: São Paulo

Re: Trocar de estado Pino_A1

Mensagempor RobL » 05 Abr 2013 15:19

O erro de digitação na variável não é bug, apesar de não compilar.
Mas o problema até a primeira hora, aí sim deu inseto.
Com uma mexidinha na inicialização, resolve fácil, pelo menos numa rápida olhada.
Mas a solução continua bonita.
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Re: Trocar de estado Pino_A1

Mensagempor cfreund » 05 Abr 2013 16:08

Além desse problema, tem um - bastante grave - na lógica. Eu consegui identificá-lo lendo a sua explanação. Segue correção:

Código: Selecionar todos
for(;;){
      if( (hours >= TIME_TO_START) && (hours < TIME_TO_STOP) ){
         if( !( (hours - TIME_TO_START) % TIME_TO_TOOGLE) && (last_time != hours) ){
            output_toggle(PIN_A1);
            last_time = hours;
         }
      }
   }
}


Agradeço-lhe pelos elogios exaltantes.
Cláudio F
Avatar do usuário
cfreund
Word
 
Mensagens: 672
Registrado em: 14 Out 2006 14:02
Localização: São Paulo


Voltar para PIC

Quem está online

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

x