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:
Segue abaixo o arquivo HEX para TX:
Segue abaixo o arquivo ASM para RX:
Segue abaixo o arquivo HEX para RX:
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’:
Segue o arquivo HEX do TX desta versão com chave ‘DIP’:
Segue o arquivo ASM do RX desta versão com chave ‘DIP’:
Segue o arquivo HEX do RX desta versão com chave ‘DIP’:
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):
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):
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!!!
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.
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.
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
Olá Claudio, vc teria um código pwm simplificado incremento e decremento em asm. para o pic16f877a. se poder me arrumar fico muito agradecido.
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
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
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.
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