Ir ao conteúdo
  • Cadastre-se

PIC Como fazer piscar o led com o 12f629


Posts recomendados

Em outro post semelhante a este deixei uma dúvida sobre o 12f675 e depois fui modificando a dúvida, e tal. Enfim, ficou meio confuso. Agora que tenho noção exata do que busco, decidi colocar aqui neste novo post:

 

Tenho um botão do pino 7 (Gp0) ao + 5 Volts com 10 K indo para o GND. Tenho um led no pino 3 (Gp4) com catodo para o GND. Vou ligar o pino 7 num alto-falante externo. Quando ocorrer o primeiro áudio, o PIC inicia um contador interno. Quando o áudio cessar por tempo = x, o led no pino 3 deve piscar 1 única vez por 500 ms; Digamos que x seja 5 segundos. Então quando o áudio cessar e transcorrer 5000ms o led deve piscar só 1 vez. Se antes dos 5000ms tornar a ocorrer áudio, o contador interno deve resetar (x=0;)

 

Pensei assim, mas seu que está errado:

 

while(!botão){
        delay_ms(1); 
          if(botão==1) {
          x++;         
            if(x==5000){
             Gp4=1;
             delay_ms(500);
             Gp4=0;
             x=0;
          }
       } 
     }

 

Como tem que ser ?

 

GRATO

 

 

 

 

 

 

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Que tal

if (!botão) x=0;
delayms(1);
x++;
if(x==5000) //>=5000
	{ 
	Gp4=1;
	delay_ms(500);
	Gp4=0;
	x=0;
	}

Entenda e me explique...

Tarefa/dica: pra capturar sinal de baixa amplitude, use o comparador. Pesquise antes de perguntar como.

comparator-graphic.jpeg

https://www.microchip.com/en-us/products/microcontrollers-and-microprocessors/8-bit-mcus/core-independent-and-analog-peripherals/integrated-analog/comparator

Link para o comentário
Compartilhar em outros sites

Assim quase deu certo. Com o botão fechado (ou seja, áudio rolando no alto-falante a ser monitorado) o led pisca e se deixar vai piscando enquanto houver áudio.

 

No caso, o led só deve piscar quando o áudio cessar. Começa sem áudio, led apagado. Começa o áudio, led apagado. Aí para o áudio por 5s, led pisca só 1 vez. 

Link para o comentário
Compartilhar em outros sites

Aí o led fica piscando direto, pois há um 10K mantendo Gp0 em nível baixo

Assim:

 

Gp0 = 0 , led = 0

Gp0 = 1 , led = 0

Gp0 = 0 , inicia tempo interno , led continua = 0

Gp0 = 0 por mais que 5s , led = pisca só 1 vez

 

 

Outra interpretação:

 

O tempo interno só deve começar quando Gp0 passar de 1 para 0

Link para o comentário
Compartilhar em outros sites

Veja se entendi certo o seu código:

 

if (!botão) x=0; .............................. se botão é igual a zero, variável x é igual a zero

delay_ms(1); ................................ passam 1 ms

x++;............................................... a variável x vai somando + 1

if (x==5000) { ............................... quando x for igual a 5000

Gp4=1; ........................................ pino 3 fica em 1

delay_ms(500); ........................... pausa 400ms

Gp4=0; ........................................ pino 3 fica em 0

x=0; .............................................. variável acumuladora do tempo, zera

}

 

 

 

 

Link para o comentário
Compartilhar em outros sites

Daqui eu não passo, já tentei de tudo:

 if(Gp0==0){
     z++;
     delay_ms(1);
       if(z==1000) //>=5000
        { 
         Gp4=1;
         delay_ms(500);
         Gp4=0;
         z=0;
        }
    }

 

O problema tá no seguinte: Quando liga, Gp0 já está em zero (10K para GND), então o Led em Gp4 já começa piscando independente de qualquer coisa. Não pode. Tem que esperar Gp0 ir a nível 1 (áudio entrando) para daí aguardar Gp0 ir para nível 0 (áudio parou) para daí iniciar a contagem do tempo na variável z (ver se áudio parou por mais que z milisegundos). Se sim, pisca Gp4. Se não, reseta z=0.

 

Deixei z = 1000 só pra agilizar nos testes aqui..

 

 

 

 

 

Link para o comentário
Compartilhar em outros sites

  • Membro VIP
22 minutos atrás, eletron1791 disse:

Tem que esperar Gp0 ir a nível 1 (áudio entrando)

while(!gp0); //faça algo aqui pra saber onde está... tipo pisque um led amarelo

 

23 minutos atrás, eletron1791 disse:

para daí aguardar Gp0 ir para nível 0 (áudio parou)

while(gp0); //o mesmo aqui: um led vermelho

 

while(!gp0)

{

26 minutos atrás, eletron1791 disse:

para daí iniciar a contagem do tempo na variável z (ver se áudio parou por mais que z milisegundos). Se sim, pisca Gp4. Se não, reseta z=0.

}

Obs: jamais pisque um led verde

 

Agora vai...

Link para o comentário
Compartilhar em outros sites

Mas e aquele seu primeiro código ?

 

Como seria a inclusão deste while ?

 

Já testei várias configurações com while e parênteses, nenhuma atendeu exatamente o propósito

 

while(Gp0==1){
if(Gp0==0){
     z++;
     delay_ms(1);
       if(z==1000) //>=5000
        { 
         Gp4=1;
         delay_ms(500);
         Gp4=0;
         z=0;
        }
    }
}

 

  • Confuso 1
Link para o comentário
Compartilhar em outros sites

  • Membro VIP

melhor 1 de nós começar a desenhar. .. Ah sim, tô sem lápis e papel.

 

11 horas atrás, eletron1791 disse:

Peço que deixe para ver se aparece mais alguém disposto a dar a resposta do primeiro post desta série. 

ok. por segurança coloquei você na minha l.n.: literalmente não vou ver + seus posts. Se achar que deve, faça o mesmo e boa sorte.

  • Amei 1
Link para o comentário
Compartilhar em outros sites

Criei este pequeno código onde chamo uma entrada de desarma e uma saída chamo de relé. O desarma tem a conotação de pausar, Ou seja, se desarma for igual a 1, o tempo x começa a incrementar e quando ele for igual a 5s o relé dá um pulso de 400ms (o rele na prática é um led). Mas notem que este trecho está abaixo do fechamento do //void while (true) e acima do fechamento do void main. Não funciona de jeito nenhum. Se eu colocar este pequeno código acima do fechamento do //void while (true) aí funciona a lógica mas não respeita o tempo, ou seja, basta eu fazer desarma == 1 e manter que o relé começa a piscar indefinidamente. Como fazer funcionar este pequeno código ?

 

 }//void while(true) 

      if(desarma==1){
        z++;
        delay_ms(1);
        if(z==5000){
             rele=1;
             delay_ms(400);
             rele=0;
             z=0;
          }
       } 
       
}//void main

 

Link para o comentário
Compartilhar em outros sites

Fazendo mais testes acho que encontrei o foco de toda a minha dificuldade. A variável z que declarei como int z=0: não funciona. O código não conta como deveria. Se desarma == 1 nada acontece. Se eu comentar a variável aí sim, funciona. Por que será ?

Alguém tem alguma ideia ?

 


     if(desarma==1){
      delay_ms(1);
      z++;
      if(z==5000){
      rele=1;
      z=0;
      }
    }

 

O certo seria, se desarma for = 1 por 5 segundos, o relé liga e o tempo z zera.

 

Link para o comentário
Compartilhar em outros sites

 

if(botao==1){
    delay_ms(100);    // filtro de ruído
    while(botão==0){
        delay_ms(1);
        x++;
        if (x == 5000){
            Gp4=1;
            delay_ms(500);    //led aceso
            Gp4=0;
                }
            }
    x=0;
    Gp4=0;
        
        }



não sei se ta certo tenta ai kkkk, n lembro como escreve em c++....
porém quando o led estiver aceso não detectará botao... não sei configurar interrupção do timer do pic no c++ pra interromper o led também...

Link para o comentário
Compartilhar em outros sites

esquecí de uma coisa, é legal sempre zerar as variáveis e portas antes de começar os programas, as vezes elas ficam com os valores presos na memória
tipo colocar

     x=0;
    Gp4=0;
no começo do programa também, ou ele pode bugar...

Link para o comentário
Compartilhar em outros sites

Fiz isso. Mas estou com problemas na variável x, por algum motivo que desconheço ela não está sendo respeitada. Eu a declarei como int x=0; em variáveis globais. E deixei x=0; em void main (inicialização de portas e registradores). Mas, com o botão aberto, o led começa a piscar direto (500ms), mostrando que de fato não está respeitando o x (uso o CCS e compila sem erros). O código tem mais coisas, esta seria só uma pequena intervenção. Não quero postá-lo aqui pois não tenho domínio sobre ele. Sei que assim fica difícil mas se tiver alguma ideia...beleza. Com o botão fechado, o led fica apagado..

Link para o comentário
Compartilhar em outros sites

  • DiF alterou o título para Como fazer piscar o led com o 12f629

Vejam, reduzi meu código até este limite. Querendo com isso fazer apenas a função do led piscar se a chave (esquema elétrico nos tópicos mais acima) abrir e ficar aberta por 5 s. Assim o led deve piscar só 1 vez. Mas o que está acontecendo é que o led, ao abrir a chave, pisca direto, pisca em 500ms direto, não respeita a variável <tempo>. Como tem que ficar este código para passar a respeitar a variável tempo ? e por quenão está respeitando ?

 

#include <12F675.h>
#device adc=8
#use delay(clock=4000000)
#fuses NOWDT,INTRC_IO, NOCPD, NOPROTECT, NOMCLR, PUT, BROWNOUT
#use fast_io(A)
#endif
#ZERO_RAM

#byte tris=0x85

#bit  led     = 0x5.4 //pino 3
#bit  botao   = 0x5.0 //pino 7

int tempo;

void main() {
 
   tris=0b001101; //gp0 como entrada
   tempo=0;
 
   while(true){
     
   if(botao==1){
      delay_ms(100);    // filtro de ruído
      while(botao==0){
        delay_ms(1);
        tempo++;
        if (tempo==5000){
            led=1;
            delay_ms(500);    //led aceso
            led=0;
                }
            }
    tempo=0;
    rele=0;   
        }
 
  } 
}

 

GRATO

 

Link para o comentário
Compartilhar em outros sites

ve se as interrupções do microcontrolador estão desativadas


saquei... perae vou arrumar aqui com uma flag...

#include <12F675.h>
#device adc=8
#use delay(clock=4000000)
#fuses NOWDT,INTRC_IO, NOCPD, NOPROTECT, NOMCLR, PUT, BROWNOUT
#use fast_io(A)
#endif
#ZERO_RAM

#byte tris=0x85

#bit  led     = 0x5.4 //pino 3
#bit  botao   = 0x5.0 //pino 7

int tempo;

void main() {
 
   tris=0b001101; //gp0 como entrada
   tempo=0;

   flag_led_piscou=0;
 
   while(true){
     
   if(botao==1){
      delay_ms(100);    // filtro de ruído
      while(botao==0 && flag_led_piscou==0){
        delay_ms(1);
        tempo++;
        if (tempo==5000){
            led=1;
            delay_ms(500);    //led aceso
            led=0;
            flag_led_piscou=1;  // poderia ser um return ou sei la
                }
            }
    tempo=0;
    rele=0;   
        }
 
  }
}

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...