arduino irc.pdf

4
7/18/2019 arduino irc.pdf http://slidepdf.com/reader/full/arduino-ircpdf 1/4 Cómo acoplar un mando a distancia en Arduino Resumen Acoplar un mando a distancia (de infrarrojos, IR) a nuestros proyectos con microcontroladores (en este caso Arduino) puede ser una opción muy interesante y de bajo coste para tener comunicación inhalámbrica. El siguiente proyecto muestra cómo se hace. El programa recibe las pulsaciones del mando a distancia de la Xbox [1]  e imprime el código de cada tecla en hexadecimal por el puerto serie. Aunque no es imprescindible, puedes leer primero Cómo funciona un mando a distancia, por si no lo sabes. Hardware Material Placa Arduino (ATmega8) y de prototipos Chip TFMS5560 (Telefunken). Hay decenas de chips receptores de IR, no tiene por qué ser este en concreto, puede ser cualquier otro, eso sí, con filtro paso-banda en 56kHz a ser posible Cables de conexión Alimenta la placa de inserción usando las salidas +5V y GND de Arduino, luego el chip TFMS5660 y finalmente la salida out  de este chip al pin 2 de Arduino (interrupción externa INT0) El montaje, como ves, tiene muy pocos cables, así que si no funciona... ¡asegúrate de que el mando tiene pilas! Código de línea del telemando de la Xbox LA SIGUIENTE INFORMACIÓN ES ESPECÍFICA PARA EL MANDO A DISTANCIA DE LA XBOX. SI TIENES UN MANDO DE OTRA MARCA O MODELO, LEE MÁS ABAJO. He elegido este mando porque me parece que es bastante popular y además su código de línea (modulación digital en banda base) es sencillo. [1] . Además, es uno de los mandos que tenía en casa muertos de risa, algo había que hacer con el... Cada vez que pulsamos una tecla del mando, el TFMS5560 procesa la señal recibida [1]  y entrega en el terminal out  una secuencia de pulsos y espacios como la que aparece en la figura [1] , con 13 flancos de subida y 13 de bajada, alternados, lógicamente. La distancia entre dos flancos consecutivos (que llamaremos ranura), determina si el bit es "0" o "1". La primera ranura es el pulso inicial AGC (Automatic Gain Control) necesario para estabilizar el control automático de ganancia del TFMS5560 y no representa ningún bit de información. A continuación llega el código de 24 bits de la tecla pulsada Contents  1 Hardware 2 Código de línea del telemando de la Xbox 3 Software 4 Mandos de otras marcas y modelos 4.1 ir_remote_raw Página 1 de Cómo acoplar un mando a distancia en Arduino - Javier Valcarce's Personal Website 28/11/200 http://javiervalcarce.es/wiki/C%C3%B3mo_acoplar_un_mando_a_distancia_en_Arduino

Transcript of arduino irc.pdf

Page 1: arduino irc.pdf

7/18/2019 arduino irc.pdf

http://slidepdf.com/reader/full/arduino-ircpdf 1/4

Cómo acoplar un mando a distancia en Arduino

Resumen Acoplar un mando a distancia (de infrarrojos, IR) a nuestros proyectos con microcontroladores (en este caso Arduino)puede ser una opción muy interesante y de bajo coste para tener comunicación inhalámbrica. El siguiente proyecto muestra

cómo se hace. El programa recibe las pulsaciones del mando a distancia de la Xbox[1] e imprime el código de cada tecla enhexadecimal por el puerto serie.

Aunque no es imprescindible, puedes leer primero Cómo funciona un mando adistancia, por si no lo sabes.

Hardware

Material

Placa Arduino (ATmega8) y de prototipos

Chip TFMS5560 (Telefunken). Hay decenas de chips receptoresde IR, no tiene por qué ser este en concreto, puede ser cualquierotro, eso sí, con filtro paso-banda en 56kHz a ser posible

Cables de conexión

Alimenta la placa de inserción usando las salidas +5V y GND de Arduino,luego el chip TFMS5660 y finalmente la salida V out  de este chip al pin 2 deArduino (interrupción externa INT0)

El montaje, como ves, tiene muy pocos cables, así que si no funciona...¡asegúrate de que el mando tiene pilas!

Código de línea del telemando de la Xbox

LA SIGUIENTE INFORMACIÓN ES ESPECÍFICA PARA EL MANDO A DISTANCIA DE LA XBOX. SI TIENES UN MANDO DE OTRAMARCA O MODELO, LEE MÁS ABAJO.

He elegido este mando porque me parece que es bastante popular y además su código de línea (modulación digital en banda base) essencillo.[1]. Además, es uno de los mandos que tenía en casa muertos de risa, algo había que hacer con el...

Cada vez que pulsamos una tecla del mando, el TFMS5560 procesa la señal recibida [1] y entrega en el terminal V out  una secuencia depulsos y espacios como la que aparece en la figura[1], con 13 flancos de subida y 13 de bajada, alternados, lógicamente. La distanciaentre dos flancos consecutivos (que llamaremos ranura), determina si el bit es "0" o "1".

La primera ranura es el pulso inicial AGC (Automatic Gain Control) necesario para estabilizar el control automático de gananciadel TFMS5560 y no representa ningún bit de información.

A continuación llega el código de 24 bits de la tecla pulsada

Contents  1 Hardware 2 Código de línea del telemando de la Xbox 3 Software 4 Mandos de otras marcas y modelos 

4.1 ir_remote_raw 

Página 1 deCómo acoplar un mando a distancia en Arduino - Javier Valcarce's Personal Website

28/11/200http://javiervalcarce.es/wiki/C%C3%B3mo_acoplar_un_mando_a_distancia_en_Arduino

Page 2: arduino irc.pdf

7/18/2019 arduino irc.pdf

http://slidepdf.com/reader/full/arduino-ircpdf 2/4

Software

Parece que la forma más conveniente de demodular este código de línea (puedo estar equivocado) es usar la interrupción externaINT0 y la del temporizador TMR2. No parece factible hacer esto por sondeo ni usar bucles de espera activa porque consumiría buenaparte de los recursos del micro (y se supone que el receptor de IR va a ser sólo una pequeña parte del proyecto total).

La interrupción INT0 

Salta cada vez que hay un flanco de bajada o de subida en el pin 2 de Arduino. Esta rutina de servicio a la interrupción es básicamenteuna máquina de estados cuya variable de estado (variable bit) es el número bit que estamos recibiendo (hay un pulso inicial y luego24 bits).

La rutina comprueba el número de bit que estamos recibiendo, mide la duración de la ranura y decide si es "0" ó "1". Cuando llegamosal bit 24, el código de tecla queda almacenado en la variable ir_cmd.

La interrupción TMR2 La rutina anterior necesita poder medir el tiempo. Con una resolución de 16us es más que suficiente. Para esto lo mejor es usar lainterrupción del temporizador TMR2 configurado en modo normal y sin divisor de reloj (preescaler = 1) para que dispare cada 16us eincremente la variable usec 

ALTERNATIVA 

Otra posibilidad sería usar únicamente el temporizador TMR2, muestrear periódicamente la señal V out  de salida del chip y demodular.Así nos ahorramos la interrupción externa INT0. Aun así, he elegido la primera opción en lugar de esta porque me parece más clara,más pedagógica ;-)

PREESCALER * TIMERCOUNT / F_CLK = 1*256/16000000 = 16us 

Fichero: ir_remote_xbox.pde 

MANDO A DISTANCIA DE LA XBOX (DVDKit)

Frecuencia de la portadora: 56 kHz

Duración del pulso inicial AGC: 4500 us

Duración de la ranura correspondiente al bit 0: 1500 us

Duración de la ranura correspondiente al bit 1: 2500 us

Número de bits/trama: 24

Código de cada tecla:

Tecla Código de tecla

-----------------------------

DISPLAY 0x52AAD5

REVERSE 0x51DAE2

PLAY 0x515AEA

FORWARD 0x51CAE3

SKIP- 0x522ADD

STOP 0x51FAE0

PAUSE 0x519AE6

SKIP+ 0x520ADF

TITLE 0x51AAE5

INFO 0x53CAC3

MENU 0x508AF7

BACK 0x527AD8

UP 0x559AA6

DOWN 0x558AA7

LEFT 0x556AA9

RIGHT 0x557AA8

SELECT 0x5F4A0B

1 0x531ACE

2 0x532ACD

3 0x533ACC

4 0x534ACB

5 0x535ACA6 0x536AC9

7 0x537AC8

8 0x538AC7

9 0x539AC6

0 0x530ACF

Página 2 deCómo acoplar un mando a distancia en Arduino - Javier Valcarce's Personal Website

28/11/200http://javiervalcarce.es/wiki/C%C3%B3mo_acoplar_un_mando_a_distancia_en_Arduino

Page 3: arduino irc.pdf

7/18/2019 arduino irc.pdf

http://slidepdf.com/reader/full/arduino-ircpdf 3/4

#include <avr/io.h> 

#include <avr/interrupt.h> 

// This is the INT0 Pin of the ATMega8 

#define PIN_IRRX 2 

// Xbox IR remote control codes 

#define IRCODE_DISPLAY 0x52AAD5 

#define IRCODE_REVERSE 0x51DAE2 

#define IRCODE_PLAY 0x515AEA 

#define IRCODE_FORWARD 0x51CAE3 

#define IRCODE_SKIPSUB 0x522ADD 

#define IRCODE_STOP 0x51FAE0 

#define IRCODE_PAUSE 0x519AE6 

#define IRCODE_SKIPADD 0x520ADF 

#define IRCODE_TITLE 0x51AAE5 

#define IRCODE_INFO 0x53CAC3 

#define IRCODE_MENU 0x508AF7 

#define IRCODE_BACK 0x527AD8 

#define IRCODE_UP 0x559AA6 

#define IRCODE_DOWN 0x558AA7 

#define IRCODE_LEFT 0x556AA9 

#define IRCODE_RIGHT 0x557AA8 

#define IRCODE_SELECT 0x5F4A0B 

#define IRCODE_1 0x531ACE 

#define IRCODE_2 0x532ACD 

#define IRCODE_3 0x533ACC 

#define IRCODE_4 0x534ACB 

#define IRCODE_5 0x535ACA 

#define IRCODE_6 0x536AC9 

#define IRCODE_7 0x537AC8 

#define IRCODE_8 0x538AC7 #define IRCODE_9 0x539AC6 

#define IRCODE_0 0x530ACF 

///////////////////////////////////////////////////////////////////////////////////////////////  

volatile unsigned int  usec;

volatile int  ir_bit;

volatile unsigned long  ir_tmp;

volatile unsigned long  ir_cmd;

volatile boolean ir_cmd_new;

// Decoder state (variable "ir_bit") -1, 0, 1, 2, 3... 24 and (25) 

#define WAIT -1 // Waiting for an IR signal 

#define HEAD 0 // Receiving AGC pulse

//... 

#define PERR 250 // Maximun absolute error permited in us 

#define TIME_HEAD 4500 // AGC pulse lenght (in us) #define TIME_BIT0 1500 // Bit 0 lenght (in us) 

#define TIME_BIT1 2500 // Bit 1 lenght (in us) 

// Aruino runs at 16 Mhz,

// Raise interrupt every 1 / ((16000000 / 1) / 256) = 1 / 62500 = 16us 

///////////////////////////////////////////////////////////////////////////////////////////////  

ISR(TIMER2_OVF_vect) 

usec += 16;

if (usec == 6400)  // 6400 % 16 == 0 

// Time over! Reset receiver's state machine

usec = 0;

ir_bit = WAIT;

};

///////////////////////////////////////////////////////////////////////////////////////////////  

#define VALID_TIME(v, a, b) ( ((v) > (a)-PERR) && ((v) < (b)+PERR) ) 

// INT0, arduino pin2 

ISR(INT0_vect) 

switch (ir_bit) 

case WAIT:

// Waiting for an incoming signal 

if (!ir_cmd_new) ir_bit++;

 break;

case HEAD:

// Initial AGC pulse 

if ( VALID_TIME(usec, TIME_HEAD) ) 

Página 3 deCómo acoplar un mando a distancia en Arduino - Javier Valcarce's Personal Website

28/11/200http://javiervalcarce.es/wiki/C%C3%B3mo_acoplar_un_mando_a_distancia_en_Arduino

Page 4: arduino irc.pdf

7/18/2019 arduino irc.pdf

http://slidepdf.com/reader/full/arduino-ircpdf 4/4

Mandos de otras marcas y modelos

Por desgracia, no hay ningún tipo de normalización y cada mando genera un código de línea (secuencia de pulsos y espacios)diferente. Puedes encontrar información sobre el formato de trama y códigos de distintos modelos en el proyecto LIRC (Linux InfraredRemote Control).

Si tienes un mando "rarito" que no aparece en LIRC tendrás que investigar tú mismo el código de línea quegenera. Para ello puedes usar el programilla ir_remote_raw, que te comento a continuación. El hardwarenecesario para usarlo es el mismo, reemplazando el chip receptor por uno adecuado a la frecuencia deportadora del mando. Hay varios modelos del chip receptor de Telefunken (ver la tabla). Algunos mandos(muy pocos) usan incluso  f  0=455kHz.

Si no sabes cual es la  f  0 de tu mando usa un chip de  f  0=38kHz y seguro que aciertas. Aunque no uses el chipexacto lo único que ocurrirá es que disminuirá el alcance del mando. Prueba con un chip de 38kHz primero ysi no funciona prueba con uno de 56kHz.

Lo mejor es comprar un mando universal y configurarlo para que use el protocolo RC5 de Sony, que es el más popular. Laespecificación de dicho protocolo la tienes aquí (con ejemplos en ensamblador para un micro AVR8)

ir_remote_raw

Fichero: ir_remote_raw.pde 

En este pequeño programa, la RSI de INT0 guarda en una tabla en memoria la duración de cada pulso y de cada espacio de lasecuencia. Cuando la transmisión finaliza (lo decide un temporizador de inactividad al vencer), imprime por el puerto serie la lista detiempos (raw codes ). La lista presenta la duración de pulsos y espacios alternadamente (pulso-espacio-pulso-espacio-...) siendo elprimer valor la duración del pulso inicial AGC.

Puedes imprimir esta lista en un fichero de texto desde HyperTerminal de Windows o Minicom en Linux. Los tiempos medidos nosiempre son exactamente iguales[1] cada vez que pulsas la tecla ni tampoco el número de pulsos recibidos, procura pulsar la tecla delmando rápidamente (un golpe seco) para que envíe sólo una secuencia, prueba varias veces. Ajusta la constante TIME_OVER si creesque el mando transmite más de una vez la misma secuencia en un corto espacio de tiempo. Puedes ver el cronograma de la señalusando la función irsignal.m para Matlab.

A partir de esta lista de tiempos deberás fijarte bien e intentar  inferir cómo se transmite el "1" y el "0". Se suelen usar 4 tipos de códigosde línea

Anchura de pulso. La distancia entre 1 flancos de subida y el siguiente de bajada (en realidad es al revés porque el TFMS5XX0es activo a nivel bajo) determina si el bit es "0" o "1"

Anchura de espacio. La distancia entre 1 flancos de bajada y el siguiente de subida (en realidad es al revés porque elTFMS5XX0 es activo a nivel bajo) determina si el bit es "0" o "1"

Anchura de pulso o espacio. La distancia entre dos flancos consecutivos (de bajada o de subida) determina si el bit es "0" o "1".Este es precisamente el código de línea que usa el mando a distancia de la Xbox

De la familia Manchester. Un ejemplo de este código es el RC5 de Sony (bastante popular), para decodificarlo sólo esnecesario que la rutina de servicio a la interrupción del temporizador muestree la señal en 1/4 y 3/4 del periodo de bit parasaber si se trata de un "0" o "1"

Además puede que haya códigos especiales al dejar pulsada una tecla, ten ojo avizor.

This page was last modified on 9 June 2008, at 18:25.Retrieved from JavierValcarce.Es: Javier Valcarce's Personal Website.

Content is available under GNU Free Documentation License 1.2 .

 f 0  IC

30kHz TFMS530033kHz TFMS533036kHz TFMS536038kHz TFMS538040kHz TFMS540056kHz TFMS5560

Página 4 deCómo acoplar un mando a distancia en Arduino - Javier Valcarce's Personal Website

28/11/200http://javiervalcarce es/wiki/C%C3%B3mo acoplar un mando a distancia en Arduino