IR Remote
Este projecto tem como objectivo utilizar um receptor Infravermelho e o Arduino para receber sinais IR, por exemplo de comandos de TVs, Vídeos, etc. e usar os mesmos como um objecto de controlo a um qualquer circuito.
O receptor usado foi retirado de um leitor de DVDs (de mesa) semelhante a este:
O esquema de ligação ao Arduino é muito básico:
(neste caso o pino de dados do receptor foi ligado ao pino digital 2 do Arduino)
Quanto ao código a utilizar optei pelo exemplo para um comando Sony, disponível no site: http://www.miklos.blog.br/2010/05/ir-receiver-controle-remoto-de-tv.html
/*
Program that reads key presses of a sony remote control
Created by Kurtis Waterston, March 6 2010
Realesed into the public domain
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1267950229
*/
int irDet = 2;
int key = 0;
int data[12];
int state;
void setup() {
Serial.begin(9600); //For debugging
pinMode(irDet, INPUT); //IR detector connected to digital pin 2
}
void loop() { //Main loop
if (pulseIn(irDet, LOW) > 2200) { //Check for start pulse
getIRkey();
Serial.print("Key press is = ");
Serial.println(key);
}
}
int getIRkey() { //Read pulses
data[0] = pulseIn(irDet, LOW);
data[1] = pulseIn(irDet, LOW);
data[2] = pulseIn(irDet, LOW);
data[3] = pulseIn(irDet, LOW);
data[4] = pulseIn(irDet, LOW);
data[5] = pulseIn(irDet, LOW);
data[6] = pulseIn(irDet, LOW);
data[7] = pulseIn(irDet, LOW);
data[8] = pulseIn(irDet, LOW);
data[9] = pulseIn(irDet, LOW);
data[10] = pulseIn(irDet, LOW);
data[11] = pulseIn(irDet, LOW);
for(int x = 0; x <= 11; x++) { //Decide wether pulses are 1's or 0's
if(data[x] > 1000) {
data[x] = 1;
}
else {
data[x] = 0;
}
}
int result = 0; //Convert array into interger
int seed = 1;
for(int i=0;i<11;i++) {
if(data[i] == 1) {
result += seed;
}
seed = seed * 2;
}
key = result;
return result;
}
No entanto, para conseguir utilizar qualquer comando sem ser apenas um da Sony, descobri o site http://www.arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html
Aqui podemos encontrar a biblioteca "IRremote" e o código que nos permite identificar as teclas de qualquer comando remoto:
/*
* IRhashdecode - decode an arbitrary IR code.
* Instead of decoding using a standard encoding scheme
* (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value.
*
* An IR detector/demodulator must be connected to the input RECV_PIN.
* This uses the IRremote library: http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
*
* The algorithm: look at the sequence of MARK signals, and see if each one
* is shorter (0), the same length (1), or longer (2) than the previous.
* Do the same with the SPACE signals. Hszh the resulting sequence of 0's,
* 1's, and 2's to a 32-bit value. This will give a unique value for each
* different code (probably), for most code systems.
*
* You're better off using real decoding than this technique, but this is
* useful if you don't have a decoding algorithm.
*
* Copyright 2010 Ken Shirriff
* http://arcfn.com
*/
#include <IRremote.h>
int RECV_PIN = 2;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
irrecv.enableIRIn(); // Start the receiver
Serial.begin(9600);
}
// Compare two tick values, returning 0 if newval is shorter,
// 1 if newval is equal, and 2 if newval is longer
// Use a tolerance of 20%
int compare(unsigned int oldval, unsigned int newval) {
if (newval < oldval * .8) {
return 0;
}
else if (oldval < newval * .8) {
return 2;
}
else {
return 1;
}
}
// Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param
#define FNV_PRIME_32 16777619
#define FNV_BASIS_32 2166136261
/* Converts the raw code values into a 32-bit hash code.
* Hopefully this code is unique for each button.
*/
unsigned long decodeHash(decode_results *results) {
unsigned long hash = FNV_BASIS_32;
for (int i = 1; i+2 < results->rawlen; i++) {
int value = compare(results->rawbuf[i], results->rawbuf[i+2]);
// Add value into the hash
hash = (hash * FNV_PRIME_32) ^ value;
}
return hash;
}
void loop() {
if (irrecv.decode(&results)) {
Serial.print("'real' decode: ");
Serial.print(results.value, HEX); //!!!!!!!PARA IDENTIFICAR AS TEClAS :)
Serial.print(", hash decode: ");
Serial.println(decodeHash(&results), HEX); // Do something interesting with this value
irrecv.resume(); // Resume decoding (necessary!)
}
}
#define LEDPIN 13
void blink() {
digitalWrite(LEDPIN, HIGH);
delay(200);
digitalWrite(LEDPIN, LOW);
delay(200);
}
// Blink the LED the number of times indicated by the Philips remote control
// Replace loop() with this for the blinking LED example.
void blink_example_loop() {
if (irrecv.decode(&results)) {
unsigned long hash = decodeHash(&results);
switch (hash) {
case 0x322ddc47: // 0 (10)
blink(); // fallthrough
case 0xdb78c103: // 9
blink();
case 0xab57dd3b: // 8
blink();
case 0x715cc13f: // 7
blink();
case 0xdc685a5f: // 6
blink();
case 0x85b33f1b: // 5
blink();
case 0x4ff51b3f: // 4
blink();
case 0x15f9ff43: // 3
blink();
case 0x2e81ea9b: // 2
blink();
case 0x260a8662: // 1
blink();
break;
default:
Serial.print("Unknown ");
Serial.println(hash, HEX);
}
irrecv.resume(); // Resume decoding (necessary!)
}
}
Resultado:
Update 30-12-2011:
Para usar a biblioteca 'IRemote' com a nova versão IDE 1.0 do Arduino, temos de alterar o seguinte no ficheiro IRremoteInt.h:
Change the "#include WProgram.h" in IRremoteInt.h to this:
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif