FAÇA UM CONTROLE REMOTO DE 5 CANAIS (RF)- COM PIC 12F675 (REF 156)

Os controles remotos tipo chaveirinho permite usar apenas 2 ou 3 botões de acionamento. E se você deseja 5 botões?

Neste caso, terá que fazer seu próprio chaveirinho. Uma boa alternativa é usar um pequeno Pic 12f675 de 8 pinos, relativamente barato, para produzir o protocolo de transmissão para um tx comercial de 433mhz (miniatura). Veja o Esquema abaixo:

Com 5 chaves dactilares, e alguns resistores, podem ser facilmente acondicionados em uma pequena caixa plastica, escolhida a gosto pelo hobista. Poderá ser alimentado com uma bateria de 12 volts, reduzindo-se a tensão por meio de um ci regulador do tipo 7805. Ou pode-se usar 4 pilhas de 1,5 volts, com um diodo em série para reduzir a nivel seguro de operação.
O protocolo transmite 4 bytes, sendo 2 bytes de um número serial qualquer, a ser escolhido pelo hobista, e que deverá ser usado tanto no tx como no rx. Neste caso, foi usado o numero 0x89ab. O próximo byte é uma cópia da gpio, mostrando a condição das chaves dactilares. E finalmente o último byte é a somatória dos 3 primeiros, servindo de conferência para a integridade da transmissão.
No receptor, foi previsto a escolha de modo pulso ou retenção pelo usuário, alterando de forma individual, por canal. O mesmo pode ser dito se queremos saída em modo normal ou invertida. Basta alterarmos estas definições por comentar (//) ou descomentar a opção desejada e em seguida, recompilar o arquivo C. Na pasta fornecida abaixo, temos um hex pronto para modo normal e retenção em todos os canais. O hex para o tx não sofre mudanças com as alterações de modo pulso/retenção ou mesmo modo normal/retenção, sendo sempre o mesmo.
No esquema do receptor foi usado reles nas saídas, para controlar cargas, mas nada impede usar apenas transistores de potencia para controlar diretamente pequenos motores ou conjuntos de leds, bem como outras cargas desejadas. Para uso com cargas AC, convém manter os reles, isolando assim o circuito das cargas.
Obs. Esta montagem foi feita unicamente em placa de protoboard, sendo sujeita a bugs ainda não detectados. Esta sendo fornecido os arquivos que poderão ser alterados conforme a necessidade dos hobistas.

Segue pasta com os arquivos desta montagem:

CR_5C_675

Poderá ver também o artigo ‘CONTROLE REMOTO 8 CANAIS ON/OFF – PIC 16F628A’, para 8 canais.

Em 18/12/2014, foi postado esta nova versão de receptor, que testa por 2 recepções corretas antes de acionar saídas as saídas (medida para evitar falsos acionamentos em áreas com muita interferências):

cr_5c_675_v2_

Manuais:

Pic 12f675

Curiosidades:

Mestres medievais da medicina
Mestres medievais da mecânica
O coletor solar da asa da borboleta
Será que a Bíblia está de acordo com a ciência?
Ainda há tempo para salvar o planeta?
Como vencer a estafa
Uma visita a Camarões
Os sensores do besouro
Como posso lidar com o estresse?
Você acredita que já viveu antes?

Outros assuntos:
Como se livrar do ressentimento
Como ensinar seu filho a usar a internet com segurança
Por que rejeitar a pornografia?
Como ser feliz no casamento?
Quando seu casamento não é o que você esperava
Como resolver diferenças no casamento
Como recuperar a confiança no casamento
Quando um dos cônjuges tem necessidades especiais
Aprenda a perdoar
Como acabar com a tática do silêncio
Como criar filhos responsáveis
Como administrar o seu dinheiro
Como posso controlar meu peso?
Como evitar ferir com palavras?
Como tratar seu cônjuge com respeito?

Até o próximo artigo!!!

81 comments on “FAÇA UM CONTROLE REMOTO DE 5 CANAIS (RF)- COM PIC 12F675 (REF 156)

  1. Amigo uma duvida que me apareceu sobre este projeto ela suprotaria gravar o controle comercial ?
    tipo gravar 3 teclas de um e 2 teclas de outro ?
    ou fica preso ao TX ?

    1. Olá Liliano!
      Realmente, isto não é possível, pois não há compatibilidade entre o controle remoto comercial e esta montagem , estando ‘preso’ ao TX.
      Cláudio

  2. Olá Larios… vou te encher de novo. Tô com um probleminha aqui e talvez você possa me dar uma luz! Gostaria de implementar via código um tipo de teste para validar o acionamento do botão, algo assim:

    Receptor detecta o acionamento do botão;
    Receptor aguarda um tempo e verifica se o botão continua acionado;

    Somente após esta verificação é que eu iria acionar ou não a saída do pic.

    Estou tendo alguns problemas com disparo acidental (mesmo com o transmissor desligado) acho que pode ser algum ruido no receptor e gostaria de eliminar esta possibilidade via programação… Como sempre muito grato pela atenção.

    Obs: A saída do meu RX é ativo em nível baixo, até já coloquei uns resistores de pull up para ver se resolveria o problema mas sem sucesso.

    1. Olá Karllo! A faixa de frequência de 433Mhz já está se tornando saturada com tantos tx de portões hoje em dia. Você diz, se eu entendi bem, para aguardar uma segunda transmissão após um tempo, para confirmar entre um possível falso acionamento de um verdadeiro acionamento, é isto? Se a interferência não for cíclica, poderá funcionar. Poderia compartilhar em que está usando o sistema?
      Cláudio

      1. O acionamento não é cíclico… Eu não gostaria de passar os detalhes do projeto por aqui, mas me envie um e-mail que te explico direitinho, é um projeto muito legal.

        Tentei executar a procedimento “recebe()” duas vezes dentro do laço while (com um buffer auxiliar) com intuito de comparar as 2 recepções e não funcionou.

        Você teria alguma sugestão de onde eu poderia estar modificando o código?

        Grato.

        1. Olá Karllo!
          Tente estas alterações (não tive chance de testa-la), que tem por objetivo realizar 2 recepções corretas antes de acionar as saídas. Foi colocado um contador aux_seg que depois de certo tempo reseta para impedir uma segunda recepção que não seja dentro de um tempo específico.

          while(true){
          int8 conf,aux,aux_ret;
          //—————————————————————————
          int1 flag_acionar,flag_1rec; //<——acrescentar
          int8 aux_seg; //<——acrescentar

          if(!–aux_ret){aux_ret=250; at_cont_ret();}
          if(!–aux_seg) {aux_seg++;flag_1rec=0;} //<——acrescentar

          flag_rok=0; // <—–acrescentar
          recebe(); // <—–acrescentar
          if((flag_rok)&&(!flag_1rec)){
          conf=buffer[1]+buffer[2]+buffer[3];
          if(conf==buffer[0]){flag_1rec=1;aux_seg=0xff;}// // <—–acrescentar
          }
          flag_rok=0;
          recebe();
          if((flag_rok)&&(flag_1rec)){
          conf=buffer[1]+buffer[2]+buffer[3];
          if(conf==buffer[0]){flag_acionar=1; }
          }

          if(flag_acionar){ // <—–acrescentar
          flag_1rec=0; // <—–acrescentar
          flag_acionar=0; // <—–acrescentar

          //if(flag_rok){ //<—comentar
          // conf=buffer[1]+buffer[2]+buffer[3]; //<—comentar
          // if(conf==buffer[0]){ //<—comentar

          //——————————————————————————————-

          if((buffer[3]==make8(serial_number,1))&&(buffer[2]==make8(serial_number,0))){
          aux=buffer[1];

          if(!bit_test(aux,3)){
          cont_c1=t_inv;
          #ifdef c1_ret
          if(!fc1){
          c1=!c1; fc1=1;
          }
          #else
          #ifdef c1_inv
          c1=0;
          #else
          c1=1;
          #endif
          #endif
          }
          if(!bit_test(aux,1)){
          cont_c2=t_inv;
          #ifdef c2_ret
          if(!fc2){
          c2=!c2; fc2=1;
          }
          #else
          #ifdef c2_inv
          c2=0;
          #else
          c2=1;
          #endif
          #endif
          }

          if(!bit_test(aux,2)){
          cont_c3=t_inv;
          #ifdef c3_ret
          if(!fc3){
          c3=!c3; fc3=1;
          }
          #else
          #ifdef c3_inv
          c3=0;
          #else
          c3=1;
          #endif
          #endif
          }

          if(!bit_test(aux,4)){
          cont_c4=t_inv;
          #ifdef c4_ret
          if(!fc4){
          c4=!c4; fc4=1;
          }
          #else
          #ifdef c4_inv
          c4=0;
          #else
          c4=1;
          #endif
          #endif
          }

          if(!bit_test(aux,5)){
          cont_c5=t_inv;
          #ifdef c5_ret
          if(!fc5){
          c5=!c5; fc5=1;
          }
          #else
          #ifdef c5_inv
          c5=0;
          #else
          c5=1;
          #endif
          #endif
          }

          // } //<—comentar /////////////////////////////////////////////////////////////////<———————–não esqueça aqui
          }
          flag_rok=0;
          }//if(flag_rok) // agora será flag_acionar
          }//while
          }//main

          Cláudio

          1. Claudio;

            Antes de mais nada tú é meu salvador, obrigado!

            Fiz a seguinte alteração (acho que está errado no código acima)

            flag_rok=0; //*aqui troquei por flag_acionar = 0;*
            }//if(flag_rok) // agora será flag_acionar
            }//while
            }//main

            Só que o saída não está ativando, ou seja não entra no “if((flag_rok)&&(flag_1rec))” logo o flag_acionar nunca vai para “1”.

            Vou estudando aqui para ver se acho a solução, estou aguardando seu e-mail para lhe passar os detalhes do projeto. Abraço!

          2. Fui testando aqui e vi que no primeiro recebe() a transmissão é validada (flag_1rec fica igual a “1”), porém no segundo recebe() o flag_rok sempre fica em “0”, logo o flag_acionar sempre será “0”.

          3. Olá Karllo!
            Eu analisei melhor o código passado, e notei que fiz um erro de grafia:
            Veja a porção abaixo:
            while(true){
            int8 conf,aux,aux_ret;
            //—————————————————————————
            int1 flag_acionar,flag_1rec; //<——acrescentar
            int8 aux_seg; //<——acrescentar

            if(!–aux_ret){aux_ret=250; at_cont_ret();}

            //————
            if(!–aux_seg) {aux_seg++;flag_1rec=0;} //<——acrescentar xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx aqui tem erro

            modifique esta linha para:

            if(!aux_seg- -) {aux_seg++;flag_1rec=0;} //<——acrescentar

            E experimente, por favor.
            Não estou conseguindo tempo para montar no protoboard para testes. Se não der certo, peço que aguarde até que possa verificar na prática o que me pede.
            Cláudio

          4. Você já está fazendo demais… Tenho uma placa de teste e ainda analiso no proteus antes…
            Fiz a substituição como sugerida e também não funcionou. É só comentar esta parte que consigo ativar a saída…

          5. Já ia me esquecendo… se inicializo a variável aux_seg (int8 aux_seg=0xff;) funciona perfeitamente com a última modificação que me passou… mas não sei é correto fazer isto. Grato Claudio.

          6. Olá Karllo!
            Eu postei uma nova versão com 2 recepções antes de realizar o acionamento. Tente adapta-la ao seu circuito, alterando onde você desejar.( Obs. Esta versão está ajustada para modo pulso, normal.)
            A constante ‘tempo_seg’ determina a janela máxima de tempo para uma nova recepção após uma recepção correta. Passando este tempo, o flag_1rec é resetado obrigando o sistema a ter de receber mais 2 novas recepções corretas. O registrado aux_seg ganhou um companheiro, o aux_seg1, para poder dar suficiente tempo. Ambos foram colocados como variáveis globais do sistema.
            Divirta-se!

            Cláudio

          7. Nem sei como te agradecer! Como sempre ficou ótimo! Valeu mesmo Claudio.
            Só achei que esta variável de tempo (tempo_seg) não faz muita diferença (o disparo é quase instantâneo), até alterei para int16 (também a aux_seg1) e coloquei o valor inicial em 0xFFFF. Mas vou brincando aqui…

          8. Olá Karllo!
            O objetivo da variável aux_seg1 (+ aux_seg+ tempo_seg) é disponibilizar uma janela de tempo após uma recepção correta. Você verá que, se reduzir abaixo de 0x05, já não funcionará, por não se ter tempo suficiente para uma segunda recepção . Quanto mais aumentar seu valor (como você fez colocando 0xfffff), mais estará retirando a segurança e propiciando que o ruído acione o sistema. Em resumo, maior segurança será com valores baixos obtidos experimentalmente (por volta de 0x05 para aux_seg1). Resta ver se ainda haverá os acionamentos indesejados com este ‘firewall’.
            Cláudio

  3. Olá Claudio! O serial é um número hexadecimal (16 bits)? Logo seria correto afirmar que a faixa de valores varia de 0 a 65535 em decimal? Grato.

    1. Olá Karllo!
      O seu raciocínio está correto. Mas, lembrando que a operação de 2 conjuntos (tx/rx) na mesma frequência de transmissão, apesar de ‘serial number’ diferentes, poderão sofrer mau funcionamento por interferência mutua. Apenas garante que um conjunto não acione outro de ‘serial number’ diferente, mas não garante funcionamento concomitante.
      Cláudio

      1. Eu sei! Em meu projeto o transmissor só é habilitado (energizado) no momento em que se pressiona o botão. Eu percebi essa interferência quando o portão eletrônico aqui de casa não abria de forma nenhuma, foi só desligar o transmissor e ele voltou a funcionar. Mais uma vez muito obrigado!

  4. Lários socorro! Teria como introduzir um delay de acionamento em algum dos botões no RX? Tentei adicionar um delay_us(xxx) mas não funcionou da forma esperada. Será que isto seria possível ? Aonde especificamente eu poderia estar inserindo este atraso no código fonte? Mais uma vez muito grato.

    Exemplo do que fiz na rotina “at_cont_ret()”

    if(!–cont_c5)

    delay_us(xxx);

    #ifdef c5_ret
    fc5=0;
    #else
    #ifdef c5_inv
    c5=1;
    #else
    c5=0;
    #endif
    #endif

    1. Olá Karllo! Poderia explicar melhor o assunto do delay? Você quer que depois de acionado demore a ligar a saída ou que a saída fique ligada por um tempo e desligue? O sistema de recepção neste exemplo opera ‘in-line’. Qualquer temporização colocada no meio das linhas de código irá destruir os tempos de recepção. A temporização terá que ser paralela , ou seja, a cada loop do bloco ‘while’ incrementamos um registrador e chegando a certo valor podemos desligar a saída. Para varias saídas temos que usar vários registradores.
      Para usar a rotina padrão de delay ‘delay_ms(xxxx)’ temos que mudar a rotina de recepção para o método de interrupção por mudança de estado da entrada rf ou por temporização de um timer que examina a entrada rf de tempos em tempos.
      Cláudio

      1. Claudio, quero que depois de acionado demore a ligar a saída (pulso e em nível baixo). Mas somente para um dos botões, tipo assim:

        Ch 1 -> instantâneo
        Ch 2 -> instantâneo
        Ch 3 -> instantâneo
        Ch 4 -> instantâneo
        Ch 5 -> atraso de xxx ms

        Cheguei a pensar em utilizar um 555 para resolver isso, mas o ideal seria solucionar por programação.

        Desde ja muito grato pela paciência.

        1. Olá Karllo!
          Entendi! Como já citei anteriormente, então poderá, na saída escolhida, setar um flag ao invés da saída propriamente dita, quando ocorrer o acionamento da mesma.
          Depois, no final do loop principal while(1), deverá testar este flag, e se estiver setado, começará a incrementar um ou mais registradores em cascata, e assim que atingirem determinado valor desejado que corresponda ao tempo, ligar a saída. Mas lembre que deverá ocorrer somente um incremento por ciclo do loop para não travar a recepção.
          Cláudio

  5. Olá Larios! Mais uma duvida: os capacitores para o regulador de tensão seriam pF o mF? Gostaria de informar a todos que realizei a montagem com sucesso, muito obrigado pela atenção!

Comments are closed.

Back To Top