FAÇA UM RECEPTOR PARA CONTROLE REMOTO INFRAVERMELHO DE 8 CANAIS – COM PIC 16F628A (REF132)

Quem não gosta da comodidade de apertar um simples botão do controle remoto para ligar algum aparelho? Que tal mais uma montagem, mas com 8 canais?

Esta versão usa o PIC16F628A, sendo que este PIC tem mais pinos (18), para obtermos os 8 canais desejados.
Diferentes das outras montagens, esta usa o protocolo ‘Sony’ de 12 bits para comandar o acionamento das cargas. Para testes, foi usado um controle universal _RCA _SystemLink_4, programado com o código ‘002’(Sony). Veja o esquema da montagem abaixo:

Segue basicamente os mesmos blocos de sáidas das montagens anteriores, usando um transistor para comandar um rele de 12 volts, cujos contatos irá acionar a carga desejada. Foi usado um receptor de sinais infravermelho TSOP 1550 (que estava disponível), mas poderá ser experimentado o uso de outros modelos. A fonte de alimentação deverá fornecer 5 volts para o PIC e 12 volts para os reles. O hobista poderá optar por usar um transformador de 12 volts com diodos retificadores, capacitores de filtros e um regulador 7805 para os 5 volts regulados ou ainda, usar um adaptador de parede de 12 volts, usando apenas um 7805 para derivar a alimentação do PIC.
Para programar as teclas, deverá ser apertado a tecla ‘PROG’ por 2 segundos, até que o led 1 comece a piscar. Em seguida, escolhemos a tecla que queremos memorizar e a apertamos. O led 2 passará a piscar. Escolha outra tecla e aperte, e faça isto sucessivamente até gravar as 8 teclas desejadas.
Quando for gravado as 8 teclas, todos os leds inicialmente se acenderão para indicar de devemos escolher o modo de operação de cada saída. Elas podem ser de acionamento momentãneo (modo ‘Pulso’) ou poderá ser de modo ligado com um toque e desligado com outro toque (modo de ‘Retenção’). Deixando apagado os leds, será modo ‘Retenção’e aceso será ‘Pulso’. Aperte cada tecla gravada para fazer esta escolha individual de modo de operação (cada aperto basculará a saída, ora acendendo ora apagando o led correspondente). Em seguida, para sair do modo de programação, aperte por 2 segundos o botão ‘PROG’ e solte-o quando apagar todos os leds acesos (obs. Caso tenha programado todos os canais para modo ‘retenção’ ou seja, com todos os leds apagados,então neste caso, deverá apertar o botão ‘prog’ até começar a piscar o primeiro led e mantenha apertado até parar de piscar, soltando imediatamente o botão, saindo assim, do modo de programação).
Após sair do modo de programação, faça uma verificação, apertando as teclas programadas e veja se estão correspondendo a programação desejada. Caso encontre algum erro, repita a programação quantas vezes for necessário, lembrando que tem que gravar todas as teclas primeiro para depois poder gravar o modo de operação (pulso ou retençao) de cada canal.
Obs. Esta montagem é de caráter didático, sendo realizada somente em placa de protoboard, sujeita a bugs ainda não observados. Esta sendo fornecido os arquivos que poderão ser alterados segundo a necessidade do hobista.

Segue pasta compactada com arquivo ‘C’ e Hex para esta montagem:

infra_sony_8canais

Manuais:
PIC16F628A
PROTOCOLO _SONY

Outros assuntos:
Por que se preocupar com a exposição ao sol?
A asa da borboleta
Poder criativo — “Aquele que fez o céu e a terra”
Fim do mundo — do que as pessoas têm mais medo
O quase indestrutível urso d’água
Monteverde — uma reserva natural nas nuvens
Fogos de artifício que encantam
“Nunca chove em Lima?”
A anaconda revela alguns dos seus segredos
Fogo! Que tipo de extintor usar?
Por que alguns cientistas acreditam em Deus
“Não se esqueça de levar o guarda-chuva!”

Orientações para uma vida melhor:
Por que continuar? Três razões para não desistir da vida
Qual é o sentido da vida?
“Tenho certeza de que existe um Criador”
A verdade sobre magia, encantamento e feitiçaria
Como posso causar uma boa impressão?
Transtornos de humor – Como obter alívio
Como resolver problemas no casamento
Aprenda a perdoar
Como lidar com os sogros
Como criar filhos responsáveis
Como administrar o seu dinheiro
Ensine valores morais a seus filhos
Como evitar ferir com palavras?
Como tratar seu cônjuge com respeito?

Até o próximo artigo!

27 comments on “FAÇA UM RECEPTOR PARA CONTROLE REMOTO INFRAVERMELHO DE 8 CANAIS – COM PIC 16F628A (REF132)

  1. Caro Claudio montei seu circuito no protoboard , funcionou , montei a placa e está funcionando perfeitamente.Muito obrigado e parabéns.Agora queria alterar o projeto p/ que funcionasse com o controle remoto da minha TV(LG – LED).Vc poderia me ajudar?Não sei qual o protocolo nem como alterar o programa.

    1. Olá EURI!
      Fico feliz pelo seu sucesso! Existem inúmeros protocolos para controle remoto, e de tempos em tempos, as fabricantes trocam de protocolo. Não saberia te informar qual deve ser o seu. Tente pesquisar na internet para obter mais informações. Alterar o protocolo se torna também complicado. Toda a rotina tem que ser alterada e não conheço muitas. Se precisar usar muitos tipos, alguns hobistas tem usados as bibliotecas do Arduino para obter informações, ou então criar uma na raça, por estudar o protocolo em detalhes.
      Cláudio

  2. Olá Claudio, fiz uma alteração neste programa para funcionar com protocolo NEC, mas ocorreu o seguinte erro: Aperto PROg e gravo os botões funciona normal depois aperto PROG de novo para apagar os LEDs pois quero todos em modo pulso. Quando aperto qualquer botão do controle só o 1º LED acende, os outros não não obedece as teclas que foram gravadas.
    Segue o Código em C:
    include
    #use delay(clock=4000000)
    #fuses NOWDT,INTRC_IO, NOPUT, NOPROTECT, BROWNOUT, MCLR, NOLVP, NOCPD
    #use fast_io(A) // sentido das portas feita pelo programador
    #use fast_io(b) // sentido das portas feita pelo programador
    #ZERO_RAM
    #rom 0x2110={1,1,1,1,1,1,1,1}

    //==============================================================================
    // REGISTRADORES
    //==============================================================================
    #byte porta = 0x05
    #byte portb = 0x06
    #byte tmr0 = 0x01
    #byte trisa = 0x85
    #byte trisb = 0x86
    #byte t1con =0x10
    #byte tmr1h =0x0f
    #byte tmr1l =0x0e
    #byte pir1 =0x0c
    #byte tmr1h =0x0f
    #byte tmr1l =0x0e
    #byte intcon =0x8b
    #byte status =0x03
    //==============================================================================
    // DEFINIÇÃO DE PINOS E SAIDAS
    //==============================================================================
    #bit s1 = 0x6.0 //pino 6
    #bit s2 = 0x6.1 //pino 7
    #bit s3 = 0x6.2 //pino 8
    #bit s4 = 0x6.3 //pino 9
    #bit s5 = 0x6.4 //pino 10
    #bit s6 = 0x6.5 //pino 11
    #bit s7 = 0x6.6 //pino 12
    #bit s8 = 0x5.6 //pino 15

    #bit _in = 0x6.7 //pino 13
    #bit _prog = 0x5.2 //pino 1
    //#bit _prog = 0x6.7 //pino 13

    #bit cy = 0x3.0 //carry bit
    #bit on_tmr1 = 0x10.0 //on/off tmr1
    #bit fov1 = 0x0c.0//flag over flow do tmr1
    #bit tmr1if = 0x0c.0 //flag over flow do tmr1
    #bit tmr0if = 0x8b.2//flag over tmr0
    //#define prog pin_b7
    #define in pin_b7 //pino 13
    #define prog pin_a2 //pino1 sw de programação
    //#priority RA,timer0
    //==============================================================================
    // CONSTANTES GERAIS
    //==============================================================================
    //int const qbits = 12; //quantidade de bits a receber ‘sony’
    int const qbits = 32; //quantidade de bits a receber ‘nec’
    int const TLIGADO=30; //10; //tempo mínimo para manter acionamento com botão apertado
    int const TINITPROG=150; // tempo mínimo para iniciar ‘modo de programação’
    int const TIME_RX_ON=0x20;
    //==============================================================================
    // VARIÁVEIS GLOBAIS
    //==============================================================================

    int qb,passo,ax1,cnt1,cnt2,cnt3,cnt4,cnt5,cnt6,cnt7,cnt8,cntp1,grcnt;
    int buffer[4];
    short pisca,flag_prog,flag_prap,flag_rok;
    short flag_m1, flag_m2, flag_m3,flag_m4,flag_m5, flag_m6,flag_m7,flag_m8;
    short fs1,fs2,fs3,fs4,fs5,fs6,fs7,fs8,flag_stop;
    //==============================================================================
    // SUBROTINAS E FUNÇÕES GERAIS
    //==============================================================================

    //==============================================================================
    // GRAVA EEPROM
    //==============================================================================
    void grava( int a,int b){
    if(!flag_stop){
    disable_interrupts(GLOBAL);
    write_eeprom(a,b);
    enable_interrupts(GLOBAL);
    }
    }

    short mem(int a){

    return ((buffer[0]== read_eeprom(a))&&(buffer[1]== read_eeprom((a+1))));

    }

    //==============================================================================
    // grava memória
    //==============================================================================

    short rx_gr(void) {

    if((flag_rok)&&(!flag_stop)){

    grava(passo,buffer[0]);
    grava(passo+1,buffer[1]);
    passo+=2;
    flag_stop=1;
    return 0;}
    else { return pisca;}
    }

    //==============================================================================
    // INTERRUPÇÃO POR MUDANÇA DE ESTADO – RECEPÇÃO DO CONTROLE IR (PADRÃO ‘NEC’)
    //==============================================================================
    #int_RB
    void rx_nec_mudanca_gp3() {
    int16 const LIMITE_BYTE_LOW=1200, PULSO_9MS=7000,PULSO_4MS=3800;
    static int16 ref,gt;
    static short ov1,flag_p;

    portb|=portb; //ler port para conseguir zera gpif (DS41190C-page 21)
    if(!flag_rok){
    on_tmr1=0; ov1=tmr1if; gt=get_timer1(); set_timer1(0);
    tmr1if=0; on_tmr1=1;//desliga timer1/pega valor/zera e religa

    cnt1=TLIGADO;
    cnt2=TLIGADO;
    cnt3=TLIGADO;
    cnt4=TLIGADO;
    cnt5=TLIGADO;
    cnt6=TLIGADO;
    cnt7=TLIGADO;
    cnt8=TLIGADO;

    if(!input(in)){ //input=’0′
    if((gt>PULSO_9MS)||(ov1)){ qb=qbits;}

    if(flag_p){
    shift_right(&buffer[0],4,(gt>ref));
    if(–qb==0) { qb=qbits;
    //if ((buffer[0]+buffer[1]==0xff)&&(buffer[2]+buffer[3]==0xff)){ flag_rok=1;}
    if (!(buffer[0]+buffer[1]+buffer[2]+buffer[3]+0x2)){ flag_rok=1;}
    }
    }
    }
    else{ //input=’1′
    if((gt>PULSO_4MS)||(ov1)){ qb=qbits; flag_p=0;}
    else {
    if((gt<LIMITE_BYTE_LOW)&& (!ov1)&& (!flag_p)){
    flag_p=1; qb=qbits; ref=gt; ref<=6) {
    pisca=!pisca;
    t1_int=0;

    if(++ax1==0) –ax1;
    }
    }
    else{ pisca=0;}
    }

    //==============================================================================
    //
    // PROGRAMA PRINCIPAL
    //
    //==============================================================================

    void main() {

    //==============================================================================
    // INICIALISAÇÃO DE PORTAS E REGISTRADORES
    //==============================================================================

    setup_comparator(NC_NC_NC_NC);
    setup_vref(FALSE);
    setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_1 );
    portb=0;
    porta=0;
    ax1=0;
    pisca=0;
    trisa=0b00100100; //tudo saída exceto mcrl/vpp e ra2
    trisb=0b10000000; //tudo saída exceto b7 entrada
    set_timer1(0); //zera tmr1
    tmr1if=0 ; //apaga flag over flow
    on_tmr1=1;//liga timer1
    setup_counters(RTCC_INTERNAL,RTCC_DIV_256);
    enable_interrupts(INT_RB);//habilita interrupção por mudança de estado
    enable_interrupts(global);
    delay_ms(20);
    cntp1=TINITPROG;
    qb=qbits;//carrega quantidade de bits a receber
    passo=0;// bit_set(t1con,0);
    flag_rok=0;
    flag_stop=0;
    grcnt=0;

    //==============================================================================
    // LOOP PRINCIPAL
    //==============================================================================
    while(true){
    delay_ms(10); //atraso temporização correta do desligamento (modo Pulso)
    //==============================================================================
    // Desligamento de saídas em modo pulso
    //==============================================================================

    if(!flag_prog){
    if(flag_m1){ if(–cnt1==0) s1=0;}//desliga saidas em modo ‘pulso’
    else { if(–cnt1==0) fs1=0;}

    if(flag_m2){ if(–cnt2==0) s2=0;}
    else { if(–cnt2==0) fs2=0;}

    if(flag_m3){ if(–cnt3==0) s3=0;}
    else { if(–cnt3==0) fs3=0;}

    if(flag_m4){ if(–cnt4==0) s4=0;}
    else { if(–cnt4==0) fs4=0;}

    if(flag_m5){ if(–cnt5==0) s5=0;}
    else { if(–cnt5==0) fs5=0;}

    if(flag_m6){ if(–cnt6==0) s6=0;}
    else { if(–cnt6==0) fs6=0;}

    if(flag_m7){ if(–cnt7==0) s7=0;}
    else { if(–cnt7==0) fs7=0;}

    if(flag_m8){ if(–cnt8==0) s8=0;}
    else { if(–cnt8==0) fs8=0;}

    }

    //=============================================================================
    // TESTA BOTÃO ‘PROG’ (INICIO/FIM DE MODO DE PROGRAMAÇÃO)
    //==============================================================================

    if(!input(prog)) {

    if(–cntp1==0) {
    cntp1=TINITPROG;
    if(flag_prog){ flag_prog=0; pisca=0;
    flag_prap=0;
    disable_interrupts(int_timer0);}
    else { flag_prog=1; passo=0; pisca=1; enable_interrupts(int_timer0);}
    porta=0;
    portb=0;
    }
    }
    else
    { cntp1=TINITPROG;}

    //==============================================================================
    // PROGRAMAR TECLAS DO CONTROLE REMOTO NA EEPROM -MODO DE PROGRAMAÇÃO
    //==============================================================================

    if(–grcnt==0xff){grcnt=0; flag_stop=0;};

    if(flag_prog){
    int a;

    switch (passo){
    case 0:
    s1=rx_gr();

    break;
    case 2:
    s2=rx_gr();
    break;
    case 4:
    s3=rx_gr();
    break;
    case 6:
    s4=rx_gr();
    break;
    case 8:
    s5=rx_gr();
    break;

    case 10:
    s6=rx_gr();
    break;
    case 12:
    s7=rx_gr();
    break;
    case 14:
    s8=rx_gr();
    break;

    case 16:

    flag_stop=0;
    for(a=0;a<8;++a) {grava(a+16,1); } //coloca todas saidas em modo pulso
    flag_stop=1;
    passo=17;
    break;

    case 17:
    if(!read_eeprom(16)){ flag_m1=0; s1=0; }
    else{flag_m1=1; s1=1; }
    if(!read_eeprom(17)){ flag_m2=0; s2=0; }
    else{flag_m2=1; s2=1; }
    if(!read_eeprom(18)){ flag_m3=0; s3=0; }
    else{flag_m3=1; s3=1; }
    if(!read_eeprom(19)){ flag_m4=0; s4=0; }
    else{flag_m4=1; s4=1; }
    if(!read_eeprom(20)){ flag_m5=0; s5=0; }
    else{flag_m5=1; s5=1; }
    if(!read_eeprom(21)){ flag_m6=0; s6=0; }
    else{flag_m6=1; s6=1; }
    if(!read_eeprom(22)){ flag_m7=0; s7=0; }
    else{flag_m7=1; s7=1; }
    if(!read_eeprom(23)){ flag_m8=0; s8=0; }
    else{flag_m8=1; s8=1; }
    passo=18;
    break;

    case 18:

    if(flag_rok){
    if(mem(0)){
    if(read_eeprom(16)){ flag_m1=0; s1=1; }
    else{flag_m1=1; s1=0; }
    grava(16,flag_m1);
    flag_stop=1;
    }
    else
    if(mem(2)){
    if(read_eeprom(17)){ flag_m2=0; s2=1; }
    else{flag_m2=1; s2=0; }
    grava(17,flag_m2);
    flag_stop=1;
    }
    else

    if(mem(4)){
    if(read_eeprom(18)){ flag_m3=0; s3=1; }
    else{flag_m3=1; s3=0; }
    grava(18,flag_m3);
    flag_stop=1;
    }
    else

    if(mem(6)){
    if(read_eeprom(19)){ flag_m4=0; s4=1; }
    else{flag_m4=1; s4=0; }
    grava(19,flag_m4);
    flag_stop=1;
    }
    else

    if(mem(8)){
    if(read_eeprom(20)){ flag_m5=0; s5=1; }
    else{flag_m5=1; s5=0; }
    grava(20,flag_m5);
    flag_stop=1;
    }

    else

    if(mem(10)){
    if(read_eeprom(21)){ flag_m6=0; s6=1; }
    else{flag_m6=1; s6=0; }
    grava(21,flag_m6);
    flag_stop=1;
    }
    else

    if(mem(12)){
    if(read_eeprom(22)){ flag_m7=0; s7=1; }
    else{flag_m7=1; s7=0; }
    grava(22,flag_m7);
    flag_stop=1;
    }

    else
    if(mem(14)){
    if(read_eeprom(23)){ flag_m8=0; s8=1; }
    else{flag_m8=1; s8=0; }
    grava(23,flag_m8);
    flag_stop=1;
    }

    } //if(flag_rok)
    }//switch(passo)

    flag_rok=0; //libera nova recepção

    }//if(flag_prog)

    //=============================================================================
    // ACIONAR SAÍDAS CONFORME PROGRAMAÇÃO
    //==============================================================================

    if((!flag_prog)&&(flag_rok)){
    if(mem(0)){
    if(read_eeprom(16)){s1=1;flag_m1=1;cnt1=TLIGADO;}
    else { if (!fs1){s1=!s1; flag_m1=0;fs1=1;}
    }
    }
    else
    if(mem(2)){
    if(read_eeprom(17)){s2=1;flag_m2=1;cnt2=TLIGADO;}
    else { if (!fs2){s2=!s2; flag_m2=0; fs2=1;}
    }
    }

    else
    if(mem(4)){
    if(read_eeprom(18)){s3=1;flag_m3=1;cnt3=TLIGADO;}
    else { if (!fs3){s3=!s3; flag_m3=0; fs3=1;}
    }
    }
    else
    if(mem(6)){
    if(read_eeprom(19)){s4=1;flag_m4=1;cnt4=TLIGADO;}
    else { if (!fs4){s4=!s4; flag_m4=0; fs4=1;}
    }
    }
    else
    if(mem(8)){
    if(read_eeprom(20)){s5=1;flag_m5=1;cnt5=TLIGADO;}
    else { if (!fs5){s5=!s5; flag_m5=0; fs5=1;}
    }
    }

    else
    if(mem(10)){
    if(read_eeprom(21)){s6=1;flag_m6=1;cnt6=TLIGADO;}
    else { if (!fs6){s6=!s6; flag_m6=0; fs6=1;}
    }
    }
    else
    if(mem(12)){
    if(read_eeprom(22)){s7=1;flag_m7=1;cnt7=TLIGADO;}
    else { if (!fs7){s7=!s7; flag_m7=0; fs7=1;}
    }
    }
    else
    if(mem(14)){
    if(read_eeprom(23)){s8=1;flag_m8=1;cnt8=TLIGADO;}
    else { if (!fs8){s8=!s8; flag_m8=0; fs8=1;}
    }
    }

    flag_rok=0;
    }
    }//void while(true)
    }//void main

    1. Olá Renato!
      Migrar de um protocolo para outro geralmente tende a dar este tipo de problema. Tente gravar os controles de forma normal e depois ler a eeprom com o programador para ver se efetivamente foram gravadas as teclas bem como a situação das mesmas (retenção/pulso). Estude bem a diferença do protocolo Sony em relação ao Nec, e veja se não está esquecendo algo, nas linhas de código.
      Cláudio

      1. Olá novamente, consegui alterar o programa para o protocolo NEC, mas quando programo os 8 botões todos os leds se apagam, escolho se devem ficar acesos ou apagados, mas não adianta sempre ficam em modo retenção.
        PS: tem como editar a postagem acima, postei o código todo aí e ficou muito grande atrapalhando o blog.

        1. Olá Renato!

          Você está indo bem. Tente conferir, se na eeprom, se realmente está programando para modo pulso. Isto pode ser feito lendo somente a eeprom com o programador de pic que você está usando. A partir da posição 16 (0010h) começa os valores para retenção (0) ou pulso (1). Todos os gravados para pulso devem estar em 0001h conforme o número do controle gravado (16 + número do controle entre 0 e 7). Se estiver gravando corretamente, tente ver se não esqueceu algo na parte de acionamento da saída.
          Cláudio

          1. Não está gravando todos os valores estão em “0” para retenção, quando alterei manualmente pelo gravador funcionou o modo pulso.

          2. Olá Renato!
            Muito bom! Você já tem o diagnóstico! Verifique as rotinas que fazem a gravação em modo pulso, pois sabemos que o problema esta nesta área.
            Cláudio

          3. Olá Renato!
            Parabéns pelo seu esforço e por compartilhar conosco! Com certeza a persistência permite bons resultados!

            Cláudio

    1. Olá Tiago! Cada fabricante escolhe qual protocolo irá usar em seu equipamento. As vezes, ao longo da produção e novos produtos, podem mudar de um para outro. Existe muitíssimos protocolos para controles remotos infravermelhos. O que muda é a rotina de recepção para cada protocolo. Infelizmente, não disponho de biblioteca para outros protocolos senão os que foram postados. Procure usar um controle remoto universal que fica mais fácil utilizar as montagens aqui postadas.
      Cláudio

  3. lario boa tarde.para este projeto qualquer controle ramoto da sony serve?visto que e de grande ajuda para me que tenho grande apreço por projeto desta altura.obrigado.

    1. Olá José!
      Esta é uma pergunta difícil!
      Usei um controle remoto universal RCA systemlinker4 com o primeiro código da Sony. Não sei se todos os outros funcionam. Infelizmente, terá que testar se desejar saber.
      Cláudio

Comments are closed.

Back To Top