RECEPTOR GENERICO FLEX – UM PROGRAMA PARA VARIAS OPÇÕES DE CIRCUITOS INTEGRADOS – COM PIC 12F675/629 (REF126)

Hoje encontramos no mercado, transmissores de controle remoto para portão e alarmes com vários circuitos integrados. Que tal um único código em que pudéssemos optar qual modelo usar?

Analisando as muitas situações de uso para os controles remotos, desejei tentar fazer um programa que atendesse as mais variadas necessidades dos hobistas. Por exemplo: Um artigo é postado para um receptor usando um HT6P20b, com 2 canais. Surge alguém que precisa de 3 canais. Outro hobista deseja um canal invertido. Ainda outro, que a saída seja em modo ‘retenção’ para todos os pinos. Sem falar dos que desejam um pino em modo ‘pulso’ e outros em ‘retenção’. Realmente se torna um pouco ‘enfadonho’, escrever e reescrever os códigos já publicados, com estas simples alterações. Também, em muitas localidades não se encontra determinado integrado usado na montagem, mas existe de outros modelos. Surgiu a ideia de escrever um código em que fosse possível montar nosso receptor a ‘LA CARTE’. Cada hobista escolheria sua opção e marcaria no código. Depois é só compilar e carregar o PIC.

As características desejadas obtidas neste código são estas:

1) Opção de escolher qual integrado do transmissor iremos decodificar. Assim, poderá ser optado pelo ci HT6P20B, PT2262,PT2240B e família HCS 200 …301 (somente em modo fixo, sem usar o HOPPING CODE).
Obs. Apenas um modelo pode ser usado por vez.
2) Opção de escolher de forma individual, se as saídas serão em modo ‘PULSO’ ou ‘RETENÇÃO’.
3) Opção de escolha de forma também individual, se as saídas serão ‘invertidas’ ou ‘normais’.
4) Opção por aprendizado único de todos os botões (para uso em um único aparelho) ou aprendizado individual (para uso com vários aparelhos)
5) Escolher entre o PIC 12f675 ou 629.
6) Escolher carregar um byte de calibração provisório (em situações de perda deste de forma acidental). Os Pics ‘encostados’ , por não funcionarem em programas gerados em compiladores ‘C’, pela falta deste byte de calibração, poderão ser reaproveitados.
7) Possibilidade de mudar quais pinos serão usados, respeitando as limitações para pinos específicos.

Outra necessidade é que fosse em uma linguagem mais ‘usual’ e não no ‘Assembly’, pois muitos tem ‘aversão’, uma genuína ‘idiossincrasia’ só da menção do nome desta nobre linguagem. Dando os primeiros passos na linguagem “C”, portanto, esta foi a linguagem escolhida para este humilde projeto de iniciante. Creio que, para quem já é experiente nesta linguagem, não terá dificuldade em alterar e talvez simplificar as linhas de código. Mas foi o que consegui e portanto, estou compartilhando. Todas sugestões serão bem recebidas, de como fazer de uma forma melhor.

Voltando ao código, foi usado o compilador CCS C para a compilação, podendo ser usado a versão de demonstração. Logo no início do programa, podemos alterar nossas escolhas em ‘Opções do Usuário’, por comentar ou descomentar as linhas relacionadas as opções.
A rotina faz uso da interrupção do Timer 0 a cada 100 microssegundos, para analisar o estado da entrada que tem o sinal do receptor de 433mhz (RFIN, pino 3). Se for ‘0’, irá incrementar o contador ‘LC’ e acionar o flag_L. Depois, quando a entrada ficar ‘1’, irá incrementar o contador ‘HC’. Quando a entrada rfin ficar ‘0’ novamente, será analisado se o contador ‘LC’ estourou um valor máximo, o que indicaria um intervalo grande (pausa entre transmissões) e que servirá de sincronização do sinal. Se o valor de ‘LC’ ficou abaixo do permitido, haverá uma subtração de ‘LC’- ‘HC’, cujo valor do ‘carry’ será deslocado para dentro do buffer de recepção de 3 bytes e resetando ‘LC’, ‘HC’ e o ‘flag_L’, em preparação para um novo bit a ser recebido. Ao final de 24 bits recebidos (ou 64 no HCS) teremos uma recepção completa. Isto será sinalizado por setar o ‘flag_rok’. São feitas 2 recepções para comparar e eliminar erros de transmissão. Depois a rotina procura na memória pelo número transmitido (serial number), se já foi aprendido na memória. Se foi, irá acionar as saídas de acordo com as opções escolhidas pelo usuário. Se não, irá verificar se o botão ‘LEARN’ foi apertado (e o led ‘learn’ deverá estar aceso). No caso de ter sido apertado, será gravado este número recebido na EEprom e apagará o led “LEARN’. Com respeito a recepção do HCS, foi aproveitado apenas parte do serial number (HCS usa 28 bits + 4 botões= 32 bits ou 4 bytes da parte ‘fixa’ + 32 bits ou 3 bytes na parte encriptada, mas são gravados na EEprom apenas 22 bits + 2 bits dos botões). A razão desta decisão foi dar compatibilidade com os outros controles que usam apenas 3 bytes para o serial number.
Atenção: Este programa é de caráter didático apenas, sujeito a bugs ainda não detectados.

Segue o arquivo ‘C’:

RX_GEN_FLEX_C

Segue pasta zipada com os arquivos do projeto (10/11/2013):

arquivos_projeto_c

Segue pasta zipada com os arquivos do projeto ( atualizada em 17/12/2016):

RX_GEN_FLEX__

Segue pasta zipada com os arquivos do projeto, sendo esta uma versão que salva o estado das saídas em retenção na EEprom do pic e retorna no seu reset ( 17/12/2016):

rx_gen_flex__eep.c

E versão (em teste) para ht6p20d também:

RX_GEN_FLEX_4_C

Como a montagem permite muitíssimas combinações de circuitos integrados e modos de operação, ficará evidente porque não tentei fornecer o arquivo Hex. Cada hobista deverá escolher a suas opções e recompilar, para obter o arquivo HEX.
Obs. Ainda não obtive retorno do funcionamento do código para PT2262, sendo testado apenas com o clone do PT2262 deste blog.

Segue os esquemas de 4 sugestões de montagens, onde temos receptores de 1 a 4 canais:

Manuais:
HCS200
PT2262
PT2240b
Pic12F675

Curiosidades:
O rio que teve seu curso invertido
Outros grandes terremotos estão por vir
Será que Deus é o responsável?
Teve um Projeto? O econômico peixe-cofre
Por que a cooperação é essencial
Como poderá manter um conceito equilibrado sobre o dinheiro?
Sou viciado em aparelhos eletrônicos?
20 modos de criar mais tempo
Dengue — uma ameaça crescente
Preservados numa gota dourada
O “mundo perdido” da Bolívia

Outros assuntos:
Um site para você
Como disciplinar seu filho adolescente
Por que eu me corto?
Desempenhem bem o papel de pais
Como fazer seu segundo casamento dar certo
O que acontece quando morremos?
Como criar filhos responsáveis
Como administrar o seu dinheiro
Ensine valores morais a seus filhos
Ensine seus filhos bons principios com atividades de colorir
Como posso ter ânimo para exercitar
Como posso controlar meu peso?
Entrevista com um bioquímico
Adolescentes- O que fazer se estou sofrendo bullying?
Como evitar ferir com palavras?
Como tratar seu cônjuge com respeito?
Perguntas Bíblicas Respondidas

Até o próximo artigo!!!

113 comments on “RECEPTOR GENERICO FLEX – UM PROGRAMA PARA VARIAS OPÇÕES DE CIRCUITOS INTEGRADOS – COM PIC 12F675/629 (REF126)

  1. Boa Noite Cláudio, tudo bem, Parabéns pelo artigo, naveguei bastante na net procurando como decodificar o ht6p20 em código C, encontrei somente o seu. Gravei, funcionou certinho. Gostaria de fazer umas modificações para se adaptar as minhas necessidades, mas mesmo com seus comentários no código estou encontrando dificuldades.
    Preciso fazer o seguinte:

    Gravar os botões, e tratar alguns tempos dentro do pic.
    Exemplo.
    Botão 1 se apertado, conta 30 segundo e desliga pino2
    Botão 2 se apertado, conta 40 segundos e desliga pino2
    Botão 3 se apertado, conta 40 segundos e desliga pino2

    Desde já agradeço.

    1. Olá Rony! Realmente, alterar este código fica meio confuso com tantas opções ! Talvez possa nomear as saídas (_s1…_s3) para serem flag. Então, no final do main você usa estes flag para acionar as saídas em rotinas de tempo dinâmicas (a cada loop do main decrementa uma variável que ao chegar à zero liga/desligá a saida desejada.)
      Claudio

      1. Entendi Cláudio, na verdade o que preciso mesmo é entender melhor a decodificação do ht6p20b, com certeza por falta de conhecimento meu, só preciso fazer, por exemplo, o botão 1 mudar o estado de uma variável “liga” (exemplo)
        botão 2 mudar estado de variável “liga1”
        botão 3 mudar estado de variável “liga2”, o restante creio que consigo, seria o mais básico mesmo.

        Precisava de primeiro gravar o código gerado pelo botão 1 na memória e quando apertado depois de gravado, buscar na memória se for igual acionar uma variável, isso para os três botões, o restante eu trabalho aqui.
        Se possível me ajudar agradeço, pois nem meus professores de faculdade sabem me ensinar, estou no terceiro ano de engenharia de automação e controle.
        Obrigado Cláudio

        1. Olá Rony!

          Realmente, é díficil achar matéria sobre este tipo de circuito integrado e seu funcionamento. Mas encontrei no site da Holtek um flowchart com os passos para realizar a decodificação ( note application HA0120E e HA0121E). Encontra-se no link : http://www.holtek.com.tw/english/tech/appnote/uc/pdf/ha0120ev110.pdf .Também alguns colegas postaram maneiras diferentes de realizar a decodificação. Por exemplo: O projeto enviado por José Ney no link http://picsource.com.br/archives/1899/. Também no site ASM51 poderá ler a matéria do colega Fabim no link http://www.asm51.com.br/phpbb/viewtopic.php?f=10&t=7322.
          Também poderá baixar o pdf no link http://application-notes.digchip.com/044/44-34036.pdf mostrando o protocolo.
          Quando você diz ‘acionar uma variável’, o que você quer dizer? Colocar um valor nela? Incrementa-la? Decrementa-la? Uma variável de quantos bits? Se puder ser mais específico do que você pretende fazer fica mais fácil entender.
          Cláudio

          1. Ok, eu preciso apertar o botão de gravação, depois apertar o botão do controle para gravar(exemplo botão 1).
            Depois de gravado, quero somente acionar uma saída do pic (exemplo: Botão 1 do controle acionado, “output_high(pin_a5)), simples assim, com esse código, consigo entender como foi feita a leitura do ht6p20b, sua gravação na eeprom, e depois a comparação para acionamento da saída . Desculpa se não estou conseguindo me expressar corretamente.

            Obrigado Cláudio

        1. Cláudio, Boa noite, consegui adaptar seu código pra minha necessidade, muito bom, só não estou conseguindo resolver um probleminha, talvez possa me ajudar.
          O código depois de adaptado, funciona certinho, aciono o botão 1, conta um determinado tempo (+ ou – 30s) e para, se eu acionar enquanto está contando o tempo, ele interrompe a contagem, tudo certo.Porém se eu ficar com o botão apertado ele fica alternando liga e desliga.
          Não consegui entender 100% a parte de gravação pra eu colocar algo pra evitar isso.

          Se fosse no caso de entrada de botão, normalmente uso o seguinte:

          //////////////////////////////////////////////////////
          if (input(pin_b4)){
          delay_ms(10);
          x++;
          do{}
          while(input(pin_b4));
          }
          /////////////////////////////////////////

          Segue o código que está funcioando, porém com esse detalhe.

          Obrigado.

          ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
          ////////////////////////////////////////////////////////////////////////////////
          ///////////*************************************************************////////
          //**************************************************************************////
          /////////////////Claudio Lários////////////////////////////////////////////
          //****************************************************************************//
          //****************************************************************************//
          //****************************************************************************//
          ////////////////////////////////////////////////////////////////////////////////
          ////////////////////////////////////////////////////////////////////////////////
          //==============================================================================

          #include
          #device adc=8
          #use delay(clock=4000000)
          #ignore_warnings 203,202 //desconsidera mensagem de ‘condition always true’
          #fuses NOWDT,INTRC_IO, NOCPD, NOPROTECT, NOMCLR, NOPUT, BROWNOUT
          #ZERO_RAM
          #use fast_io(a)
          //bytes
          #byte tris=0x85
          #byte gpio=0x05
          //bits
          //bit
          #bit LEDG=0x05.0//led learn pino 7
          #bit LRN=0X05.0//botão de gravação/apagamento pino 7
          #bit RF =0x05.3 //entrada do sinal de RF pino 4
          #bit t0if=0x0b.2//flag over flow timer 0
          //defines
          #define NBIT 28 // numero de bits
          #define apagar 70 //tempo com botão LRN apertado para apagar eeprom
          #define T_MAX 250 //tempo maximo em modo de gravação de controles (15 seg)
          #define T_basico 500 //tempo basico (pulso inicial da transmissão)
          //#define v_tempo_acionado 4000 //tempo das saidas acionadas em modo pulso
          #define t_intervalo 400 // intervalo entre transmissões (400 a 5000)
          #define tris_led 0b001000; //trisio para acender led prog
          #define tris_lrn 0b001001; //trisio para acender led prog

          //variavéis globais
          int32 buffer=0; //buffer de dados a receber
          int32 bufferx=0;//buffer de copia da transmissão anterior

          int16 timerx=0;
          int1 fled1,fled2,fled3;//flags auxiliares
          void testa_lrn(); //prototipo
          int16 cont=0;
          int16 contador=0;
          int16 botoes=0;
          int16 soma=0;

          int16 desl_qd_ap_botao=0;
          int16 cnt_eeprom;

          //==============================================================================
          // Rotina para captura de bits enviados pelo tx (ht6p20b)
          //==============================================================================

          int1 get_htp(void) {
          int8 x=0;
          buffer=0;
          while(!RF){
          testa_lrn();
          if(!++timerx) return false;
          }

          if(timerx>t_intervalo) { // intervalo entre transmissões (23te x pulso basico)

          for(x=0;x>=1;
          }
          else buffer>>=1;

          delay_us(T_basico);

          if(!RF){ return FALSE; }
          }

          return TRUE;
          }

          else return FALSE;
          }
          //==============================================================================
          // Rotina de apagamento dos controles gravados
          //==============================================================================

          void apagar_eeprom(){
          int8 a;
          for(a=0;a<128;a++) { write_eeprom(a,0xff); }
          tris=tris_led;
          for(a=0;aapagar)&&!LRN){ apagar_eeprom();}//apagar todos controles
          tris=tris_led;//saida no pino 7
          if(tempo_led>T_MAX) LEDG=1; //termina periodo de programação e apaga led prog
          }
          //Rony // desliga_saida();//desliga saidas ativadas apos tempo
          }
          //==============================================================================
          // Rotina de pesquisa por controle gravado na eeprom
          //==============================================================================
          int1 procura(){

          int8 a;
          for(a=0;a<127;a+=3){

          if(make8(buffer,2)!=read_eeprom(a)) continue ;//achou o primeiro byte?
          if(make8(buffer,1)!=read_eeprom(a+1))continue ;//achou o segundo byte?
          if(make8(buffer,0)!=read_eeprom(a+2))continue ;//achou o terceiro byte?
          return true;//sim! Os tres!
          }
          return false;//não!
          }

          //==============================================================================
          // Rotina para obter o endereço que deve ser gravado o novo controle
          //==============================================================================

          int8 end_gravar(){
          int8 a;

          for(a=0;a=1){beep2(); } //Chama void beep somente em condição que botoes>=1, ou seja, quando alguma tempo estiver acionado
          desl_qd_ap_botao++;
          cont=0;
          contador=0;
          botoes=3;
          delay_ms(400);// tempo para não contar a variável de baixo muito rápida e conar mais de um

          }//aciona a saída 3 (Botão 3)

          ///3333333333333333333333 **acionamento botão 3** 333333333333333333333333333333333333333333333///////

          //222222222222222222222 **acionamento botão 2** 2222222222222222222222222222222222222222222222222/////
          else{

          if(bit_test(aux,7)) {

          if(botoes==0){beep(); } //Chama void beep somente em condição que botoes=0, ou seja, quando nenhuma tempo estiver acionado
          if(botoes>=1){beep2(); } //Chama void beep somente em condição que botoes>=1, ou seja, quando alguma tempo estiver acionado

          desl_qd_ap_botao++;
          cont=0;
          contador=0;
          botoes=2;
          delay_ms(400);// tempo para não contar a variável de baixo muito rápida e conar mais de um
          } //aciona a saída 1 (Botão 2)
          //222222222222222222222222 **acionamento botão 2** 22222222222222222222222222222222222222222222222////

          ///11111111111111111111111111 **acionamento botão 1** 1111111111111111111111111111111111111111111111///

          if(bit_test(aux,6)){

          if(botoes==0){beep(); } //Chama void beep somente em condição que botoes=0, ou seja, quando nenhuma tempo estiver acionado
          if(botoes>=1){beep2(); } //Chama void beep somente em condição que botoes>=1, ou seja, quando alguma tempo estiver acionado

          desl_qd_ap_botao++;
          cont=0;
          contador=0;
          botoes=1;
          delay_ms(400);// tempo para não contar a variável de baixo muito rápida e conar mais de um

          }//aciona a saída 2 (Botão 1)
          ///11111111111111111111111111111 **Fim do acionamento botão 1** 1111111111111111111111111111111111111////////
          }
          LEDG=1;
          }
          else{
          tris=tris_led;
          if(!LEDG){
          if(!gravar()) { LEDG=1; }//gravação ok, led learn apaga
          Delay_ms(3000); // Tempo para não acionar as saidas logo depois da gravação
          }
          }
          }
          ///////////////////////////////////////////////////////////////////////////////
          ///////////////////////////////////////////////////////////////////////////////
          ///////////////////////////////////////////////////////////////////////////////
          //==============================================================================
          // Rotina de recepção do tx comparando 2 recepções consecutivas
          //==============================================================================

          void recebe_tx(){
          static int1 fr;
          if(get_htp()){
          if(!fr) {bufferx=buffer; fr=1;}//salva a primeira recepção
          else{
          fr=0;
          if(bufferx==buffer){ action(); bufferx=0; }//compara a primeira com a segunda
          }
          }
          }

          //==============================================================================
          // Rotina principal
          //==============================================================================

          void main() {

          setup_adc_ports(NO_ANALOGS|VSS_VDD);
          setup_adc(ADC_OFF);
          setup_counters(RTCC_INTERNAL,RTCC_DIV_256);
          setup_timer_1(T1_DISABLED);
          setup_comparator(NC_NC_NC_NC);
          setup_vref(FALSE);
          tris=tris_led;

          if((!input(pin_a4))) {botoes = 4; desl_qd_ap_botao=1;} // função “desliga_qd_ap_botao foi colocado com valor 1,
          //pois permite desligar a função no primeiro toque de qualquer botão,
          // pois isso acontece quando essa variáve é igual a 2”

          output_low(pin_a0);
          output_low(pin_a2);
          output_low(pin_a5);
          LEDG=1; //mantém led prog apagado quando liga na energia
          //==============================================================================
          // Loop principal
          //==============================================================================

          while(1){

          if(desl_qd_ap_botao>=2){desl_qd_ap_botao=0; cont=0;
          contador=0; botoes=0; soma=0; output_low(pin_a5); } //Desliga saídas se qualquer botão for acionado

          ///11111111111111111111111111111111***Botão1****1111111111111111111111/////////////////////////1

          if(botoes==1 && (input(pin_a4))){

          cont++;

          // if(beep_off==0){beep();} //aciona beep

          if(cont>=10){ contador++; cont=0; }

          if(contador>=1 && contador=1501){ output_low(pin_a5); } // Apaga (botão 2)

          if(contador>=1502) {cont=0; contador=0; soma++; } //Tempo apagado (botão 2)

          if(soma>=1){ botoes=0; soma=0;}

          }
          //////////11111111111111111***Botão1****11111111111111111111111111////////////

          //////////222222222222222222***Botão2****2222222222222222222222222222²²²²²²²²

          if(botoes==2 && (input(pin_a4))){

          cont++;

          // if(beep_off==0){beep();} //aciona beep

          if(cont>=10){ contador++; cont=0; }

          if(contador>=1 && contador=1561){ output_low(pin_a5); } // Apaga (botão 2)

          if(contador>=3102) {cont=0; contador=0; soma++; } //Tempo apagado (botão 2)

          if(soma>=5){ botoes=0; soma=0; }
          }
          ///22222222222222222222***Botão2****2222222222222222//////////////////////////

          ////3333333333333333333***Botão3****33333333333333//////////////////////

          if(botoes==3 && (input(pin_a4))){

          cont++;

          // if(beep_off==0){beep();} //aciona beep

          if(cont>=10){ contador++; cont=0; }

          if(contador>=1 && contador=3103){ output_low(pin_a5); } // Apaga (botão 3)

          if(contador>=6200) {cont=0; contador=0; soma++; } //Tempo apagado (botão 3)

          if(soma>=15){ botoes=0; soma=0; }

          }

          //////33333333333333333333***Botão3****3333333333333333333333////////////////////

          //////////////////////////início Pino aterrado////////////////////////////////

          if((!input(pin_a4)) && botoes>=1){

          cont++;

          if(cont>=10){ contador++; cont=0; }

          if(contador>=1 && contador=3103){ output_low(pin_a5); }

          if(contador>=6200) {cont=0; contador=0; }

          }

          ///////////////////////Fim Pino aterrado////////////////////////////////

          recebe_tx();//verifica se houve uma recepção de tx
          testa_lrn(); //verifica se foi pressionado botão de aprendizado
          }//while(1)
          }//main
          ///////////////////////////////////////////////////
          /////////////////////////////////////////////////////

          1. Olá RonyFreitas!
            Para testar um botão, se ele continua apertado e aguardar soltar, corretamente pode

            usar o código que você citou:

            //////////////////////////////////////////////////////
            if (input(pin_b4)){
            delay_ms(10);
            x++;
            do{}
            while(input(pin_b4));
            }
            /////////////////////////////////////////

            Mas no caso da recepção é mais complexo, porque o processo da recepção bem sucedida poderá envolver no mínimo dois frames transmitidos (uns 150 mseg). Poderá ser mais, se houver muita interferência no local (quando demora para acionar).
            Para identificar se um botão do tx continua apertado, tenho usado um (ou mais) temporizador ‘dinamico’, colocado para decrementar continuamente dentro do loop da rotina principal, sendo carregado em cada recepção bem sucedida. Quando não há recepções bem sucedidas, ele chega a zero, reseta um flag de trava (de bloqueio). Este é usado na rotina que testa o bit correspondente ao botão acionado no tx e faz um ‘and’ com este flag ‘trava’. No primeiro acionamento do botão, a rotina também deverá setar este flag, para impedir novo acionamento da rotina para o botão apertado. E em cada recepção bem sucedida, deverá ocorrer uma nova carga no temporizador ‘dinamico’.
            Enquanto houver recepção bem sucedida, o temporizador dinamico nunca chega a zero e portanto, nunca reseta o flag trava, sendo que ele impede de acionar várias vezes (alternando). Mas se depois de um tempo aproximado a 6 a 10 recepções não receber carga por não ter havido recepção do tx, então o flag trava será resetado, liberando para uma possivel nova recepção.
            O ideal é um contador dinamico mais um flag trava para cada botão, para serem independentes uns dos outros, apesar que em certas aplicações apenas um de cada pode ser aceitável.

            Resumindo:
            1) Use um (ou mais) contador no loop principal decrementando até zero

            int16 cont_din;

            while(1) {//LOOP PRINCIPAL

            if(cont_din)cont_din–;
            if(!cont_din) trava=0;

            }//while(1)

            Na rotina de teste:

            if(botoes && !trava) {
            aciona();
            trava=1; //bloqueia até soltar botão no tx por um tempo
            }

            Creio que é meio complexo para entender de ínicio, mas no fim fica fácil.
            Acredito que possa existir outras soluções empregadas pelos programadores profissionais, mas desconheço, porque aindo sou apenas um hobista nesta área, tenho muito que aprender.
            Não tenho condições de alterar e testar o seu código, pois teria que ter a rotina completa e tempo para isto, coisa que ultimamente não estou tendo nem para novos artigos.

            Cláudio

  2. Bom dia Claudio. Obrigado por responder. Eu estou usando um tx da Vseg, e também da jfl, que usa o HT6P20B. Eu passei o osciloscópio na saida do tx, e é possível perceber muitas interferências, mas o que me chamou a atenção, é que somente a saida do pino 5 do pic 12f675 que é acionada. As outras duas não acionou nenhuma vez.

    Gilmar

    1. Olá Gralves!
      Como você está usando? Gravou um pic com o hex original cujas saídas acionam outro pic? Fez alguma alteração na rotina? Tentou gravar um controle por vez e testar? Pode ter um vizinho com um mesmo numero de controle (remoto mas possível).
      Claudio

      1. Olá Claudio. Os pinos do pic12f675 onde esta o programa do receptor, estão ligado aos pinos de um pic16f628, com um resistor de 10k ao gnd. Eu já fiz isso, gravei botão, por botão para fazer o teste, mas o pino 5 do 675 exita a entrada do 628 com um pulso muito rápido. Eu fiz uma mudança no meu programa, colocando um retardo de 500ms na entrada que esta recebendo esse sinal, para ver se resolve. Ou seja, esta saída só vai ser aciona, se o botão do canal 3 for pressionado pro mais de 500ms. Vou ver se resolve. Não foi possível testar ainda, porque não terminei de montar outra placa. Amanha cedo vou levar o pic gravado e substituir, para fazer o teste no local que esta instalado o sistema.

        1. Olá Gralves!
          Você colocou um capacitor de 220 nanofarads do vcc ao gnd bem próximo de cada pino dos pics? Evita ‘resets’ indesejados por interferência mutua entre pics. Você usou retenção ou pulso? Invertido ou normal? Quanto tempo você acredita que seja este ‘pulso’ no pino 5? Como se fosse acionado o tx em modo pulso e soltado o botão? Ou é bem mais rápido? Você compilou o arquivo c para ht6p20b? Ajustou as configurações de usuário? Existe algum rele que seja acionado que você tenha esquecido de colocar um diodo em paralelo com sua bobina? Pode ser qualquer bobina que seja ligada sem este diodo? Ao se desligar uma bobina, ela gerará elevada ddp entre os seus terminais, que podem resetar pics com facilidade, com o perigo de destruir o chip. Mas parece que você disse que ligou apenas um diodo para teste sem o restante do circuito, é isto? Se for, não deve ser o caso. Creio que você fez o teste fora do veículo, na bancada. Também manifestou o problema? Ou somente no veiculo? A energia do carro (12 volts) é muito poluída eletricamente falando, com ruídos de faíscas, alternador, componentes eletrônicos, etc. Atenção especial deve ser dado na entrada da fonte quando usada em veículos.

          Att.
          Cláudio

          1. Oi Claudio, sim, eu coloco capacitor de 100nf entre os pinos + e gnd. Eu estou usando pulso normal. Como eu havia dito, eu coloquei no meu programa um retardo de 500ms, como se fosse um antrebut, mas ainda esta ocorrendo o problema somente no píno 5. Eu compilei o seu programa C para o ht6p20b. Na configuração de usuário, eu descomentei para uso do 675. O programa esta rodando blz, a não ser esse ativação da saída -s2 – pino 5. O tempo desse pulso é maior que 500ms, porque o retardo que coloquei no meu programa indica isso, pois ainda esta abrindo a tranca magnética da porta. Se me passar um e-mail, eu lhe mando o projeto inteiro pra você analisar. Esse projeto é para controlar 3 portas com tranca magnética. Se enviar um sinal para abrir uma, as outras fica travada. E se uma abrir, as outras não abre, e assim sucessivamente. O programa sinaliza a abertura da porta através de LDs VD e VM. O LD verde pisca na cadencia de 1/2 segundo, se um dos botôes do tx for acionado, e se abrir a porta, ele pisca de 1 em 1 segundo. A trava elétrica volta a energizar depois de 10s. Se não tiver funcionando correto, as portas não funcionara.

          2. Relacionado com os diodos em paralelo com as bobina, é necessário coloca-los, para não queimar o transistor por pico reverso. Como eu havia lhe dito antes; eu estou com o receptor montado no protoboard. Somente um regulador filtrado com os capacitores, o pic12f675, os resistores e o LDs nos pinos, para visualizar o funcionamento. E de vez em quando, o LED na saída do pino 5 aciona. Lá no local onde montei o projeto completo, o acimamento é mais frequente, devido a muitos sistemas sem fio instalado. As interferência são mais frequente. Aqui na minha oficina de eletrônica, tenho poucas interferências, por isso aciona com uma frequência menor.

          3. OLÁ GRAVES!
            Vamos tentar no arquivo c. Experimente reduzir a janela de recepção alterando a constante para ht6p20b nomeada de tmax_ht=80 para 20 ou 30. Recompile e teste o novo hex. Verifique se pode reduzir alguma oscilação do receptor rf_ colocando um resistir de 1M5 a 2M2_ na saída analógica. Fico no aguardo.
            Claudio

          4. Olá Claudio, boa noite. Eu fiz a mudança. Estou com o osciloscópio plugado na saída analógica do rx. Foi na linha 201(byte const tmax_ht= 20;). Primeiro eu tentei com 30, mas logo que liguei, o led do pino 5 acendeu umas três vezes, depois pus esse valor (20). Passou uns 10 minutos e houve mais um lampejo do led. De vez em quanto eu leu um trem de pulso no osciloscópio. Mas não da para ver quando exita o led.

          5. Olá Gralves!
            Mantenha a janela (constante tmax_ht=20) e altere a seguinte linha da rotina de recepção do ht6p20b:
            if(lc>tmax_ht) {reset_rx (); qb=24;}
            por:
            if((lc>tmax_ht)||(hc>tmax_ht)) {reset_rx (); qb=24;}

            Também vamos apertar a escolha do bit 1 ou 0 na rotina, trocando a linha :
            else { shift_right(&buffer[0],3,(lc>hc)) ;
            por:
            else { shift_right(&buffer[0],3,(lc>(hc+(hc/2)))) ;
            Depois recompile e teste o novo hex.
            Fico no aguardo
            Att.
            Claudio

          6. Oi Cládio, boa noite, eu fiz as alterações, conforme me explicou. As mudanças foram feitas nas linha 755 e 756, ROTINA DE RECEPÇÃO DOS 24 BITS.
            A compilação ocorreu normal, sem erros, mas eu não consegui gravar os TXs.

          7. Claudio, durante a gravação do pic, eu percebi que o checksum no Pickt 2 não alterava. Resolvi reiniciar o PCW, para ver se alterava. Puxei o programa que esta funcionando antes,com o problema fiz o teste, e funcionou. Fiz novamente a primeira alteração na linha 755, o comando (if), gravei o pic só com essa linha primeiro. O checksum mudou, não era o mesmo. Coloquei o pic no protoboard e o LD lampejou novamente. Ou seja eu consegui gravar o controle. Alterei a segunda linha, a 756 com a instrução (else). Gravei o pic e consegui gravar o TX. Durante a edição desse texto eu não vi o LD acender.Estou com o osciloscópio plugado na saída do RX para ver se algum ruido vai aparecer e ocorrer o problema. Estou confiante que funcionara. Eu lhe informo depois.

          8. Oi Claudio, nesse momento, em quanto eu estava observando o sinal no osciloscópio, o LD que esta no pino 5, acendeu novamente. O receptor, recebe ruidos constantes, não uma forma de onda gerado pelo ht6p20b. Mesmo assim ocorre esse acionamento. Hoje eu mudei meu programa, e aumentei o retardo na entrada do sinal desse pino, para 1000ms. Durante o dia inteiro, a tranca magnética não foi acionada, mesmo com esse pulso do pic12f675. Tudo indica que o pulso é menor que 1000ms. Não quero lhe dar trabalho, mas se você tiver mais alguma informação, quando tiver um tempo, eu agradeço.

          9. Olá Gralves!
            Onde tenho feito as montagens não tem tanto ruido elétrico na faixa de 433mhz e fica difícil simular a sua situação. Mas irei estudar mais alguma possibilidade para ajudar a tentar contornar a situação.
            Cláudio

          10. Ola´Claudio, como vai, tudo bem. Eu gostaria de lhe passar uma informação, sobre aquele problema que estava ocorrendo, do acionamento do pino 5 do PIC12f675 do seu projeto acima. Você havia me passado algumas instruções para tentar corrigir o problema, alterando primeiramente o valor da instrução,tmax_ht=80, para 20, ou 30. Eu fiz isso mas a saída anida continuava a ser exitada.

            Uma coisa que não lhe falei, foi que ao alimentar o projeto que esta montado no proto board, essa saída também era exitada. Ai de tempo em tempo ela era exitada. No entanto um dia desses eu resolvi, sem conhecimento algum, colocar na instrução tmax_ht=40 e fiz o teste de alimentar o protoboard para ver se a saída do pino 5 seria exitada. Para minha surpresa ela não foi mais. Deixei o projeto energizado e percebi que esse pino 5 onde estava com um LED nele, não mais foi exitado por ruido externo. Estou lhe passando essas informações, para quando tiver tempo descobrir, por que com esse valor esse problema não ocorre mais.

          11. Olá Gralves!
            Obrigado por notificar suas descobertas curiosas! Quando tiver um tempo, irei analisar mais de perto o assunto. Mas, espero que isto tenha resolvido o seu problema na questão da interferência.
            Cláudio

  3. Olá Claudio, com esta, tudo bem?. Claudio eu fiz um projeto de controlador de intertravamento de portas, feito em ladder, usando seu projeto do receptor,O RX_GEN_FLEX_C para utilizar um tx. Nesse projeto eu utilizo os três botoes do tx independente. Foi um dos motivos que eu o achei interessante. Eu percebi recentemente que umas das portas esta abrindo sozinha, ou seja, sem pressionar o potão do controle. Montei no protoboard para ver se era algum bug no programa, visto que limpei varias vezes a memoria e gravei os controlos de novo, e o problema continuou. Esta ocorrendo um acimamento no pino 5. Os dois outros esta perfeito. No teste com o projeto montado no protoborad, eu coloquei um led azul para me chamar atenção, quando o problema ocorresse.De vez em quando, ele da uma piscada. Como eu disse, isso só ocorre no pino 5. Eu dei uma olhada no seu código fonte para ver se via alguma coisa que pudesse fazer, para corrigir esse problema, mas eu só arranho no C. Por isso estou precisando de sua ajuda, pra saber o posso fazer para corrigir esse problema.

    1. Olá Graves!
      Pode acontecer em locais com muita interferência em 433mhz que possa ocorrer acionamento esporádico pelo receptor em especial se esta interferência for cíclica ou que se repita em uma determinada sequência. Também, notei que alguns receptores comerciais de 433mhz tendem a entrar em oscilação em dados momentos , gerando ruído cíclico. Alguns receptores tem uma saída analógica aonde podemos colocar um resistir de 1M5 deste pino ao gnd. Em alguns casos tem resolvido. Em outros tem que trocar a frequência de trabalho optando por tx de 315mhz e receptor da mesma frequência. Se dispor de um osciloscópio, tente ver o sinal na saída do receptor para ver como é a situação de interferência de sua região. A propósito, qual é o modelo de tx que está usando? Http?

      Claudio
      Claudio

  4. Boa noite Sr. Cláudio. Como estão as coisas? Estou com uma dúvida. Tentei compilar seu código em C utilizando um PIC18F4550 e não consegui fazê-lo funcionar. Você poderia me dar alguma dica. Utilizei os mesmos pinos que estão no código atual, alterando apenas o tipo do microcontrolador. O módulo é o HT6P20B. Desde já agradeço. Um abraço.

    1. Olá Xuguinho!
      Quando migramos de um modelo de pic para outro, sempre temos que analisar a compatibilidade entre eles.
      Por ex. Temos um programa para o 12f629. Queremos migrar a 12f675. Então mudamos o programa somente trocando o arquivo ‘include’ para o mesmo. Não vai funcionar! O 12f675 tem conversor analógico/digital que toma conta dos pinos ao resetar. Temos que incluir linhas de código para desligar o conversor analógico/digital ao reiniciar o programa. Neste caso, temos poucas alterações.
      E se temos outra familia, por exemplo do 12 para o 18? Piorou mais ainda! Temos que analisar o datasheet do pic que migraremos e ver esta compatibilidade, é quais alterações terão que ser feitas. Se forem muitas, talvez seja melhor fazer um programa novo partindo do zero, para aquele modelo.
      Em resumo: Migrar um programa de um pic para outro não se trata apenas de trocar os arquivos ‘include’ e ir compilando. Somente se forem compatíveis este método irá funcionar!
      Portanto, estude o datasheet do pic18f4550 e veja o que é diferente, para alterar nas linhas de código.
      Cláudio

  5. Oi Claudio estou aguardando sua ajuda no seu projeto do receptor flex em, que achei muito legal, devido às opções de varios tx. Eu comecei aprender o assembler ja algum tempo, comecei recentemente aprender um pouco de C para Arduino, mas eu só arranho. Eu aprendi um poucos mais de ladder, devido a precisar na empresa que trabalhei muitos anos. Mas eu gosto muito do assembley, mas não tive muito tempo para me dedicar no aprimoramento dela. Inclusive baixei quase todos os programas seus programa tentar me aprimorar mais. Mas o que eu gostaria de saber também, é se você dispõe de um curso e material didático de assembley que eu poderia adquiri-lo para meu aprimoramento. Tenho algumas apostilas, mas esse material é muito tecnico, embora eu seja técnico em eletrônica, eu gostaria de material mais detalhado. Ou seja, mais fácil de assimilar.

    1. Olá Gralves!
      Fiz a montagem no protoboard e defini para ht6p20b, pulso, pic 12f675, aprender individual, saida normal, e compilei gerando o hex.
      Testei com varios controles e funcionou normalmente. Gravei um botão de um controle e depois o outro e também com os 2 botões acionados (o terceiro botão de alguns controles). Também repeti com outro controle e todos estão funcionando normalmente depois do aprendizado. Deve haver algum erro na sua compilação ou na montagem.
      Eu não tenho curso ou mesmo artigos específicos sobre a linguagem ‘assembly’ que possa ser de ajuda. Poderá pesquisar na internet que temos uma fartura de material. O youtube tem muitos cursos que poderão ser de ajuda. Para compreender programas em C, poderá usar o arquivo .List para ter uma ideia de como o programa foi montado. Obtenha clicando aqui estes arquivos para você testar.
      Cláudio

      1. Boa noite Claudio. Obrigado pelo retorno. Eu fiz o teste com quatro TX. Os quatros deles usam um o HT6P20B. Dois usam um oscilador 433, ajustado com trimmer. Os outros dois usam um oscilador R980 para gerar a portadora 433. Mas eu consegui inicialmente com um da VSEG que usa o R980, e o outro ja JFL que usa esse oscilador eu no consegui. Passei o osciloscopio no da jfl, que uso muito para centrais de alarme para ver se conceguia descobrir o problema, não consegui ainda. Vou usar o da VSEG que ficou blz.

        1. Olá Gralves! Eu não conheço estes controles, mas sei que o Ht6p20b tem um resistor e um capacitor para escolher uma dada frequência de trabalho. Verifique se são diferentes nestes controles.
          Cláudio

Comments are closed.

Back To Top