# Protocolo RC5 IR con PIC, ahora Funciona



## ELIUSM (Nov 19, 2007)

Hola a todos!
Busco la manera de entender el protocolo de comunicación IR de un control remoto común, uno universal por ejemplo. Eso lo busco para poder armar un aparato con un PIC que interprete la señal enviada por el control, y que de allí para adelante pase cualquier cosa.

He buscado en google, pero normalmente venden controles remotos, o venden otras cosas... seguiré buscando en todo caso. Pero si alguien tiene un manual u hoja de datos que sirva... sería super bueno.

Graciaas!


----------



## ELIUSM (Nov 19, 2007)

Holaa!
Me acordé de una vieja página super paltosa!

http://www.epanorama.net/links/irremote.html

Aqui en principio sale de todo.

Igual, si hay comentarios, se agradece si los escriben o adjuntan.

Saludos!


----------



## tiopepe123 (Nov 20, 2007)

Me parece que en microchip ya tenian algo, pero busca por RC5 
Es una codificacion bastante normal, pero recuerda que cada fabricante hace lo que le... que hacen lo que quieren.

Basicamente se trata de enviar unos bloques de 38-40Khz, o sea por ejemplo

Un uno es:

 38khz   nada
|||||||||--------------

Por eso se dice que es modulada

Ademas de epanorama tambien 
http://www.lirc.org/
http://www.hobbyprojects.com/I/Infrared_Circuits.html

Codigos por marcas, yo lo he utilizado para disparar una canon S70
http://www.remotecentral.com/cgi-bin/files/rcfiles.cgi?area=other


----------



## ELIUSM (Nov 21, 2007)

Hola!
Buenos Lnks!
Lamentablemente no tengo tanto timpo ahora como para leerlos todos. De allíme surge una pregunta, que seguramente sale por allí escrita la respuesta, pero ¿los controles universales usan el protocolo RC5?

En todo caso este se ve como bien fácil de usar, como con el puerto B del 16F84, donde hablamos de Rising Edge o Falling Edge.

Un amigo me dijo que se podría hacer fácilmente con el puerto serial del cmputador, pero después de experimentar un momento me di cuenta que al menos ninguna de las velocidades del puerto serial coincidía bien con la señal enviada por el control. (38KHz)...

Interesante eso que con una cámara digital se pueda ver el infrarrojo que emite el control eh?

Bueno, cuando vuelva a tener tiempo terminaré este proyecto y veré si logro subirlo completamente aqui (esquemáticos y programas).

Saludos!


----------



## ELIUSM (Nov 21, 2007)

Hola denuevo!
Preguntaré ahora por algún chip o circuito integrado que esté hecho para ser un decodificador receptor IR del protocolo RC5 y lo convierta en otro más fácil de usar? Como RS232 u otro? Estaré buscando eso.
Saludos!


----------



## niten (Nov 21, 2007)

es mas facil de lo k piensas....
solo tienes k poner un osciloscopio en las patitas del emisor del control.
con esa señal puedes hacer lo que quieras, si la pones en un pic, y listo.
espero no quieras un circuito magico que lo tenga todo listo para conectar..

saludos


----------



## ELIUSM (Ene 8, 2009)

Hola!
Bueno, he logrado algunas cosas entre tanto. He hecho un código de PIC que se atiene exactamente a los tiempos de bits y secuencia del protocolo RC5, publicado en varias páginas.

Lo que he logrado hasta ahora, es hacer que mi aparato reacciones de la misma manera frente a cada tecla diferente pulsada. Ahora, los datos que obtengo no son útiles. Creo que tengo un problema de tiempos.

Como estoy esperimentando al lote con un control remoto cualquiera, tengo la duda si de el sale realmente el código RC5. Si me comprara un control remoto universal... qué debo hacer para que de el salga tal código? Tendría que programarle algún aparato de Philipps cierto?

Gracias!


----------



## ELIUSM (Ene 11, 2009)

Hola a todos!
Esto está interesante! El código que publico a continuación lo hice yo, pero no funciona completamente. Así como va, se alcanza a notar el siguiente problema: que al pulsar distintas teclas del control remoto, la reacción es la misma, pero es diferente para distintos _grupos_ de teclas. Quiero decir, que no siempre sale lo mismo por el PORTB (por donde salen los datos reconocidos).

Les pido ayuda, para terminar de desarrollar este código junto a ustedes, y para que quede publicado en este foro, ya que creo que muchas personas quisieran hacer algo así. En Google se encuentra mucha información sobre el protocolo RC5, pero casi ningún buen programa hecho en assembler. El código que publico, está bien ordenado y bien comentado, para que se entienda bien.

Antes, les voy a dejar dos links útiles:

http://www.ucontrol.com.ar/Articulo...colo_de_los_controles_remotos_philips_RC5.htm

http://www.8051projects.net/out.php?link=http://www.ustr.net/infrared/infrared1.shtml

Ahora mi código: La idea es que lo vean, lo metan al MPLab, y le hagan cambios (si fuese necesario), y comenten aqui, para terminarlo.
Les agradecería mucho. Saludos!


```
list		p=16F84A		; list directive to define processor
#include	<p16F84A.inc>		; processor specific variable definitions
	
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC

DATA_IN		EQU	0
ERROR_PIN	EQU	1
ADDRESS		EQU	0x0C
DATO		EQU	0x0D
CONTADOR	EQU	0x0E
PDel0		EQU	0x0F
PDel1		EQU	0x10
PDel2		EQU	0x11

;*******Inicialización del microcontrolador y variables***********************************************
	bsf		STATUS,RP0	;Pasar al banco 1
	movlw	B'00000001'
	movwf	TRISA		;1-7 = salida, 0 = entrada
	movlw	B'00000000'
	movwf	TRISB		;0-7 salida
	bcf		STATUS,RP0	;Volver al banco 0

	clrf	PORTA		;Limpiar puertos
	clrf	PORTB
;*******Fin inicialización del microcontrolador*******************************************************

MAIN
	call	LEER
	movf	ADDRESS,W
	movwf	PORTB
;	call	DEMORA		;demora de un segundo para alcanzar a ver el primer dato
	movf	DATO,W		;que salió por PORTB, subrutina omitida ahora.
	movwf	PORTB
	goto	FIN

;--------
FIN						;Es para que aqui termine el programa sin que se borre PORTB.
	goto	FIN
;--------

LEER
	btfsc	PORTA, DATA_IN	;Esperar a que entre el primer dato para comenzar
	goto	LEER
	call	DELAY14			;Retraso de 1/4 de bit
				;Una vez comenzada la lectura, comprobar el comienzo de la cadena
	btfsc	PORTA,DATA_IN	;Probar si primer start bit es 1
	goto	BAD_DATA		;Ir a BAD_DATA si el primer start bit resulta ser cero
	call	DELAY12			;Esparar por medio bit
	btfss	PORTA,DATA_IN	;Probar si entre 1er y 2do Start bit hay un 0
	goto	BAD_DATA		;Ir a BAD_DATA si el segundo start bit resulta ser cero
	call	DELAY12			;Esparar por medio bit
	btfsc	PORTA,DATA_IN	;Probar si segundo start bit es 1
	goto	BAD_DATA		;Ir a BAD_DATA si el segundo start bit resulta ser cero. HASTA AQUI, START BIT
	call	DELAY1			;Saltarse el Toggle
	call	DELAY1

	bcf		PORTA,ERROR_PIN;Apagar pin de error si todo esta bien, y en caso de que esté activo
			;Si esta malo el comienzo de la cadena, será Bad_Data
			;Ahora se comienza con la decodificación de datos útiles.

	clrf	ADDRESS			;Borrar ADDRESS y DATO para empezar con variables limpias
	clrf	DATO

	movlw	D'5'			;Cargar contador para leer 5 bits para leer la parte de ADDRESS
	movwf	CONTADOR

LEER_ADDRESS
	rlf		ADDRESS,F
	btfss	PORTA,DATA_IN	;Leer Most Significant Bit ADDRESS BITS
	bsf		ADDRESS,0		;Poner en 1 la variable ADDRESS,bit_corespondiente si fuese necesario
	decfsz	CONTADOR,F		;Decrementar CONTADOR en 1 y saltar próximo paso si es 0
	goto	LEER_ADDRESS	;Volver para leer el siguiente bit
			;Terminada la lectura de esta cadena de datos
			;Seguir con lo que sigue

	movlw	D'6'		;Recargar contador para leer 6 bits
	movwf	CONTADOR

LEER_DATO
	rlf		DATO,F
	call	DELAY1		;Esperar un bit para empezar a leer DATA
	btfss	PORTA, DATA_IN	;Leer MostSignificantBit DATA BIT
	bsf		DATO,0		;Poner en 1 la variable DATO,bit_corespondiente si fuese necesario
	decfsz	CONTADOR,F	;Decrementar CONTADOR en 1 y saltar prÃ³ximo paso si es 0
	goto	LEER_DATO	;Volver para leer el siguiente bit
			;Terminada la lectura de esta cadena de datos
			;Seguir con lo que sigue

	return			;La lectura de datos está terminada, ahora volver.

BAD_DATA
	bsf		PORTA, ERROR_PIN;Avisar que hay error
	goto	MAIN		;Volver al inicio, o salir de LEER

DELAY1
	call	DELAY14		;Llamar 4 veces al DELAY de 1/4 de Bit para que sea 1 Bit
	call	DELAY14		;Todos los DELAYs son para 4MHz, y DELAY1 = 1,778 ms
	call	DELAY14
	call	DELAY14
	return

DELAY12
	call	DELAY14		;Llamar 2 veces al DELAY de 1/4 de Bit para que sea 1/2 de Bit
	call	DELAY14
	return

;446 uS (la cuarta parte del tiempo de un bit).
DELAY14  movlw     .110      ; 1 set numero de repeticion 
        movwf     PDel0     ; 1 |
PLoop0  clrwdt              ; 1 clear watchdog
        decfsz    PDel0, 1  ; 1 + (1) es el tiempo 0  ?
        goto      PLoop0    ; 2 no, loop
        return              ; 2+2 Fin.

END
```


----------



## jsemari (Ene 20, 2009)

¿Porqué no dibujas el esquema? Así sería mejor. 
Estoy comenzando con esto de los pics, y no entiendo porqué usas la puerta A para guardar un dato (ERROR_PIN). ¿O es que tienes puesto ahí un led para ver cuando hay error?
Si es BAD_DATA luego de señalizarlo vuelve a MAIN y va a LEER de nuevo, con lo que seguramente estás leyendo bits sucesivos de la misma cadena. Habría que poner un retardo, no?
Quizás en la rutina de retardo DELAY14 debieras utilizar el timer, sería mas exacto no?
Saludos!


----------



## ELIUSM (Ene 20, 2009)

Hola jsemari.

Bueno, en el PORTA hay un LED que me indica si la lectura ha sido errónea.

He metido delays de hasta 1 segundo entre lectura y lectura, para que sea imposible que lea parte del mismo dato. Me he preocupado de darle señales limpias, por ejemplo, después de que leyó una vez y entró al delay de 1 segundo, suelto la tecla del control y cuando pasó ese segundo, recién vuelvo a presionar la tecla, para que así vuelva a leer "desde cero".

Cada bit del dato que sale del control hacia el PIC tiene un tiempo de duración tan largo, que el PIC tendría que hacer retardos de hasta 400 ciclos (a 4MHz) para entrar a leer el siguiente bit. Como los bits son tan largos, el error de esto puede ser bastante grande, sin que surjan problemas.

He visto una rutina hecha de la misma manera (con delays de software), que sirve para comunicación de puerta serial RS232 a 9600 Baud, en ambas direcciones... y funciona perfectamente.

Pero lo que pasa aquí ... es que a mismas teclas da una sola reacción, y siempre la misma. O sea, no es que esté leyendo "partes" de datos ... estoy leyendo datos completos, pero reacciona siempre de la misma manera ante ellos. Y ante otro grupo de teclas, la reacción es otra, y siempre la misma para ese grupo de teclas.

Para un diagrama, estoy usando el receptor IR del Datasheet que adjunté. En la página nº 5 hay un circuito ejemplo, y es ese exactamente el que estoy ocupando.

Agradezco tu comentario.
Saludos!


----------



## jsemari (Ene 20, 2009)

Veo en el datasheet que la frecuencia de filtrado del sensor es de 38 Khz cuando el RC5 es de 36. No se si eso tiene que ver con una respuesta pobre, quizás los niveles de salida del sensor no sean los adecuados. Aunque eso no tiene que ver con que de respuestas iguales a distintas teclas. Has probado a conectar la salida del sensor a la entrada de micrófono de tu PC? Con un programa de grabación de audio, de esos que te "pintan" la señal en la pantalla puedes ver los pulsos que da.
Saludos
Josemari


----------



## ELIUSM (Ene 20, 2009)

Hmmm! eso no lo he probado, lo de la entrada de micrófono. Hace tiempo que debí haberme armado uno de esos. Me pondré a investigar. Tienes toda la razón... si hubiera tenido un osciloscopio, ya tendría resuelto el rpblema.

Ahora por lo de 38 y 36 KHz .... por lo que sé, el protocolo RC5 está a 38 KHz, pero ahora que lo dices, no me acuerdo bien dónde leí eso. La cosa es que creo que da lo mismo, ya que el sensor es un fototransistor que es capaz de tomar cualquier frecuencia que esté por debajo de su máxima (en este caso, 38KHz).
Si el receptor fuera de 36KHz y le intentara meter 38KHz te creería que algo malo pasaría.

Igual por favor sigan comentando si ven algo más. Yo mientras tanto me pondré a investigar de una vez por todas eso de hacer un osciloscopio básico con la tarjeta de sonido.

Saludos!


----------



## ELIUSM (Ene 20, 2009)

Y ya tenemos un problema para esta aplicación, por medio de una tarjeta de sonido:

De una tarjeta de sonido se puede medir entre 0 y 20 KHz ... pero no 38 KHz. Eso está lejos por sobre el rango.

Igual seguiré con el tema del osciloscopio por tarjeta de sonido, aunque para esto ya no sirva.

Tendré que conseguirme un osiloscopio decente, aunque para eso tenga que esperar muchísimo.

Gracias!
Saludos!


----------



## jsemari (Ene 21, 2009)

No es así  Eliusm. Aquí te copio varios enlaces donde dice que son 36KHz y, el dispositivo normalmente lleva un filtro para esa frecuencia y un amplificador. La salida ya es TTL, y se encuentra filtrada de la portadora, por tanto la salida es de una frecuencia bastante inferior, justamente 64 veces menos, unos 560 Hz. Aquí tiene una página donde dice que lo conecta: http://www.comunidadelectronicos.com/proyectos/infrarrojos.htm
El código RC5: http://robots-argentina.com.ar/Comunicacion_protocolorc5.htm
Aquí puedes ver de forma gráfica como es la demodulación: http://www.sbprojects.com/knowledge/ir/ir.htm
Ten en cuenta que normalmente los sensores son de lógica inversa.
Y aquí tienen un programa que dice que funciona y lo representa en unos displays:
http://www.sbprojects.com/projects/ircontrol/picir/software.htm
http://www.sbprojects.com/projects/ircontrol/picir/rc5.htm

Sigue manteniéndome informaciónrmado de la marcha del proyecto, por favor. Me interesa mucho.
Saludos
Josemari


----------



## ELIUSM (Ene 21, 2009)

Jsemari, si no fuera por tus respuestas...

Te tengo maravillosas novedades: en el archivo adjunto hay una imágen, que muestra cómo por primera vez he visto en persona las ondas RC5.

Encima de la imágen me hice todo un análisis, y se ven los Start bits con Toggle, se ven también el Address y el Command, y lo mejor de todo: Conciden con la tabla de comandos!
El Address como se ve, por alguna razón es nada más que cero siempre. Será porque estoy usando un control remoto configurable.

Pronto encontraré los tiempos de cada bit (yo mismo), lo cual no debe ser tan difícil, y volveré a hacer un programa en Assembler que decodifique esto.

Seguiré en esto!
Gracias! y saludos!


----------



## jsemari (Ene 21, 2009)

Dime que programa usaste como "osciloscopio", se ve muy bien.


----------



## ELIUSM (Ene 21, 2009)

Ah si! se me olvidó escribir eso! Aquí va: click!

El programa es Freeware asique no debería haber problemas.

El circuito que usé para esto es el que se encuentra dentro del primer Link de los que me mandaste.

Más novedades: encontré fallas en mi programa. Durante las 5 y 6 repeticiones de lectura de Bits (5 de addr y 6 de comando), se me olvidó poner un delay que espera a que haya transcurrido un bit. Eso explica el por qué la reacción frente a distintas teclas era una misma, y otra misma para otro grupo de teclas. Además había que notar lo siguiente: solamente habían DOS reacciones diferentes a lo largo de todas las teclas del control. y NO 3 o más.

No publicaré el programa todavía, sin antes verlo funcionando yo mismo. Eso es para no rellenar innecesariamente este foro.

Pronto tendré más.

Saludos!

PD: Hay más: el Address me salió siempre cero, ya que según tablas (ver Links), corresponde a "TV1", y mi control universal lo tengo configurado ahora para hablar con TV's.


----------



## ELIUSM (Ene 21, 2009)

Señores, esto está FUNCIONANDO!

Les pongo el programa a continuación.

Algunas explicaciones quiero dar antes: Este programa está hecho SOLAMENTE para decodificar el protocolo RC5, completamente por Software. No hay más software entremezclado, como es tan típico, como por ejemplo para manejar LCDs. El programa debería ser fácil de entender, y está bien comentado.

Pines:

RA0: entrada de datos desde el receptor IR (el datasheet del que usé, el IRM8601S está adjuntado en uno de los posts anteriores).

RA1: LED que indica recepción errónea del dato (referente al comienzo del tren de bits, y sin control de la interpretación de datos o addresses.

El MAIN del programa solo está en este momento para tirar el ADDRESS por PORTB, esperar un segundo, y tirar entonces el COMMAND por PORTB, para que puedan conectar LEDs y ver qué sale (en vez de usar una complicada rutina para manejar Displays).

El resto sdel PIC se conecta como siempre. El Oscilador usado es de 4MHz, el PIC es el 16F84.

Que el programa decodifique todo por Software y no se base en Hardware, es bueno porque así es adaptable a casi cualquier PIC. Además, resulta que es bastante corto, de manera que se pueda meter en PICs de bastante poca capacidad también.

Si observan con cuidado, en el programa me salto, o no tomo en cuenta el Toggle Bit, ya que tiene una propiedad poco necesaria, que intentar decodificarla haría que el programa se alargue explosivamente. (demasiadas líneas de comando).

Si alguien tiene más preguntas, que pregunte!
Agradezco a jsemari por su ayuda.

Una observación: el programa a veces (pocas veces) tira datos erróneos (que no corresponden a la tecla), pero eso se debe seguramente a alguna impureza de señal. Talvez publique una versión mejorada de este programa.

Bueno, y este ha sido mi aporte aqui por hoy.

Saludos!


```
list		p=16F84A		; list directive to define processor
#include	<p16F84A.inc>		; processor specific variable definitions
	
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC

DATA_IN		EQU	0
ERROR_PIN	EQU	1
ADDRESS		EQU	0x0C
DATO		EQU	0x0D
CONTADOR	EQU	0x0E
PDel0		EQU	0x0F
PDel1		EQU	0x10
PDel2		EQU	0x11

;*******Inicialización del microcontrolador y variables***********************************************
	bsf		STATUS,RP0	;Pasar al banco 1
	movlw	B'00000001'
	movwf	TRISA		;1-7 = salida, 0 = entrada
	movlw	B'00000000'
	movwf	TRISB		;0-7 salida
	bcf		STATUS,RP0	;Volver al banco 0

	clrf	PORTA		;Limpiar puertos
	clrf	PORTB
;*******Fin inicialización del microcontrolador*******************************************************

MAIN
	call	LEER
	movf	ADDRESS,W
	movwf	PORTB
	call	DEMORA		;demora de un segundo para alcanzar a ver el primer dato
	movf	DATO,W		;que salió por PORTB, subrutina omitida ahora.
	movwf	PORTB
	call	DEMORA		;demora de un segundo para alcanzar a ver el primer dato
	goto	MAIN

;--------
FIN						;Es para que aqui termine el programa sin que se borre PORTB.
	goto	FIN
;--------

LEER
	btfsc	PORTA, DATA_IN	;Esperar a que entre el primer dato para comenzar
	goto	LEER
	call	DELAY14			;Retraso de 1/4 de bit, para estar bien "encima" del bit.
				;Una vez comenzada la lectura, comprobar el comienzo de la cadena
	btfsc	PORTA,DATA_IN	;Probar si primer start bit es 1 (aunque ya es así...)
	goto	BAD_DATA		;Ir a BAD_DATA si el primer start bit resulta ser cero
	call	DELAY12			;Esparar por medio bit
	btfss	PORTA,DATA_IN	;Probar si entre 1er y 2do Start bit hay un 0
	goto	BAD_DATA		;Ir a BAD_DATA si el segundo start bit resulta ser cero
	call	DELAY12			;Esparar por medio bit
	btfsc	PORTA,DATA_IN	;Probar si segundo start bit es 1
	goto	BAD_DATA		;Ir a BAD_DATA si el segundo start bit resulta ser cero. HASTA AQUI, START BIT
	call	DELAY1			;Saltarse el Toggle (por sus propiedades complicadas)
	call	DELAY1

	bcf		PORTA,ERROR_PIN;Apagar pin de error si todo esta bien, y en caso de que esté activo
			;Si esta malo el comienzo de la cadena, será Bad_Data
			;Ahora se comienza con la decodificación de datos útiles.

	clrf	ADDRESS			;Borrar ADDRESS y DATO para empezar con variables limpias
	clrf	DATO

	movlw	D'5'			;Cargar contador para leer 5 bits (ADDRESS)
	movwf	CONTADOR

LEER_ADDRESS
	rlf		ADDRESS,F
	btfss	PORTA,DATA_IN	;Leer Most Significant Bit ADDRESS BITS
	bsf		ADDRESS,0		;Poner en 1 la variable ADDRESS,bit_corespondiente si fuese necesario
	call	DELAY1			;Esperar un bit (para llegar al siguiente)
	decfsz	CONTADOR,F		;Decrementar CONTADOR en 1 y saltar próximo paso si es 0
	goto	LEER_ADDRESS	;Volver para leer el siguiente bit
			;Terminada la lectura de esta cadena de datos
			;Seguir con lo que sigue

	call	DELAY1		;Esperar un bit para empezar a leer el comando (próxima función)
	movlw	D'6'			;Recargar contador para leer 6 bits (comando)
	movwf	CONTADOR

LEER_DATO
	rlf		DATO,F
	btfss	PORTA, DATA_IN	;Leer MostSignificantBit DATA BIT
	bsf		DATO,0		;Poner en 1 la variable DATO,bit_corespondiente si fuese necesario
	call	DELAY1		;Esperar un bit para leer el siguiente
	decfsz	CONTADOR,F	;Decrementar CONTADOR en 1 y saltar prÃ³ximo paso si es 0
	goto	LEER_DATO	;Volver para leer el siguiente bit
			;Terminada la lectura de esta cadena de datos
			;Seguir con lo que sigue

	rrf		DATO,F		;Para que el Bit 0 esté en la pata PORTB,0
	rrf		ADDRESS		;Para que el Bit 0 esté en la pata PORTB,0
	return			;La lectura de datos está terminada, ahora volver.

BAD_DATA
	bsf		PORTA, ERROR_PIN;Avisar que hay error
	goto	MAIN		;Volver al inicio, o salir de LEER

DELAY1
	call	DELAY14		;Llamar 4 veces al DELAY de 1/4 de Bit para que sea 1 Bit
	call	DELAY14		;Todos los DELAYs son para 4MHz, y DELAY1 = 1,778 ms
	call	DELAY14
	call	DELAY14
	return

DELAY12
	call	DELAY14		;Llamar 2 veces al DELAY de 1/4 de Bit para que sea 1/2 de Bit
	call	DELAY14
	return

;446 uS (la cuarta parte del tiempo de un bit).
DELAY14  movlw     .110      ; 1 set numero de repeticion 
        movwf     PDel0     ; 1 |
PLoop0  clrwdt              ; 1 clear watchdog
        decfsz    PDel0, 1  ; 1 + (1) es el tiempo 0  ?
        goto      PLoop0    ; 2 no, loop
        return              ; 2+2 Fin.

DEMORA  movlw     .14       ; 1 set numero de repeticion  (C)
        movwf     PDel0     ; 1 |
PLop0  movlw     .72       ; 1 set numero de repeticion  (B)
        movwf     PDel1     ; 1 |
PLop1  movlw     .247      ; 1 set numero de repeticion  (A)
        movwf     PDel2     ; 1 |
PLop2  clrwdt              ; 1 clear watchdog
        decfsz    PDel2, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLop2    ; 2 no, loop
        decfsz    PDel1,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLop1    ; 2 no, loop
        decfsz    PDel0,  1 ; 1 + (1) es el tiempo 0  ? (C)
        goto      PLop0    ; 2 no, loop
PDelL1  goto PDelL2         ; 2 ciclos delay
PDelL2  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.

END
```


----------



## ELIUSM (Ene 22, 2009)

Más: Ya he hecho un recorrido de prueba por los diferentes códigos para controles universales para todos los aparatos Philipss. Los resultados a continuación, en la ventana de código: (usada para que las columnas del texto se mantengan en su lugar):


```
CÓDIGOS QUE FUNCIONAN para controles universales:

Aparato	Código	Observaciones

De Philipps:
TV	056	Funcionan funciones básicas para TV menos Channel
TV	043	Mismo caso
TV	011	Mismo caso
VCR	035	No es RC5, no funciona
VCR	013	Funcionan menos funciones básicas que en TV
VCR	012	No funciona
VCR	011	No funciona
VCR	063	El protocolo parece ser RC5 pero está corrido por un bit 
REC/AMP	028	Mismo caso anterior, pero con errores en el RC5 (protocolo no totalmente coincidente)
CD	015	Errores con RC5, no funciona.
TAPE	031	Con errores en el RC5 (protocolo no totalmente coincidente)
TAPE	065	Caso anterior.
DVD	004	No funciona. No es RC5.
DVD	019	Caso anterior.
DVD	021	Caso anterior.

Conclusión: los tres códigos mencionados para TV son los que mejor funcionan.
```

En algún momento probaré otras marcas.
Saludos!

PD: estoy buscando un error en el programa que me elimina el bit 6 (o 5 si se cuenta desde cero) de la parte del comando.


----------



## jsemari (Ene 22, 2009)

Enhorabuena, me alegro que lo hayas conseguido.
Saludos
Josemari


----------



## Meta (Feb 6, 2009)

Desde hace tiempo estaba buscando información sobre IRD (InfRareD) para el 16F84. Vi el código. Estaría bueno recopilar información de todo tipo para este proyecto hasta esquemas y si es posible pasarlo hasta en Proteus.

Por ahora he corregido para que el código sea más cómodo para leer en azul. Más adelante haré más cosas.


```
list      p=16F84A      ; list directive to define processor
    #include   <p16F84A.inc>      ; processor specific variable definitions
       
    __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC

    DATA_IN      EQU   0
    ERROR_PIN   EQU   1
    CBLOCK    0x0C
    ADDRESS
    DATO
    CONTADOR
    PDel0
    PDel1
    PDel2
    ENDC

    ;*******Inicialización del microcontrolador y variables***********************************************
       bsf      STATUS,RP0   ;Pasar al banco 1
       movlw   B'00000001'
       movwf   TRISA      ;1-7 = salida, 0 = entrada
       movlw   B'00000000'
       movwf   TRISB      ;0-7 salida
       bcf      STATUS,RP0   ;Volver al banco 0

       clrf   PORTA      ;Limpiar puertos
       clrf   PORTB
    ;*******Fin inicialización del microcontrolador*******************************************************

    MAIN
       call   LEER
       movf   ADDRESS,W
       movwf   PORTB
       call   DEMORA      ;demora de un segundo para alcanzar a ver el primer dato
       movf   DATO,W      ;que salió por PORTB, subrutina omitida ahora.
       movwf   PORTB
       call   DEMORA      ;demora de un segundo para alcanzar a ver el primer dato
       goto   MAIN

    ;--------
    FIN                  ;Es para que aqui termine el programa sin que se borre PORTB.
       goto   FIN
    ;--------

    LEER
       btfsc   PORTA, DATA_IN   ;Esperar a que entre el primer dato para comenzar
       goto   LEER
       call   DELAY14         ;Retraso de 1/4 de bit, para estar bien "encima" del bit.
                ;Una vez comenzada la lectura, comprobar el comienzo de la cadena
       btfsc   PORTA,DATA_IN   ;Probar si primer start bit es 1 (aunque ya es así...)
       goto   BAD_DATA      ;Ir a BAD_DATA si el primer start bit resulta ser cero
       call   DELAY12         ;Esparar por medio bit
       btfss   PORTA,DATA_IN   ;Probar si entre 1er y 2do Start bit hay un 0
       goto   BAD_DATA      ;Ir a BAD_DATA si el segundo start bit resulta ser cero
       call   DELAY12         ;Esparar por medio bit
       btfsc   PORTA,DATA_IN   ;Probar si segundo start bit es 1
       goto   BAD_DATA      ;Ir a BAD_DATA si el segundo start bit resulta ser cero. HASTA AQUI, START BIT
       call   DELAY1         ;Saltarse el Toggle (por sus propiedades complicadas)
       call   DELAY1

       bcf      PORTA,ERROR_PIN;Apagar pin de error si todo esta bien, y en caso de que esté activo
             ;Si esta malo el comienzo de la cadena, será Bad_Data
             ;Ahora se comienza con la decodificación de datos útiles.

       clrf   ADDRESS         ;Borrar ADDRESS y DATO para empezar con variables limpias
       clrf   DATO

       movlw   D'5'         ;Cargar contador para leer 5 bits (ADDRESS)
       movwf   CONTADOR

    LEER_ADDRESS
       rlf      ADDRESS,F
       btfss   PORTA,DATA_IN   ;Leer Most Significant Bit ADDRESS BITS
       bsf      ADDRESS,0      ;Poner en 1 la variable ADDRESS,bit_corespondiente si fuese necesario
       call   DELAY1         ;Esperar un bit (para llegar al siguiente)
       decfsz   CONTADOR,F      ;Decrementar CONTADOR en 1 y saltar próximo paso si es 0
       goto   LEER_ADDRESS   ;Volver para leer el siguiente bit
             ;Terminada la lectura de esta cadena de datos
             ;Seguir con lo que sigue

       call   DELAY1      ;Esperar un bit para empezar a leer el comando (próxima función)
       movlw   D'6'         ;Recargar contador para leer 6 bits (comando)
       movwf   CONTADOR

    LEER_DATO
       rlf      DATO,F
       btfss   PORTA, DATA_IN   ;Leer MostSignificantBit DATA BIT
       bsf      DATO,0      ;Poner en 1 la variable DATO,bit_corespondiente si fuese necesario
       call   DELAY1      ;Esperar un bit para leer el siguiente
       decfsz   CONTADOR,F   ;Decrementar CONTADOR en 1 y saltar prÃ³ximo paso si es 0
       goto   LEER_DATO   ;Volver para leer el siguiente bit
             ;Terminada la lectura de esta cadena de datos
             ;Seguir con lo que sigue

       rrf      DATO,F      ;Para que el Bit 0 esté en la pata PORTB,0
       rrf      ADDRESS      ;Para que el Bit 0 esté en la pata PORTB,0
       return         ;La lectura de datos está terminada, ahora volver.

    BAD_DATA
       bsf      PORTA, ERROR_PIN;Avisar que hay error
       goto   MAIN      ;Volver al inicio, o salir de LEER

    DELAY1
       call   DELAY14      ;Llamar 4 veces al DELAY de 1/4 de Bit para que sea 1 Bit
       call   DELAY14      ;Todos los DELAYs son para 4MHz, y DELAY1 = 1,778 ms
       call   DELAY14
       call   DELAY14
       return

    DELAY12
       call   DELAY14      ;Llamar 2 veces al DELAY de 1/4 de Bit para que sea 1/2 de Bit
       call   DELAY14
       return

    ;446 uS (la cuarta parte del tiempo de un bit).
    DELAY14  movlw     .110      ; 1 set numero de repeticion
            movwf     PDel0     ; 1 |
    PLoop0  clrwdt              ; 1 clear watchdog
            decfsz    PDel0, 1  ; 1 + (1) es el tiempo 0  ?
            goto      PLoop0    ; 2 no, loop
            return              ; 2+2 Fin.

    DEMORA  movlw     .14       ; 1 set numero de repeticion  (C)
            movwf     PDel0     ; 1 |
    PLop0  movlw     .72       ; 1 set numero de repeticion  (B)
            movwf     PDel1     ; 1 |
    PLop1  movlw     .247      ; 1 set numero de repeticion  (A)
            movwf     PDel2     ; 1 |
    PLop2  clrwdt              ; 1 clear watchdog
            decfsz    PDel2, 1  ; 1 + (1) es el tiempo 0  ? (A)
            goto      PLop2    ; 2 no, loop
            decfsz    PDel1,  1 ; 1 + (1) es el tiempo 0  ? (B)
            goto      PLop1    ; 2 no, loop
            decfsz    PDel0,  1 ; 1 + (1) es el tiempo 0  ? (C)
            goto      PLop0    ; 2 no, loop
    PDelL1  goto PDelL2         ; 2 ciclos delay
    PDelL2  clrwdt              ; 1 ciclo delay
            return              ; 2+2 Fin.

    END
```
*EDITO:*
Mejor colocar los archivos *.ASM y RETARDOS.INC en la misca carpeta y ejecutar el código. Es sistemas de bloques o modular, las cosas se simplifica mejor.


```
list      p=16F84A      ; list directive to define processor
    #include   <p16F84A.inc>      ; processor specific variable definitions
       
    __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC

    DATA_IN      EQU   0
    ERROR_PIN   EQU   1
    CBLOCK    0x0C
    ADDRESS
    DATO
    CONTADOR
    PDel0
    PDel1
    PDel2
    ENDC

    ;*******Inicialización del microcontrolador y variables***********************************************
       bsf      STATUS,RP0   ;Pasar al banco 1
       movlw   B'00000001'
       movwf   TRISA      ;1-7 = salida, 0 = entrada
       movlw   B'00000000'
       movwf   TRISB      ;0-7 salida
       bcf      STATUS,RP0   ;Volver al banco 0

       clrf   PORTA      ;Limpiar puertos
       clrf   PORTB
    ;*******Fin inicialización del microcontrolador*******************************************************

    MAIN
       call   LEER
       movf   ADDRESS,W
       movwf   PORTB
       call   DEMORA      ;demora de un segundo para alcanzar a ver el primer dato
       movf   DATO,W      ;que salió por PORTB, subrutina omitida ahora.
       movwf   PORTB
       call   DEMORA      ;demora de un segundo para alcanzar a ver el primer dato
       goto   MAIN

    ;--------
    FIN                  ;Es para que aqui termine el programa sin que se borre PORTB.
       goto   FIN
    ;--------

    LEER
       btfsc   PORTA, DATA_IN   ;Esperar a que entre el primer dato para comenzar
       goto   LEER
       call   DELAY14         ;Retraso de 1/4 de bit, para estar bien "encima" del bit.
                ;Una vez comenzada la lectura, comprobar el comienzo de la cadena
       btfsc   PORTA,DATA_IN   ;Probar si primer start bit es 1 (aunque ya es así...)
       goto   BAD_DATA      ;Ir a BAD_DATA si el primer start bit resulta ser cero
       call   DELAY12         ;Esparar por medio bit
       btfss   PORTA,DATA_IN   ;Probar si entre 1er y 2do Start bit hay un 0
       goto   BAD_DATA      ;Ir a BAD_DATA si el segundo start bit resulta ser cero
       call   DELAY12         ;Esparar por medio bit
       btfsc   PORTA,DATA_IN   ;Probar si segundo start bit es 1
       goto   BAD_DATA      ;Ir a BAD_DATA si el segundo start bit resulta ser cero. HASTA AQUI, START BIT
       call   DELAY1         ;Saltarse el Toggle (por sus propiedades complicadas)
       call   DELAY1

       bcf      PORTA,ERROR_PIN;Apagar pin de error si todo esta bien, y en caso de que esté activo
             ;Si esta malo el comienzo de la cadena, será Bad_Data
             ;Ahora se comienza con la decodificación de datos útiles.

       clrf   ADDRESS         ;Borrar ADDRESS y DATO para empezar con variables limpias
       clrf   DATO

       movlw   D'5'         ;Cargar contador para leer 5 bits (ADDRESS)
       movwf   CONTADOR

    LEER_ADDRESS
       rlf      ADDRESS,F
       btfss   PORTA,DATA_IN   ;Leer Most Significant Bit ADDRESS BITS
       bsf      ADDRESS,0      ;Poner en 1 la variable ADDRESS,bit_corespondiente si fuese necesario
       call   DELAY1         ;Esperar un bit (para llegar al siguiente)
       decfsz   CONTADOR,F      ;Decrementar CONTADOR en 1 y saltar próximo paso si es 0
       goto   LEER_ADDRESS   ;Volver para leer el siguiente bit
             ;Terminada la lectura de esta cadena de datos
             ;Seguir con lo que sigue

       call   DELAY1      ;Esperar un bit para empezar a leer el comando (próxima función)
       movlw   D'6'         ;Recargar contador para leer 6 bits (comando)
       movwf   CONTADOR

    LEER_DATO
       rlf      DATO,F
       btfss   PORTA, DATA_IN   ;Leer MostSignificantBit DATA BIT
       bsf      DATO,0      ;Poner en 1 la variable DATO,bit_corespondiente si fuese necesario
       call   DELAY1      ;Esperar un bit para leer el siguiente
       decfsz   CONTADOR,F   ;Decrementar CONTADOR en 1 y saltar prÃ³ximo paso si es 0
       goto   LEER_DATO   ;Volver para leer el siguiente bit
             ;Terminada la lectura de esta cadena de datos
             ;Seguir con lo que sigue

       rrf      DATO,F      ;Para que el Bit 0 esté en la pata PORTB,0
       rrf      ADDRESS      ;Para que el Bit 0 esté en la pata PORTB,0
       return         ;La lectura de datos está terminada, ahora volver.

    BAD_DATA
       bsf      PORTA, ERROR_PIN;Avisar que hay error
       goto   MAIN      ;Volver al inicio, o salir de LEER

    
    INCLUDE   <RETARDOS.INC>

    END
```
Librería RETARDOS.INC

```
DELAY1
       call   DELAY14      ;Llamar 4 veces al DELAY de 1/4 de Bit para que sea 1 Bit
       call   DELAY14      ;Todos los DELAYs son para 4MHz, y DELAY1 = 1,778 ms
       call   DELAY14
       call   DELAY14
       return

    DELAY12
       call   DELAY14      ;Llamar 2 veces al DELAY de 1/4 de Bit para que sea 1/2 de Bit
       call   DELAY14
       return

    ;446 uS (la cuarta parte del tiempo de un bit).
    DELAY14  movlw     .110      ; 1 set numero de repeticion
            movwf     PDel0     ; 1 |
    PLoop0  clrwdt              ; 1 clear watchdog
            decfsz    PDel0, 1  ; 1 + (1) es el tiempo 0  ?
            goto      PLoop0    ; 2 no, loop
            return              ; 2+2 Fin.

    DEMORA  movlw     .14       ; 1 set numero de repeticion  (C)
            movwf     PDel0     ; 1 |
    PLop0  movlw     .72       ; 1 set numero de repeticion  (B)
            movwf     PDel1     ; 1 |
    PLop1  movlw     .247      ; 1 set numero de repeticion  (A)
            movwf     PDel2     ; 1 |
    PLop2  clrwdt              ; 1 clear watchdog
            decfsz    PDel2, 1  ; 1 + (1) es el tiempo 0  ? (A)
            goto      PLop2    ; 2 no, loop
            decfsz    PDel1,  1 ; 1 + (1) es el tiempo 0  ? (B)
            goto      PLop1    ; 2 no, loop
            decfsz    PDel0,  1 ; 1 + (1) es el tiempo 0  ? (C)
            goto      PLop0    ; 2 no, loop
    PDelL1  goto PDelL2         ; 2 ciclos delay
    PDelL2  clrwdt              ; 1 ciclo delay
            return              ; 2+2 Fin.
```


----------



## SKAP (Feb 6, 2009)

disculpen pero quisiera saber si el comando:
rlf     es igual a RLCF y
rrf    es igual a  RRCF

pues en el compilador me aparecen como error.


----------



## Meta (Feb 7, 2009)

Hola:

RLCF = Rotate Left f through Carry
RRCF = Rotate Right f through Carry

Si, si son iguales.

http://ww1.microchip.com/downloads/en/DeviceDoc/39632D.pdf

Un cordial saludo.


----------



## SKAP (Feb 7, 2009)

muchas gracias meta  era una gran duda
y que me retraso en el proyecto


----------



## SKAP (Feb 7, 2009)

Yo y mis dudas al querer pasar el codigo para el pic 18f452 me aparece ciertos errores:

Error[113]    : Symbol not previously defined (RP0)
Error[113]    : Symbol not previously defined (_CP_OFF)
Error[113]    : Symbol not previously defined (_WDT_OFF)
Error[113]    : Symbol not previously defined (_PWRTE_ON)
Error[113]    : Symbol not previously defined (_XT_OSC)
y si intento con el pic :
16F84A
error (__MAXRAM must be used first)


----------



## SKAP (Feb 8, 2009)

Revisando encontre que:
en el pic 16F84A 
       STATUS Bits
RP0     EQU     H'0005'

y en el pic 18f452 no aparece y de ahi el error y no se cual sera su sustituto:
;----- STATUS Bits -
N               EQU  H'0004'
OV             EQU  H'0003'
Z               EQU  H'0002'
DC             EQU  H'0001'
C               EQU  H'0000'


----------



## jsemari (Feb 8, 2009)

He realizado el proyecto con un TSOP1736 y no me funciona. ¿Habéis vosotros realizado el circuito? ¿Que sensor habéis usado?
Gracias
Josemari


----------



## Meta (Feb 8, 2009)

http://www.datasheetcatalog.org/datasheets/208/301092_DS.pdf

El más usado es el SFH5110 VER.


----------



## Amaro (Mar 8, 2009)

Acerca del winscope, se supone que lleva algun circuito de aislacion pra proteger ?

podrian enviarlo o comentar porfavor


----------



## Jimmy Fernandez (May 1, 2009)

Un favor ELIUSM podras mostrar le esquema de tu circuito 
gracias


----------



## ELIUSM (May 1, 2009)

Hola a todos!
Que honor que hayan seguido trabajando en este Post.

Tendré que disculparme, ya que podré subir los archivos (Todos: esquemas y programa) recién el lunes. Lo que pasa es que estoy lejos de mi computador ahora. Allí sabrán qué circuitos ocupé.

Saludos!


----------



## jsemari (May 3, 2009)

Bueno, tengo que decir que al final logré leer del sensor estupendamente. Todo era un error en el conteo de los tiempos.


----------



## ELIUSM (May 3, 2009)

Aquí les tengo todos mis archivos que tienen que ver con el tema. La idea de este "pack", es que contenga toda la información necesaria para realizar el proyecto de comienzo a fin.

El amigo jsemari parece que tiene una versión más nueva del programa hecho en assembler para PIC. Es así?

Si tienen más preguntas... obvio que escriben!
Saludos!


----------



## ELIUSM (May 4, 2009)

Se me había olvidado enviarles esto, que es todo lo relacionado con medir señales con MIC, y con el programa WINSCOPE.

Que les sirva!
Saludos!


----------



## Zero_023 (Jul 27, 2009)

te felicito,magnifico aporte, pero podrias poner el ckto para entender mejor el programa.....
saludos 
gracias


----------



## xale (Abr 15, 2010)

Hola!!
Somos dos estudiantes de 2º de ingenieria de telecomunicaciones de españa y tenemos que hacer un proyecto muy parecido al de ELIUSM. Nuestro proyecto consiste en controlar por control remoto (con el protocolo RC5) 8 leds. 4 de ellos seran de salida por pines digitales para simplemente apagarlos y encenderlos y los otros 4 seran por salida analogica para regularlos en intensidad mediante el boton de volumen del mando a distancia. 
Nuestro conocimiento en este campo es bastante escaso, es posible que nos envieis el codigo del programa o algo que sea parecido??os lo agradeceriamos muxoo!!!
graciasssss!!!!!!!!!!!!!!!!!!!!!!!


----------



## Moyano Jonathan (Abr 15, 2010)

en caso de que nos les funcione con todos los controles remotos ..por que no crean ustedes mismos su propio control remoto RC5.....para poder ver los pulsos que envían los controles remotos convencionales...podrían hacer un adaptador para mostrar los pulsos en el analizador lógico del PICKIT2...para los que tengan ese programador.


----------



## xale (Abr 20, 2010)

Hola eliusm nos gustaria saber para que utilizas DATA_IN en tu programa. gracias


----------



## master666 (Sep 17, 2010)

me gustaria saber si alguno de ustedes tiene el codigo para que el pic pueda decodificar un control remoto no importa si es sony o philips, yo tengo los dos, estoy haciendo un proyecto que se controla con un control remoto pero no puedo hacer que el pic 16f84a decodifique la trama del infrarrojo, si tienen el codigo en c ( ccs ) mejor ya le estoy agarrando un poco a c o si lo tienen en asm no importa buscare la manera de entenderle. 

Desde ya muchas gracias


----------



## yulian (Oct 2, 2010)

hola compañeros del foro. Me parecio muy interesante los aportes ELIUSM y los demas integrantes de este foro, aunque el unico problema que tengo es que trabajo con microcontroladores HC08, especificamente con el GP32 y me gustaria saber como hacer el mismo proyecto utilizando este microcontrolador. Mi otro inconveniente es que en programo en C y mi fuerte no es assembler. Porfavor podrian asesorarme un poco.


----------



## Quino29 (Dic 14, 2010)

jsemari dijo:


> He realizado el proyecto con un TSOP1736 y no me funciona. ¿Habéis vosotros realizado el circuito? ¿Que sensor habéis usado?
> Gracias
> Josemari



Hola buenas, me llamo Joaquín y vi en el foro que utilizaste el receptor IR TSOP 1736 para realizar el receptor IR con el PIC. Yo estoy intentando hacer lo mismo pero con el PIC10F200 y quería preguntarte si em peudes pasar el código en ensamblador para intentar adaptarlo a mi PIC y modificar alguna cosilla, ya que mi intención es que los datos que se reciben los almacene y después mande la info en serie a un PLL. Es un poco lioso por lo que cualquier ayuda que me puedas facilitar seguro que me es muy útil.

Muchas gracias y un saludo,

Joaquín


----------



## TiTaNB009 (Feb 15, 2011)

*ooohhh muy bueno, mm si no fuera mucha molestia (alguien que ya tenga armado el cto) me podrian decir si funciona para control remoto LG* http://www.tecnicos-online.com.ar/images/2733.jpg
*repito espero no sea molestia, ya que el codigo esta diseñado para controles philips y asi solo haria las modificaciones necesarias del codigo .asm*


----------



## NerhoSonE (Dic 4, 2011)

exelente, justo lo que necesitaba para realizar mi proyecto, pero lo hare mejor con codigo sirc de sony, ya que tiene acceso a vcr dvd... mi control phillips solo tiene para tv


----------



## jose94h (Mar 11, 2012)

Buenas, me llamo jose y queria preguntarles a los que les funcionó el circuito, cúal es la distancia promedio que alcanzaron para la recepcion del pic?



Ahhhh. y me olvidaba!!!! por si todabia te sirve ELIUSM. Despues de analizar tu codigo el error del bit6 del comando es que la parte de las rotaciones a la derecha de adress y dato no se necesitan.
En adress no se ve el error porque como lo dijiste lo usaste en el mando de TV y solo tiene ceros, lo que no sucede en el comando. 
Gracias por tu aporte muy bueno.


----------



## pacocable (Dic 21, 2014)

¿Alguien lo ha probado en un 16f628a? yo si, pero no me funciona, he cambiado 0x0c por 0x20, pero creo que el error esta en los fuses, ademas que no veo el circuito.Por favor me podrian ayudar??
muchisimas gracias


----------

