Ir ao conteúdo
  • Cadastre-se

Cofre PIC/Mplab


Posts recomendados

@marcelovillar

 

No caso do seu post 25, da forma que você fez seria um começo mas não o ideal pois o PIC fica preso no while (true) dentro da função botão.

 

Chegou a testar essa programação na prática?  O delay de 1000ms tá muito grande. Pode colocar 75mS. 

 

Quando eu chegar em casa coloco o completo com tempo pra você...

 

Falou

Link para o comentário
Compartilhar em outros sites

@marcelovillar,

Melhor conferir bem essa apostila....

Página 16 ensina como calcular o resistor limitador do Led, e mostra VLed = 0,6 Volts.....

E o cara se diz Prof. Eng. ........ É..... A vaca vai mesmo pro brejo..... !!!!!!

Referente ao transistor na página 5 :

Nesse exemplo o transistor não faz nenhum debouce, é apenas um exemplo de interface .....

Paulo

Link para o comentário
Compartilhar em outros sites

@aphawk

 

Entendi, você tem algum exemplo de hardware ou programação que eu possa corrigir isso?

Ou minhas pesquisas foram fracas, ou tem muito pouco material na internet mesmo a respeito disso e que esteja 100% correto.  :confused:

 

@MatheusLPS

 

Seguindo seu exemplo e com clock de 4MHz; 62500 incrementos gera 0,5s .... X*0,5=300 => 600, preciso repetir 600 vezes,

pelo menos no Proteus funcionou hehe

Link para o comentário
Compartilhar em outros sites

@aphawk

 

Entendi, só não sei como agregar isso na biblioteca do teclado.

Eu tava dando uma olhada nela, tem coisas referentes ao debouncing;

 

#define KBD_DEBOUNCE_FACTOR 80    // Set this number to apx n/333 where 
                                                                  // n is the number of times you expect 

                                                                  // to call kbd_getc each second 

 

kchar='\0'; 
   if(++kbd_call_count>KBD_DEBOUNCE_FACTOR) { 
 
 
So não entendi como posso resolver isso ou agregar aquele programação do debouncing,  falta-me conhecimento   :confused:  :(
Link para o comentário
Compartilhar em outros sites

@marcelovillar

 

Veja o que um experiente programador do CCS diz a repeito dessa biblioteca:

 

arunb, 
Look at the keypad driver code given in the link in his post. 
The code already has a debounce feature in it. 

Code:
#define KBD_DEBOUNCE_FACTOR 33 // Set this number to apx n/333 where 
// n is the number of times you expect 
// to call kbd_getc each second 
if(++kbd_call_count>KBD_DEBOUNCE_FACTOR) 



cile, 

Quote: #use delay (clock=48000000)

This is a very high clock speed. The original CCS keypad driver was 
tested at 20 MHz maximum. However, the driver has a parameter 
that can be adjusted for the oscillator frequency. 

The ratio of 48 MHz to 20 MHz is: 
48 / 20 = 2.4 

The old debounce value (for 20 MHz operation) is 33: 

Code: #define KBD_DEBOUNCE_FACTOR 33   


So, multiply the old "debounce factor" by 2.4 to get the new value: 

Code: #define KBD_DEBOUNCE_FACTOR 79   


Edit the keypad driver file, re-compile, and see if it now works.

 

Fonte: http://www.ccsinfo.com/forum/viewtopic.php?p=118870#118870

 

E do mesmo tópico:

 

I was able to duplicate your problem. I fixed it by increasing the 
debounce value to this: 

Code: #define KBD_DEBOUNCE_FACTOR 200

I didn't experiment to try to fine-tune it to the minimum value that will 
work. I just dropped in 200 and it started working. 

I've never liked the "debounce factor" method that CCS uses in kbd.c. 
It's not clean enough. You have to estimate (or physically determine) 
the amount of time it takes to execute the keypad routine, and then 
manually calculate the debounce factor. It would be better to require 
a fixed delay such as delay_ms(1), in the loop that calls the keypad 
routines and then use a fixed value for the debounce factor (1 or 3). 
Then you wouldn't have to do this calculation every time you change 
the oscillator frequency or PIC series.

 

Fonte: http://www.ccsinfo.com/forum/viewtopic.php?p=119026#119026

 

Veja se isso pode te ajudar.

 

Nunca usei essa biblioteca na prática. Só sabia que ela existia.

 

Falou

Link para o comentário
Compartilhar em outros sites

@MatheusLPS

 

Eu não entendi completamente pois não sei ler muito bem em inglês, ele fala que preferi utilizar delay?

Onde diz o fator; # define KBD_DEBOUNCE_FACTOR 79 , eu tentei valores como; 33, 150, 200, 333 ...

nenhum funcionou na pratica.

 

Você saberia me dizer como posso implementar algum delay na programação?

Seria de grande ajuda, to a um bom tempo nisso e não encontro solução :(

 

valeu 

Link para o comentário
Compartilhar em outros sites

@MatheusLPS

 

Não agreguei LCD. 

Para teste, coloquei a senha com todos algarismos 1, e coloquei apenas um botão com o resistor de pull-up. Pensando agora, tenho que lhe dizer e espero que eu esteja fazendo errado e cometido esta grande burrada ( :confused: ) mas não coloquei o resistor de pull-up nos demais pinos (28,29,30), já que não utilizaria o resto, mas é necessário ter VCC nestes terminais, isto influencia?  :confused:

Link para o comentário
Compartilhar em outros sites

@MatheusLPS

 

Funcionou, coloquei os resistores nos demais terminais e deu certo  :)

 

O teclado matricial do cofre utiliza apenas uma entrada, cada tecla é detectada através da tensão aplicada

no terminal. Eu andei pesquisando e encontrei alguns projetos referentes a isso;

 

http://www.micropic.es/mpblog/2007/08/gestiona-un-teclado-matricial-con-un-solo-pin/

 

http://picmania.garcia-cuervo.net/proyectos_analog_keyboard.php

 

Porém, é uma nova programação acredito eu, você tem alguma ideia de como eu poderia agregar isso no projeto (utilizar apenas uma entrada) ?  :confused:  :confused:

Link para o comentário
Compartilhar em outros sites

No primeiro link acima tem uma código pronto para usar somente com 1 pino.

 

você apenas cria uma biblioteca com a leitura das teclas que retornará o valor apertado.

 

No código que passei, você pegava a tecla assim:

 

digito = kbd_getc();

 

Ou seja, você chamava a função kbc_getc e ela retornava a tecla correspondente.

 

No exemplo que você passou, você vai adaptar da seguinte forma. O código passado lê as teclas com isso:

if (Tecla<150)TeclaChar='#';else if (Tecla<154)TeclaChar='3';else if (Tecla<160)TeclaChar='6';else if (Tecla<165)TeclaChar='9';else if (Tecla<175)TeclaChar='0';else if (Tecla<180)TeclaChar='8';else if (Tecla<188)TeclaChar='5';else if (Tecla<195)TeclaChar='2';else if (Tecla<205)TeclaChar='*';else if (Tecla<211)TeclaChar='7';else if (Tecla<223)TeclaChar='4';else if (Tecla<233)TeclaChar='1';

Você vai usar esse pedaço de código aí em cima e criar uma função e chamar ela toda vez. Esse função retorna o valor de TeclaChar.

 

return(TeclaChar); 

 

Não se esqueça de ler o canal AD a cada passagem do LOOP. Agora tenta aí. Vai treinando. Já te dei todas as dicas. 

 

Falou

Link para o comentário
Compartilhar em outros sites

  • 2 semanas depois...

@MatheusLPS

 

Você poderia me ajudar com a questão de que após o cofre ser aberto, eu aperte um botão, e depois de uns segundos a trava do cofre

feche e volte para o inicio da programação, volte para o void main, onde tenho que digitar a senha. Já tentei de várias formas e não ta dando certo, até consigo fechar o cofre após o botão ser pressionado, mas ele não retorna pro inicio de toda a programação.  :confused:

Link para o comentário
Compartilhar em outros sites

@marcelovillar

 

Dica:

 

Retire essa rotina do void_main  e coloque dentro de uma função criada por você.

 

Aí quando você fechar o cofre, você chama a função de digitar a senha de novo.

 

Não necessariamente o programa precisa voltar no void_main. Mas precisa chmar uma função que digita senha.

 

Tenta aí e qualquer coisa me fala.

 

Falou

Link para o comentário
Compartilhar em outros sites

@MatheusLPS
 
Uma das maneiras que tentei foi essa, porém a parte do botão não esta funcionando;

 

void main(){
 
programa();
 
}
 
void programa()
 
{  
    programação....
 
else if (n == 6)           //Se tenho 6 posições corretas, senha certa!
   {
      printf ("\n\rSenha Correta!");         //FIM!
      output_high(tranca);
      output_high(led_tranca);
      botao();
 
   }
   while(true);
}
 
void botao()
{
 
      if(input(botao_tranca)){     
      output_low(tranca);
      output_low(led_tranca); 
      digita_senha();  ou programa();  (tentei os dois)
      
      }
}
 
Também tentei colocar;
 
   {
      printf ("\n\rSenha Correta!");         //FIM!
      output_high(tranca);
      output_high(led_tranca);
 
      if(input(botao_tranca)){
 
      output_low(tranca);
      output_low(led_tranca);
      digita_senha(); ou programa();
      delay_ms(75);
 
   }
 
Você saberia me dizer porque no final do void main tem; while(true);    ?
Tentei colocar também nessa nova programação, nenhuma destas tentativas funcionou
Link para o comentário
Compartilhar em outros sites

@marcelovillar

 

O problema que você está tentando fazer seu programa de forma sequencial e não em forma de LOOP.

 

Normalmente, todo programa fica em um loop infinito, repetindo sempre a mesma coisa. Por isso o while(true). Ele ficará repetindo sempre o que tem dentro dentro desse LOOP. Aí vai de você controlar como ele interage a cada volta do programa.

 

você não precisa fazer ele de forma linear e sequencial como você está fazendo. Até porq você perderá o timing certo quando tentar apertar o botão para trancar o cofre.

 

Olha como o seu programa se resume em linhas gerais.

 

void main(){   inicialização de módulos;   inicializaçao de bibliotecas;   inicialização de variáveis;      while (true)   {      é para digitar a senha?      {         se sim, faz esse bloco;      }      não é para digitar a senha? seria trancar o cofre agora?      {         se sim, tranque o cofre;      }   }   }

 

 

Observe que ele não é linear ou sequencial da forma que você está tentando fazer.

 

Não te dou o código pronto, pois vendo que você está aprendendo e o que falta para você não é conhecimento da sintaxe do CCS, mas prática em lógica em fazer a programação.

 

Nesse caso, acho melhor eu fazer dessa forma e caso você realmente não consiga, te darei uma das soluções. Pois há diversas formas de pegar essa senha e fechar o cofre.

 

Falou

Link para o comentário
Compartilhar em outros sites

@MatheusLPS

 

Eu não consigo ver outra forma de resolver isso, não sendo por sequência pois, depois do ELSE IF, ou eu crio nesse bloco as tarefas que irão fechar o cofre quando pressionar o botão ou eu crio por exemplo uma nova função, como por exemplo void botao, e no final

do bloco else if vá para lá, e fique preso naquele bloco (void botao) até ser pressionado o botão, e depois volte para digita_senha.

 

Naquela minha programação, o microcontrolador lê que o botão não esta pressionado e termina a leitura, "encerra" o programa.

Não esta tendo erro de sintaxe (digo erro no sentido de faltar alguma coisa)? Pois, se eu coloco um loop infinito, ele fecha o cofre, mas também não irá sair deste laço já que é sempre

verdadeiro a condição. Será que eu não teria que criar alguma condição, para que ele se mantenha neste bloco e termine somente

depois que o botão for pressionado?

Link para o comentário
Compartilhar em outros sites

Veja mais ou menos assim:

 

você crie um avariável chamada abre_cofre.

 

Ela inicia em 1. Ou seja, já vai pedir senha de cara. Uma vez a senha foi digitada corretamente, esse variável passa a ser 0.

 

Agora o programa vai para o ELSE. Ele vai ficar tentando ler o botão o tempo todo. Se for apertado, ele tranca e a variavel volta a ser 1, pedindo a senha de novo.

 

Só você colocar o teste do botão dentro do laço do ELSE.

 

Falou

Link para o comentário
Compartilhar em outros sites

@MatheusLPS

 

Tentei várias coisas, o mais próximo que consegui foi o seguinte;

 

void main()
{      
    
   kbd_init();
   
   while(true)
   {
   
   if (abre_cofre == 1)
   {
   
   printf("Digite a senha...\r\n");
   
      
   digita_senha();         
 
........
 
   else if (n == 6)           //Se tenho 6 posições corretas, senha certa!
      {
         printf ("\n\rSenha Correta!");         //FIM!
         output_high(tranca);
         output_high(led_tranca);
         abre_cofre = 0;
      }
   }
  
  else if(abre_cofre == 0)
  {
      if(input(botao_tranca)){
         output_low(tranca);
         output_low(led_tranca);
         abre_cofre = 1;  
         delay_ms(75);
      }
   }      
 }
}
 
Resumindo;
 
void main() {
 while(true)
  {
    if (abre_cofre == 1){
     }
    else if (abre_cofre == 0){
     }

  }

}

Quando aperto o botão, a saida fica em 0 por alguns mili segundos, volta a 1, e aparece 3 vezes seguidas no Virtual Terminal,

Senha correta, digite a senha... se aperto o botao novamente, acontece a mesma coisa de novo.

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

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...