Como emular un mando con Arduino


A veces   puede ser  interesante emular del comportamiento  de un mando infrarrojo  con el fin de automatizar procesos  que de otra manera  seria mucho mas complejo . Como ejemplo típico de dispositivos que podemos controlar vía infrarojos, hablamos de  reproductores de cámaras, televisores, DVD, VCR, lectores de blueray, equipos de sonidos, descodificadores  y  un largo etcétera 

Aunque pueda parecer descabellado repetir las mismas señales desde una placa Arduino , lo cierto  es que no es descabellado querer emular este comportamiento , porque  podemos  hacer cosas  que seria muy dificultoso  sin la ayuda del procesamiento de señales de infrarojos como por ejemplo  encender automáticamente  el Aire Acondicionado  cuando la temperatura  suba un determinado valor , o se desconecte a una determinadas horas ,  se apague  cuando no haya movimiento  y un largo  etcétera 

Como paso previo  debemos analizar las señales infrarrojas emitidas por el mando usado para el control de ese dispositivo  por lo que deberemos averiguar  cómo recibir los códigos y luego una vez conocidas intentar ver como transmitirlas.

Para nuestra tarea necesitamos :

  • 1 x Arduino (cualquier versión sirve  siempre que pueda procesar señales  “PWM” )
  • 1 x LED IR   (usted puede conseguir éstos de cualquier TV remoto)
  • 1 x receptor IR (usted puede conseguir éstos de cualquier TV remoto)

 

Preparación para recibir señales

Para el análisis  de las señales infrarrojas  producidas por el mando del  dispositivo a controlar en primer lugar necesitaremos  un receptor de infrarrojos ,   que bien  puede proceder de   uno reciclado de cualquier viejo proyecto que ya no utilice  o bien adquirido específicamente  en el comercio

Una interesante opción son los famosos kits para Arduino que integran por unos 4€  todo los necesario para habilitar la comunicación en los dos sentidos  gracias a un led IRDa, un receptor IRDA  y un mando para pruebas.

Kit Modulo Receptor Infrarojo IR Protocolo Nec con Mando a Distancia Arduino

Como sugerencia  para captar el código correcto , deberíamos poner el receptor IR y el mando en una caja opaca  o algo que sea oscuro  lo cual  asegurará que habrá el mínimo de interferencias y  podremos tener el código más claro para que no tengamos que programar  nuestro  Arduino  muchas veces para una simple tarea. También, asegúrese de que estar alejados de personas viendo la televisión.

Realmente el circuito es bastante sencillo pues únicamente tendremos que alimentar con 5v DC  ( que podemos tomar directamente desde nuestro Arduino )   y luego conectar la salida del receptor digital al pin digital A2 de Arduino

 

Picture of Preparing to Receive Signals

Una vez montado el simple circuito del receptor de infrarrojo es hora de  subir el programa a su Arduino  para  poder descodificar la señal infrarroja .

El siguiente programa utiliza el Arduino y un PNA4602 para descifrar IR recibido lo cual se  puede utilizar para hacer un receptor de infrarrojos. (buscando un código en particular) o transmisor (pulsando un LED IR a ~ 38KHz para el duraciones detectadas,

Este código es de dominio público (visite http://www.ladyada.net y adafruit.com), pero en esta ocasión se ha traducido para que sea mas legible y fácil de entender:


// Necesitamos usar los métodos de lectura de pin ‘raw’  porque el tiempo es muy importante aquí y el digitalRead () es un  procedimiento s más lento!

#define IRpin_PIN PIND
#define IRpin 2

// el pulso máximo que escucharemos: 65 milisegundos es mucho tiempo
#define MAXPULSE 65000

// lo que debería ser nuestra resolución de tiempo, más grande es mejor ya que es más ‘preciso’ – pero demasiado grande y no se conseguirá  tiempo exacto
#define RESOLUTION 20

// almacenaremos hasta 100 pares de pulsos (esto son muchos )
uint16_t pulses[100][2]; // par es pulso alto  y bajo 
uint8_t currentpulse = 0; // indice para pulsos que estamos almacenando

void setup(void)

{
Serial.begin(9600);
Serial.println(“Ready to decode IR!”);
}

void loop(void)

{

// tiempo de almacenamiento temporal
uint16_t highpulse, lowpulse;

//empezar sin pulso 
highpulse = lowpulse = 0;

//esto es demasiado lento!
while (IRpin_PIN & (1 << IRpin)) {
// pin esta a nivel alto

// continúa otros microsegundos
highpulse++;
delayMicroseconds(RESOLUTION);

// Si el pulso es demasiado largo, ‘se agotó el tiempo’ – o bien nada / se recibió o el código está terminado, así que imprima lo que  hemos obtenido hasta ahora, y luego reiniciamos
if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
printpulses();
currentpulse=0;
return;
}
}
// no nos detuvimos, así que escondamos la lectura
pulses[currentpulse][0] = highpulse;

// lo mismo que arriba
while (! (IRpin_PIN & _BV(IRpin))) {
// pin esta aun bajo
lowpulse++;
delayMicroseconds(RESOLUTION);
if ((lowpulse >= MAXPULSE) && (currentpulse != 0)) {
printpulses();
currentpulse=0;
return;
}
}
pulses[currentpulse][1] = lowpulse;

// leemos un pulso alto-bajo con éxito, ¡continuamos!
currentpulse++;
}

void printpulses(void) {
Serial.println(“\n\r\n\rReceived: \n\rOFF \tON”);
for (uint8_t i = 0; i < currentpulse; i++) {
Serial.print(pulses[i][0] * RESOLUTION, DEC);
Serial.print(” usec, “);
Serial.print(pulses[i][1] * RESOLUTION, DEC);
Serial.println(” usec”);
}
}


Una vez que hemos subido el código anterior  y  todo está configurado correctamente, abrir el serial monitor haciendo clic en el botón en el programa de Arduino que es el botón de un círculo en la imagen y  ya estára en marcha así que ahora usted necesitará encontrar un control remoto que desee usar para controlar algo con Arduino

El proceso  esquemáticamente  a seguir es el siguiente :

  1. Encontrar el mando a distancia del dispositivo  que quiere controla
  2. Ejecutar el código del  receptor anteriormente citado
  3. Presione el botón del mando cuyo  código desea obtener 
  4. Ver el Monitor Serial
  5. Pegar el todo el código del monitor serie  en un editor de texto 
  6. Repetir los paso 3, 4 6  con todos los botones del mando que desee descodificar 

 Interpretando las señales

Una vez siga la secuencia de paso anteriores recibirá un montón de números seguidos por “usecs” o “usec”.
Asegúrese de que ha copiado la señal que se desea formateando la salida para más fácil referencia.

Se verá algo como esto:
500 usec, 300 usec
600 usec, usec 1200

Pero habrá números mucho más que eso.

Ahora en el programa emisor  verá esto bastantes veces:

delayMicroseconds();
pulseIR();

Es decir tenemos que  tomar el primer número y poner paréntesis en delayMicroseconds(“here”); el  valor obtenido en el monitor
y a su vez   tomar el segundo número de la misma línea como el de la delayMicroseconds()  valorar y poner en el paréntesis de pulseIR(); valor.

Veamos otro ejemplo .Si conseguimos esto en el monitor serial:

OFF ON
1660 usec, usec 580
1640 usec, usec 560

Ahroa para poner los  correspondiente valores en sus áreas correspondientes lo haremos asi :

delayMicroseconds(1660);
pulseIR(580);
delayMicroseconds(1640);
pulseIR(560);

Como puede apreciar ,la  tarea de transcripción  es muy fácil.

Una vez que tenga los códigos que desee, abra un nuevo  archivo IR_SEND.pde en el programa de Arduino y luego tendremos que  poner  los valores que tiene del monitor de serie entre paréntesis haciéndolo  del mismo modo  que hemos visto anteriormente .

Ahora, una vez que tenemos los códigos que desea y haya cargado el programa con la señal que desea enviar, todo lo que tiene que hacer es conectar el LED IR al pin 13 y luego a tierra  No necesita la resistencia si tiene un Duemilanove Arduino porque tiene una resistencia integrada para PIN 13, por lo que no tiene que preocuparse.


Como ejemplo veamos este código cuando se presiona el botón para subir el canal en un  control remoto de Comcast. . Aquí está el código de Serial Monitor: Recibido:

OFF  ON
36328 usec, 280 usec
820 usec, 300 usec
1580 usec, 320 usec
640 usec, 240 usec
2740 usec, 240 usec
1280 usec, 240 usec
1240 usec, 240 usec
1120 usec, 240 usec
2600 usec, 240 usec
12740 usec, 240 usec
840 usec, 240 usec
980 usec, 240 usec
700 usec, 240 usec
700 usec, 240 usec
720 usec, 240 usec
2460 usec, 260 usec
700 usec, 240 usec
700 usec, 240 usec
14904 usec, 260 usec
820 usec, 240 usec
1660 usec, 240 usec
700 usec, 260 usec
2740 usec, 240 usec
1240 usec, 240 usec
1260 usec, 240 usec
1100 usec, 240 usec
2620 usec, 240 usec
12720 usec, 260 usec
840 usec, 220 usec
2080 usec, 240 usec
1780 usec, 260 usec
700 usec, 240 usec
700 usec, 240 usec
2480 usec, 240 usec
700 usec, 240 usec
700 usec, 240 usec

Aquí está el código realizado a partir de los datos en bruto anteriores  pero no se  asociado al código  

En el siguiente  programa   se ha introducido  un detalla original ; Arduino cambiará el canal cada diez segundos para que se puedan hacer otras cosas , Por ejemplo mientras se ve televisión y esta haciendo otras cosa  así  no tendrá que cambiar el canal de modo que el sw  recorrerá los canales para que tenga las manos libres. (todos sabemos que presionar un botón es tan difícil, ¿por qué no hacerlo de forma automática?)

 

He aquí el programa realizado por Wally_Z:


int IRledPin =  13;    // LED conectado al pin digital 13

// El método setup () se ejecuta una vez, cuando comienza el boceto

void setup()   {               
  // initializa  el pin como salida :
  pinMode(IRledPin, OUTPUT);     

  Serial.begin(9600);
}

void loop()                    
{
  SendChannelUpCode();

  delay(20*1000);  // espera veinte segundos (20 segundos * 1000 milisegundos) Cambia este valor para diferentes intervalos.

}

// Este procedimiento envía un pulso de 38KHz al IRledPin  para un cierto  numero de microsegundos. Usaremos esto siempre que tengamos que enviar códigos.

void pulseIR(long microsecs)

{
  // contaremos desde la cantidad de microsegundos que se nos dice que esperemos

  cli();  // esto apaga cualquier interrupción de fond

  while (microsecs > 0) {
   // 38 kHz tiene aproximadamente 13 microsegundos de alto y 13 microsegundos de bajo
   digitalWrite(IRledPin, HIGH);  //Esto lleva alrededor de 3 microsegundos
   delayMicroseconds(10);         // esperar 10 microseconds
   digitalWrite(IRledPin, LOW);   // esto toma sobre 3 microseconds
   delayMicroseconds(10);         // esperar   10 microseconds

   // asi que  26 microseconds  todo junto
   microsecs -= 26;
  }

  sei();  // esto devuelve el control
}

void SendChannelUpCode()

{
  // Este es el código para CHANNEL + para TV COMCAST.
 
  delayMicroseconds(36328);      //Tiempo libre (columna IZQUIERDA)      
  pulseIR(280);                               //Tiempo en (columna DERECHA) <——- NO MEZCLAR ESTOS ARRIBA
  delayMicroseconds(820);
  pulseIR(300);
  delayMicroseconds(1580);
  pulseIR(320);
  delayMicroseconds(640);
  pulseIR(240);
  delayMicroseconds(1280);
  pulseIR(240);
  delayMicroseconds(1240);
  pulseIR(240);
  delayMicroseconds(1120);
  pulseIR(240);
  delayMicroseconds(2600);
  pulseIR(240);
  delayMicroseconds(12740);
  pulseIR(240);
  delayMicroseconds(840);
  pulseIR(240);
  delayMicroseconds(980);
  pulseIR(240);
  delayMicroseconds(700);
  pulseIR(240);
  delayMicroseconds(700);
  pulseIR(240);
  delayMicroseconds(720);
  pulseIR(240);
  delayMicroseconds(2460);
  pulseIR(240);
  delayMicroseconds(700);
  pulseIR(240);
  delayMicroseconds(700);
  pulseIR(240);
  delayMicroseconds(14904);
  pulseIR(240);
  delayMicroseconds(820);
  pulseIR(240);
  delayMicroseconds(1600);
  pulseIR(240);
  delayMicroseconds(700);
  pulseIR(260);
  delayMicroseconds(2740);
  pulseIR(240);
  delayMicroseconds(1240);
  pulseIR(240);
  delayMicroseconds(1260);
  pulseIR(240);
  delayMicroseconds(1100);
  pulseIR(240);
  delayMicroseconds(2620);
  pulseIR(240);
  delayMicroseconds(12720);
  pulseIR(260);
  delayMicroseconds(840);
  pulseIR(220);
  delayMicroseconds(2080);
  pulseIR(240);
  delayMicroseconds(1780);
  pulseIR(260);
  delayMicroseconds(700);
  pulseIR(240);
  delayMicroseconds(700);
  pulseIR(240);
  delayMicroseconds(2480);
  pulseIR(240);
  delayMicroseconds(700);
  pulseIR(240);
  delayMicroseconds(700);
  pulseIR(240);
}

 

Via Instrucables.com

 

 

 

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.