CONTROLE REMOTO 8 CANAIS ON/OFF – PIC 16F628A

Controlar brinquedos por controle remoto tem sido um dos passatempos mais apreciados por crianças e também ‘adultos’. Muitos gastam ‘fortunas’ comprando replicas de carros, locomotivas, etc. Os menos afortunados nas finanças , preferem ser mais ‘economicos’, montando suas proprias réplicas e construindo seus próprios circuitos eletrônicos. Em alguns casos, queremos apenas controlar alguma coisa a distância, como por exemplo, um aparelho colocado no telhado ou em um prédio distante. Será que poderiamos tirar proveito das facilidades de programação de um microcontrolador para fazermos isto? Veja a resposta…

Veja o esquema abaixo:

Este projeto experimental, utiliza 2 PIC’s 16F628A , sendo um no transmissor e outro no receptor. No transmissor, temos 8 chaves ligadas aos pinos do PIC, que quando acionadas, setarão as respectivas saidas no receptor (led 0 a led 7). Esta saidas poderão controlar reles de carga, controlando assim maior potência. Cargas pequenas poderão ser controladas por transistores, também pode-se usar foto acopladores como MOC3021 para controlar triac’s diretamente em corrente alternada (lampadas, motores,etc). Use sua imaginação!!!

O protocolo usado, basicamente envia um startbit, seguido por um numero de 8 bit, correspondente ao ‘NÚMERO IDENTIFICADOR’ do aparelho, após o que, vem os 8 bits correspondentes ao estado dos botões e um intervalos final entre transmissões. A idéia do numero do aparelho, é poder usar varios conjuntos tx + rx de numeros diferentes, sem que um controle o outro (pelo menos em teoria). Este número poderá ser alterado no arquivo asm e deverá ser recompilado para obter o novo arquivo hex.
Um bit ‘0’ é formado por 1 periodo de tempo ‘low’ + 2 periodos de tempo ‘high’ na saida, pino 17. O bit ‘1’ corresponde a 2 periodos de tempo em nivel ‘low’, seguido de 1 periodo de tempo em nivel ‘high’ na saida, pino 17.
A rotina de recepção examina a cada 50 microsegundos o estado do pino 17 (entrada de rf) e se=0 incrementa o contador ‘LC’. Se for =’1′, incrementa o contador ‘HC’. A diferença entre eles corresponde ao bit a ser transferido no contador de saida (Res1,Res0). Em uma recepção bem sucedida, o byte Res0 é comparado com um número fixo do aparelho, e se for igual, irá colocar na saida (Portb), os valores recebidos. Caso cesse a transmissão, os contadores de tempos NOTX1 E NOTX, serão decrementados pela rotina, e , chegando em ‘zero’, irão apagar todas as saidas (clrf portb).

Deverá ser usado transmissor e receptor na frequencia cedida a controle remotos na faixa de 27 mhz . Existe muitos vendidos comercialmente, mas poderão ser também montados. Abaixo temos um exemplo ilustrativo de circuito transmissor e receptor, comum nos sites da internet, (porém, não tendo sido testado por mim, nem tenho algum em especial para recomendar):

Como se trata de uma montagem experimental, foi testada apenas em protoboard, com um tx + rx de 433 mhz, mas, para uso em brinquedos, não é permitido, porque nesta frequencia, poderá atrapalhar o funcionamento de equipamentos como portões, alarmes, etc.

Segue abaixo o arquivo ASM para TX:

CR27_TX_ASM

Segue abaixo o arquivo HEX para TX:

CR27_TX_HEX

Segue abaixo o arquivo ASM para RX:

CR27_RX_ASM

Segue abaixo o arquivo HEX para RX:

CR27_RX_HEX

Adicionalmente, pode-se aproveitar as portas que sobram do portA para colocar uma chave ‘DIP’ externa, com o
objetivo de com um único transmissor, poder controlar vários receptores que usem o mesmo ‘serial number’ escolhido no ASM.
Aquele que tiver a combinação da chave “DIP’ igual a do transmissor é que será acionado naquele momento.
Veja o esquema para esta opção de montagem abaixo:

Como temos 6 bits disponíveis, isto permite usar até 64 receptores em um grupo de mesmo ‘serial number’.
Note que o acionamento é apenas momentâneo, uma vez que paramos de apertar a tecla, a saída do receptor desliga.
Assim, deverá ser previsto circuitos do tipo flip-flop ligados na saída do microcontrolador, quando se desejar funções de ‘retenção’.

Segue o arquivo ASM do TX desta versão com chave ‘DIP’:

CR_TX_8C_SEL_ASM

Segue o arquivo HEX do TX desta versão com chave ‘DIP’:

CR_TX_8C_PROG_HEX

Segue o arquivo ASM do RX desta versão com chave ‘DIP’:

CR_RX_8C_SEL_ASM

Segue o arquivo HEX do RX desta versão com chave ‘DIP’:

CR_RX_8C_PROG_HEX

Em 15/03/2014, foi realizado modificações no receptor para que se possa escolher entre modo pulso ou retenção, alterando o ASM e recompilando. O esquema é o mesmo, apenas foi ajustado o arquivo ASM. Portanto, segue abaixo a pasta com esta nova versão configurável pino a pino de saída, com atualização em 01/12/2015 (eliminado bug que alternava saída em modo retenção se interruptor fosse continuamente acionado):

CR_8C_PROG_RET_v4

Em 16/12/2015 foi feita esta versão abaixo que grava na EEprom a situação das saídas programadas para modo ‘Retenção’, retornando os valores após um reset (como na falta de energia elétrica da rede doméstica):

CR_8C_SEL_RET_V5_EEPROM_FILES

Caso queira uma versão PWM de 8 canais e 5 botões on/off veja o artigo ‘FAÇA UM CONTROLE REMOTO PWM 8 CANAIS (1MS A 2MS) – COM PIC 16F628A’
Caso deseje outra versão PWM de 2 canais e 3 botões on/off, veja o artigo ‘FAÇA UM PEQUENO CONTROLE REMOTO PWM DE 2 CANAIS (1MS A 2MS) – COM PIC 12F675’
Caso deseje ainda outra versão PWM de 2 canais (sendo uma de 0-5v) e 3 botões on/off, veja o artigo ‘FAÇA UM ‘VERSÁTIL’ CONTROLE REMOTO REMOTO – COM PIC12F675’

Curiosidades:
Filas
Petróleo – acabará algum dia?
Gás Natural – energia para o lar
Ponte da torre – Uma entrada para Londres

Outros assuntos:
Qual o objetivo dos pais ao criar os filhos?
Como lidar com os sogros?
Desempenhem bem o papel de pais
Como reagir ao assédio sexual
Como lidar com problemas financeiros e dívidas
Converse com seus filhos sobre sexo

Assista a este vídeo: O que é um amigo de verdade?

Até o próximo artigo!!!

156 comments on “CONTROLE REMOTO 8 CANAIS ON/OFF – PIC 16F628A

  1. Olá Claudio, na verdade so preciso de duas saídas PWM, e elas podem até ter a mesma frequência não tem problema.
    Quando aciona o b0 do TX, sai do RX CCP1 e CCP2 incrementando.
    Quando aciona o b1 do TX, sai do RX CCP1 e CCP2 decrementando.
    Desculpe pela pela falta de explicação, Grato.

  2. Olá Claudio, suas palavras de apoio e um incentivo para qualquer pessoa não desistir de seu objetivo, fico feliz por isso.
    Bom Claudio eu como explicador so melhor como pedreiro, é q não sou programador simplesmente sou apaixonado por programação e eletrônica.
    O que faço é pegar partes de programas já prontos e executáveis e vou montando e emendando pra chegar no meu objetivo, esse seu código fiz o teste no protoboard e funciona que é uma beleza.
    Vc esta certo apesar de eu já estar fazendo calo na bunda eu não to conseguindo configurar os bits e nem fazer o incremento e decremento correto. To usando o registrado res1 dessa maneira para separar e identificar o canal e mandar para o pwm para ser incrementado/decrementado.
    Ficaria assim RX:
    CCP1 PWM1 MOTOR1
    CCP2 PWM2 MOTOR2
    B1 ESQUERDA
    B2 DIREITA
    B3 FRENTE
    B4 RÉ
    E mais uns incrementos tipo buzina, farol etc. Eu vo verificar suas dicas e qualquer resultado eu posto aqui, mais uma ves Agradeço.

    1. Olá Mauro!
      Gostaria de lembra-lo que com um único PWM não conseguirá controlar vários canais. Você tem que escolher um único canal para ser PWM ou usar um microcontrolador com vários PWM’s.
      Claudio

  3. Olá Claudio, vc teria um código pwm simplificado incremento e decremento em asm. para o pic16f877a. se poder me arrumar fico muito agradecido.

  4. Olá Claudio Obrigado pela atenção, Cara dizem q quem programa em assembly é louco vc é mesmo muito louco, admiro o dom q tem para programar parabéns. Bom fiz umas mudanças e deu certo agora o código tá funcionando no 16f877a, Mas não to conseguindo meu principal objetivo que é incrementar dois PMW, gostaria que me ajudasse pois to tentando aprender programação por conta própria, vou postar aqui o código.
    Meu objetivo é um carrinho controle remoto em q eu possa controlar a velocidade dos motores, Grato.

    LIST P=16F877A ;, R=DEC
    RADIX DEC
    INCLUDE “P16F877A.INC”
    ;————————–
    ERRORLEVEL -302
    __CONFIG _XT_OSC &_CP_OFF &_PWRTE_ON &_WDT_ON &_BODEN_OFF&_LVP_OFF ;&_INTRC_OSC_NOCLKOUT &_MCLRE_ON

    #DEFINE BANK0 BCF STATUS,RP0 ;SETA BANK0 DE MEMORIA
    #DEFINE BANK1 BSF STATUS,RP0 ;SETA BANK1
    #DEFINE FLAG FLAGS,0 ;FLAG DE SITUAÇÃO
    #DEFINE FLAG1 FLAGS,1 ;FLAG DE NOVA LEITURA
    #DEFINE SIN PORTC,7 ;PINO 17 IN RF

    CBLOCK 0X20
    PWM_SOBE,PWM_DESCE,RES1,RES0,RES1A,RES0A,FLAGS,BITCOUNTER,LC,HC,CONT,R0,R1,R2,NOTX,NOTX1,AUX
    ENDC

    seg EQU 20h
    mili EQU 21h
    x EQU 22h
    W2 EQU 23h
    ST2 EQU 24h

    TMAX EQU .50 ;TEMPO MAXIMO DO SINAL LOW
    QBYTE EQU .16 ;QUANTIDADE DE BYTES A SER RECEBIDO
    VNOTX1 EQU .1 ;HIGH TEMPO MAXIMO SEM TRANSMISSÃO PARA ZERAR SAIDAS
    VNOTX EQU .50 ;LOW TEMPO MAXIMO SEM TRANSMISSÃO PARA ZERAR SAIDAS

    ORG 0X0000
    GOTO START

    ;=============================PWM=========================
    ORG 0X0004
    movwf W2 ; salvo o W em W2
    movf STATUS,W ; W = Status original
    movwf ST2 ; Salva em ST2

    BTFSS INTCON,T0IF
    GOTO SAI_INT
    BCF INTCON,T0IF

    GOTO INCREMENTA_CCPR1L
    GOTO SAI_INT

    INCREMENTA_CCPR1L
    MOVLW .255 ;255
    XORWF CCPR1L,W
    BTFSC STATUS,Z
    GOTO SAI_INT
    INCF CCPR1L,F

    ;DECREMENTA_CCPR1L
    ; MOVLW .0 ;0
    ; XORWF CCPR1L,W
    ; BTFSC STATUS,Z
    ; GOTO SAI_INT
    ; DECF CCPR1L,F

    SAI_INT
    movf ST2,W ; le STATUS2 para w
    movwf STATUS ; e recupera
    movf W2,W ; recupero W original
    retfie ; retorna da interrupcao.
    ;=======================================================

    START:

    MOVLW 0X07
    MOVWF CMCON ;DESLIGA COMPARADORES
    MOVLW .0
    MOVWF PORTA
    MOVWF PORTB
    BANK1

    MOVLW B’11010110′
    MOVWF OPTION_REG

    MOVLW B’00000001′ ;ENTRADA RF
    MOVWF TRISA
    MOVLW B’00000000′ ;TUDO SAIDA
    MOVWF TRISB
    MOVLW B’10000000′
    movwf TRISC
    MOVLW B’00000000′
    MOVWF TRISD
    MOVLW B’00000000′
    MOVWF TRISE

    MOVLW .255
    MOVWF PR2

    BANK0
    MOVLW B’00000111′
    MOVWF CMCON
    MOVLW B’11100000′
    MOVWF INTCON
    MOVLW B’00000110′
    MOVWF T2CON
    CLRF CCPR1L
    MOVLW B’00001100′
    MOVWF CCP1CON

    CLRF FLAGS ;APAGA REGISTRADOR DE FLAGS
    MOVLW VNOTX
    MOVWF NOTX
    MOVLW VNOTX1
    MOVWF NOTX1

    INICIO:
    BCF INTCON,T0IF

    CLRF RES1
    CLRF RES0
    MOVLW QBYTE ;PREPARA PARA A RECEPÇÃO COM NUMERO DE BITS A RECEBER
    MOVWF BITCOUNTER
    L0
    BCF FLAG ;LIMPA FLAG E REGISTRADORES DE RECEPÇÃO
    CLRF HC
    CLRF LC
    L1
    L1H
    SS5:
    BTFSS FLAG ;TESTA FLAG DE HUM/ZERO RECEBIDO
    GOTO L2 ;FLAG=0
    BTFSS SIN ;SIN ? TESTA SINAL DE ENTRADA DO RECEPTOR DE RF
    GOTO M0 ; SIN=0
    L2
    BTFSS SIN ;SIN ?
    GOTO LA1 ;SIN=0
    BSF FLAG ;SIN=1
    INCF HC,F
    BTFSC STATUS,Z
    DECF HC,F
    GOTO LA2 ;VAI CONTAR TEMPO DE 50 MICRO SEGUNDOS
    LA1
    INCF LC,F ;INCREMENTA REGISTRADOR DE LOW SIGNAL NA ENTRADA RF
    BTFSC STATUS,Z
    DECF LC,F
    LA2
    MOVLW .11 ;.11 = 50 MICROSEG (ACERTA TEMPO ENTRE LEITURAS DA ENTRADA DE RF)
    MOVWF CONT
    DECFSZ CONT,F
    GOTO $-1

    DECFSZ NOTX,F
    GOTO SEG_RECP
    MOVLW VNOTX
    MOVWF NOTX
    DECFSZ NOTX1,F
    GOTO SEG_RECP
    CLRF PORTB ;DESLIGA TODAS AS SAIDAS, SE NÃO HOUVER SINAL RF

    SEG_RECP

    GOTO L1
    M0
    MOVFW LC ;TESTA SE NÃO PASSOU DO LIMITE MAXIMO DE TEMPO EM LOW NA ENTRADA DE RF
    SUBLW TMAX
    BTFSS STATUS,C
    GOTO INICIO ;C=0 (-) – LC>TMAX (REJEITAR DADO – PAUSA INICIAL)
    MOVFW HC ;OBTEM O VALOR DE ‘CARRY'(HUM OU ZERO)
    SUBWF LC,W
    RRF RES1,F ;DESLOCA O BIT NOS REGISTRADORES DE RESULTADO
    RRF RES0,F
    DECFSZ BITCOUNTER,F ;DECREMENTA O CONTADOR DE BITS A SER RECEBIDO
    GOTO L0 ;LE PROXIMO BIT
    BTFSC FLAG1 ;TESTA SE É A PRIMEIRA OU A SEGUNDA RECEPÇÃO
    GOTO PULA1
    MOVFW RES1 ;SALVA A PRIMEIRA LEITURA PARA COMPARAÇÃO COM UMA SEGUNDA
    MOVWF RES1A
    MOVFW RES0
    MOVWF RES0A
    BSF FLAG1 ;SETA FLAG DE PRIMEIRA RECEPÇÃO
    GOTO INICIO
    PULA1
    BCF FLAG1 ;SEGUNDA RECEPÇÃO, COMPARA COM A PRIMEIRA
    MOVFW RES1
    XORWF RES1A,W
    BTFSS STATUS,Z
    GOTO ERROTX
    MOVFW RES0
    XORWF RES0A,W
    BTFSS STATUS,Z
    GOTO ERROTX ;ERRO DE RECEPÇÁO
    GOTO ACIONAR ;OK – BOA RECEPÇÃO
    ERROTX
    CLRF RES1A ; APAGA RESULTADOS DE COMPARAÇÃO
    CLRF RES0A
    GOTO INICIO
    ;============================\\ INICIO //===========================
    ACIONAR
    MOVLW 0XAA
    XORWF RES0,W
    BTFSS STATUS,Z
    GOTO INICIO
    ;===========================\\ PWM_SOBE //===============
    COMF RES1,W
    MOVWF PWM_SOBE
    MOVLW .128
    XORWF PWM_SOBE,W
    BTFSS STATUS,Z
    bCf intcon,t0if
    MOVLW .108
    MOVWF TMR0

    ;GOTO VAI

    GOTO PWM_CAI
    ;===========================\\ PWM_DESCE //==============
    PWM_CAI
    COMF RES1,W
    MOVWF PWM_DESCE
    MOVLW .8 ; 64
    XORWF PWM_DESCE,W
    BTFSC STATUS,Z
    GOTO FOI
    GOTO POE_PORTB
    ;===========================================================
    ;VAI
    ;BSF PORTB,7
    ;CALL S1
    ;BCF PORTB,7
    ;GOTO ENFRENTE
    FOI
    BSF PORTB,6
    CALL S1
    BCF PORTB,6
    GOTO ENFRENTE
    ;=============================POE NA PORTA B=================
    POE_PORTB
    COMF RES1,W ;PÕEM NA SAIDA
    MOVWF PORTB

    ;=======================LIMPA SEILA COMO SE FALA ISSO=========
    ENFRENTE
    MOVLW VNOTX ;RECARGA DO REGISTRADOR DE TX RECEBIDO
    MOVWF NOTX
    MOVLW VNOTX ;RECARGA DO REGISTRADOR DE TX RECEBIDO
    MOVWF NOTX1
    GOTO INICIO
    ;=========================DELAY 1 SEGUNDO=======================
    s1
    movlw 1
    movwf seg ; Até aqui incluindo o call gastaram-se 4 us.

    ms100
    movlw 100 ; 1 us Carrega milisegundo com 100
    movwf mili ; 1 us

    ms1
    movlw 249 ; carrega x com o valor 249 (decimal)
    movwf x ; 2 us ( 1 do movlw e 1 do movwf )
    ms2
    nop ; + 1 us
    decfsz x ; + 1 us (no último eh 2 e pula p/ decfsz seg)
    goto ms2 ; + 2 us, total 4us.(no último não passa aqui)
    ; (4 us x 249)-1 totaliza 995 us
    decfsz mili ; +1 us (na última pasagem 2 us)
    goto ms1 ; +2 us (na última passagem pula)
    ; total ms1 (1000 x 100)-1 = 99999
    decfsz seg ; + 1 us (no último eh 2 e pula p/ return)
    goto ms100 ; +2 us (na última passagem pula)

    ; Total antes do return: 4us (inicio) +10 X 100004
    ; {(1 do movlw100 + 1 do movwf milisegundo + 99999 da
    ; rotina ms1 + 1 do decfsz seg + 2 do goto)}- 1 da
    ; última passagem Total = 1000043 us
    return ; + 2 us retorna da sub-rotina apos 1.000.045 us
    ; aproximadamente 1 segundo

    ;===========================fim da rotina de 1 segundo===================

    CLRWDT
    GOTO $-1
    end

    1. Olá Mauro!
      Fico feliz que esteja fazendo progresso com o programa. Quanto a ‘ser louco’ por programar em assembly , creio que vai do costume. Se você começa com “C” é difícil querer aprender em assembly. Mas, parece que o oposto também ocorre. Creio que todas as linguagens tem suas vantagens e desvantagens. Quanto ao seu código, verifique no datasheet do pic 16f877,pagina 67, como usar corretamente o PWM. O registrador CCP1L + CCP1CON nos bits 4,5 , tem que ser incrementados/decrementados para variar o tempo ‘on/off’ em plena escala. Eu achei estranho a sua rotina de interrupção, pois nela você está incrementando o CCP1L. Também, ao receber a transmissão correta, você esta usando todo o registrador res1 para comandar. Quantos botões você esta usando para aumentar e diminuir? Quantos canais serão? Como atuarão? Procure colocar no papel a sequencia de idéias, de como funcionará cada passo. Depois, comece a digitar cada porção de código. Você está indo muito bem. Não desista!
      Cláudio

  5. Olá. O que é preciso para mudar para que o código do rx funcione no pic16f877a para que eu possa ter mais opções de controle, Grato.

    1. Olá Mauro! Precisará mudar os arquivos de cabeçalho de 16f628a para 16f877a. Depois, terá que escolher quais portas usará e ajustar os ‘tris’ respectivos. Leia o datasheet para determinar o que deve ser ajustado para que cada port funcione como digital, pois o portA tem conversor analógico digital.
      Cláudio

Comments are closed.

Back To Top