Revista 100% Verde

Como emular un mando con Arduino

Por Soloelectronicos @soloelectronico

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.

Como emular un mando con 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

Como emular mando Arduino

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)

{

// 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 I nstrucables.com


Volver a la Portada de Logo Paperblog