Está en la página 1de 32

Da 3: receptor/emisor IR

abi2
841 das ago
7
Da 3

PreviousNext

Los led infrarrojos se caracterizan por emitir radiacin electromagntica, invisible al ojo
humano, ya que su longitud de onda es mayor a la del espectro visible.

Para comprobar si un led IR funciona podemos mirarlo a travs de la cmara de nuestro


mvil, ya que este tipo de cmaras si que detectan radiacin infrarroja.

Los receptores de infrarrojos son unos pequeos integrados que poseen una foto-clula que
detecta emisiones infrarrojas. En el siguiente diagrama de bloques podemos ver su
funcionamiento:

PIN: sensor de infrarrojos (foto-diodo), convierte la seal luminosa incidente en seal elctrica.
AGC (control automtico de ganancia): proporciona una seal de salida constante. Si la seal de
entrada es pequea, aumenta la ganancia y viceversa.
Band Pass (filtro paso banda): filtra las frecuencias no deseadas (Ej: luz visible).
Demodulator (demodulador): recupera la informacin transportada por la onda portadora.
Botn transistor: invierte la seal. Si del demodulador sale un 1, la salida se conecta a masa. Por lo
tanto, si no recibimos nada, la salida va a ser 5V.

*Para que el receptor se comporte bien, el led IR que usemos tiene que tener la longitud de
onda a la cual es ms sensible el sensor. La ms comn es 940nm. Podemos encontrar estos
datos en el datasheet de los componentes.

Existen multitud de dispositivos que utilizan tecnologa infrarroja para control remoto, por
ejemplo los mandos de las televisiones. Su funcionamiento se basa en la emisin de
secuencias de pulsos de luz IR que transportan un cdigo de N bits que identifica la tecla
pulsada.
Existen muchos protocolos de comunicacin infrarroja, nos vamos a centrar en el protocolo
NEC, que es el que usan los mandos universales.
El protocolo NEC utiliza pulsos distancia para la transmisin de un mensaje. Este protocolo
funciona a una frecuencia de 38kHz, es decir, los pulsos duran 562.5 s. El mensaje se
transmite de la siguiente forma:

0 lgico: Enva un pulso de 562,5 s, seguido de un espacio de 562,5 s de duracin (tiempo de


transmisin de 1,125 ms)
1 lgico: Enva un pulso de 562,5 s seguido de un espacio de 1.6875 ms de duracin (tiempo de
transmisin de 2,25 ms)

Cuando pulsamos un botn de un mando, se enva la siguiente cadena de pulsos:


1.
2.
3.
4.
5.
6.

Una rfaga de pulsos de 9 ms.


Un espacio 4,5 ms
La direccin para el dispositivo receptor (8 bits)
El inverso lgico de la direccin (8 bits) (para comprobar errores)
El comando (8 bits)
El inverso lgico del comando (8 bits)

7.

Un pulso de 562.5 s para indicar el final de la transmisin del mensaje.

A continuacin se ilustra con una imagen para una direccin 00000000 y un


comando 10110101:

Vamos a empezar con una prctica sencilla que nos va a permitir comprobar el correcto
funcionamiento de nuestro receptor. Realizamos el siguiente montaje:

Como hemos mencionado antes, si no mandamos ningn pulso al receptor, la salida de este
tendra que dar 5V. Sin embargo, si apretamos un botn de un mando a distancia, el led
debera parpadear por unos instantes, ya que cuando recibe un pulso, la salida se pone a 0V.
Si ocurre esto, nuestro receptor funciona correctamente.
El siguiente cdigo nos permite registrar la sucesin de pulsos que manda un mando
cuando pulsas un botn. Adems te prepara el cdigo para que lo puedas implementar,
como veremos a continuacin. No vamos a explicar este cdigo, ya que es bastante
complejo, nos limitaremos a utilizarlo.
1
2
3
4
5
6
7
8
9
10
11

/* Raw IR decoder sketch!


This sketch/program uses the Arduno and a PNA4602 to
decode IR received. This can be used to make a IR receiver
(by looking for a particular code)
or transmitter (by pulsing an IR LED at ~38KHz for the
durations detected
Code is public domain, check out www.ladyada.net and adafruit.com
for more tutorials!
*/
// We need to use the 'raw' pin reading methods
// because timing is very important here and the digitalRead()
// procedure is slower!

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

//uint8_t IRpin = 2;
// Digital pin #2 is the same as Pin D2 see
// http://arduino.cc/en/Hacking/PinMapping168 for the 'raw' pin mapping
#define IRpin_PIN PIND
#define IRpin 2
// the maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAXPULSE 65000
// what our timing resolution should be, larger is better
// as its more 'precise' - but too large and you wont get
// accurate timing
#define RESOLUTION 20
// we will store up to 100 pulse pairs (this is -a lot-)
uint16_t pulses[100][2]; // pair is high and low pulse
uint8_t currentpulse = 0; // index for pulses we're storing
void setup(void) {
Serial.begin(9600);
Serial.println("Ready to decode IR!");
}
void loop(void) {
uint16_t highpulse, lowpulse; // temporary storage timing
highpulse = lowpulse = 0; // start out with no pulse length
// while (digitalRead(IRpin)) { // this is too slow!
while (IRpin_PIN & (1 << IRpin)) {
// pin is still HIGH
// count off another few microseconds
highpulse++;
delayMicroseconds(RESOLUTION);
// If the pulse is too long, we 'timed out' - either nothing
// was received or the code is finished, so print what
// we've grabbed so far, and then reset
if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
printpulses();
currentpulse=0;
return;
}

}
// we didn't time out so lets stash the reading
pulses[currentpulse][0] = highpulse;
// same as above
while (! (IRpin_PIN & _BV(IRpin))) {
// pin is still LOW
lowpulse++;

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

delayMicroseconds(RESOLUTION);
if ((lowpulse >= MAXPULSE) && (currentpulse != 0)) {
printpulses();
currentpulse=0;
return;
}
}
pulses[currentpulse][1] = lowpulse;
// we read one high-low pulse successfully, continue!
currentpulse++;
}
void printpulses(void) {
Serial.println("\n\r\n\rReceived: \n\rOFF
for (uint8_t i = 0; i < currentpulse; i++)
Serial.print(pulses[i][0] * RESOLUTION,
Serial.print(" usec, ");
Serial.print(pulses[i][1] * RESOLUTION,
Serial.println(" usec");
}

\tON");
{
DEC);
DEC);

// print it in a 'array' format


Serial.println("int IRsignal[] = {");
Serial.println("// ON, OFF ");
for (uint8_t i = 0; i < currentpulse-1; i++) {
//Serial.print("\t"); // tab
Serial.print("pulseIR(");
Serial.print(pulses[i][1] * RESOLUTION , DEC);
Serial.print(");");
Serial.println("");
//Serial.print("\t");
Serial.print("delayMicroseconds(");
Serial.print(pulses[i+1][0] * RESOLUTION , DEC);
Serial.println(");");
}
//Serial.print("\t"); // tab
Serial.print("pulseIR(");
Serial.print(pulses[currentpulse-1][1] * RESOLUTION, DEC);
Serial.print(");");
}

106
107
Si cargamos el cdigo en nuestro Arduino y abrimos la consola, nos dir que est listo para
decodificar IR. Entonces tenemos que pulsar el botn que deseamos y nos aparecer la
relacin de tiempos de los diferentes pulsos y adems nos los preparar para poder
implementarlo en nuestro programa.

Ahora que tenemos la secuencia de pulsos que emite el mando al pulsar un botn
determinado, podemos reproducir ese botn gracias a Arduino y a un led IR. Este se
conecta como un led normal:

Vamos a reutilizar parte del cdigo que utilizamos para la prctica del monitor serie. Los
pulsos van a ser enviados cuando pulsemos la barra espaciadora en el monitor. En la

funcin emitirPulsos() pegaremos el cdigo que nos ha proporcionado el programa


anterior.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

/*
Led IR
Apaga y enciende una televisin mediante un led IR.
*/
int ledIR =

13;

//Declaro pin para el led IR

void setup() {
pinMode(ledIR, OUTPUT); //Configuro el pin 13 como salida
Serial.begin(9600);
//Inicio la comunicacin serie
Serial.println("
led IR
");
Serial.println("**********************************");
Serial.println("* Control TV:
*");
Serial.println("**********************************");
Serial.println("* Encender/Apagar:
*");
Serial.println("*
barra espaciadora
*");
Serial.println("**********************************");
}
void loop(){
int serie;
serie
while (Serial.available() > 0){
serie = Serial.read();

//Almaceno los datos que llegan por


//Cuando hay datos para leer
//Leo esos datos

switch(serie){
case ' ':
//Barra espaciadora
emitirPulsos(); //Llamo a la funcin que emite los pulsos
Serial.println("Enviado!");
delay(2000);
break;
default:
//Si es otra cosa
break;
//no hago nada
}
}

void emitirPulsos(){
/*Aqu pegamos el cdigo proporcionado por el anterior programa*/
pulseIR(80);
delayMicroseconds(7140);
pulseIR(60);
delayMicroseconds(7820);
pulseIR(80);
delayMicroseconds(4240);

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

pulseIR(100);
delayMicroseconds(7200);
pulseIR(80);
delayMicroseconds(1460);
pulseIR(80);
delayMicroseconds(6340);
pulseIR(80);
delayMicroseconds(11540);
pulseIR(60);
delayMicroseconds(280);
pulseIR(120);
delayMicroseconds(5760);
pulseIR(60);
delayMicroseconds(2160);
pulseIR(120);
delayMicroseconds(160);
pulseIR(100);
delayMicroseconds(11740);
pulseIR(140);
delayMicroseconds(580);
pulseIR(60);
delayMicroseconds(5440);
pulseIR(280);
delayMicroseconds(9600);
pulseIR(160);
delayMicroseconds(2840);
pulseIR(160);
delayMicroseconds(9420);
pulseIR(100);
delayMicroseconds(10220);
pulseIR(80);
delayMicroseconds(5420);
pulseIR(120);
delayMicroseconds(4720);
pulseIR(480);
delayMicroseconds(10280);
pulseIR(60);
delayMicroseconds(3280);
pulseIR(80);
delayMicroseconds(38100);
pulseIR(140);
delayMicroseconds(25520);
pulseIR(80);
delayMicroseconds(12400);
pulseIR(60);
delayMicroseconds(40780);
pulseIR(120);
delayMicroseconds(160);
pulseIR(80);
delayMicroseconds(39980);
pulseIR(60);
delayMicroseconds(4420);

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137

pulseIR(60);
delayMicroseconds(11960);
pulseIR(60);
delayMicroseconds(8780);
pulseIR(80);
delayMicroseconds(7960);
pulseIR(60);
delayMicroseconds(12160);
pulseIR(100);
delayMicroseconds(42220);
pulseIR(80);
delayMicroseconds(38932);
pulseIR(100);
delayMicroseconds(3540);
pulseIR(80);
delayMicroseconds(51940);
pulseIR(100);
}
void pulseIR(long microseg){
/*Genera los pulsos de 38KHz de frecuencia
durante x microsegundos.
Parmetros: microseg*/
cli(); // desabilitamos cualquier interrupcin
while (microseg > 0) {
/*38KHz son aprox. 13microseg en HIGH y 13microseg en LOW
la instruccin digitalWrite tarde 3microseg en ejecutarse
por lo que hacemos dos delays de 10 en vez de 13.
En total el ciclo dura 26microseg, cuando se completa,
restamos al tiempo que tiene que estar mandando el pulso*/
digitalWrite(ledIR, HIGH);
delayMicroseconds(10);
digitalWrite(ledIR, LOW);
delayMicroseconds(10);
microseg -= 26;
}
sei(); // activa las interrupciones
}

Unknown source

Dejar un comentario

Saludos,
En esta ocasin acudo ante ustedes para que me den algunos consejos de
cmo puedo lograr mi cometido.
He hecho un contador up/down de 00-99 cuya variacin proviene de 2
sensores infrarrojos como los que estn en la figura.
Como observarn indico un par de flechas la 1era cuenta y la 2da descuenta.
Sin embargo, mi problema radica ahi.
Lo que quiero conseguir es que al pasar un objeto en direccin de la flecha 1
me cuente (no tengo ningn problema con eso) y seguidamente al pasar por el
sensor 2 no quiero que este lo descuente(ahi mi problema).
Lo mismo al pasar un objeto en direccin de la flecha 2 quiero que
descuente(bien) y que seguidamente al pasar por el sensor 1 no quiero que
este cuente(ahi mi problema).
Cmo podra lograr eso, lo intent con flip flops pero no lo consegu, an no
tengo clara la idea.

Si no qued muy claro miren este video desde el minuto 00:15 seg eso
quiero lograr

Hola MrCarlos nuevamente.


Luego de tanto insistir en Livewire finalmente sali
Sin embargo, lo implemente en el Proteus que es al que ms confianza le
tengo no sali :( ....
Ahora me queda implementarlo en el protoboard haber cul ser el resultado
Modifiqu tu circuito que subiste en otro post y lo adecu para mi contador
con el 74192. en livewire salio, pero no en el proteus.

http://i88.photobucket.com/albums/k1...ensorsalio.png
Despus comentar como me fue en el protoboard
felices fiestas chau!
Hola MrCarlos nuevamente.
Luego de tanto insistir en Livewire finalmente sali
Sin embargo, lo implemente en el Proteus que es al que ms confianza le
tengo no sali :( ....
Ahora me queda implementarlo en el protoboard haber cul ser el resultado
Modifiqu tu circuito que subiste en otro post y lo adecu para mi contador
con el 74192. en livewire salio, pero no en el proteus.
http://i88.photobucket.com/albums/k1...ensorsalio.png
Despus comentar como me fue en el protoboard
felices fiestas chau!
Aqui est el circuito:

---------- Actualizado despus de 2 minutos ----------

PD: Mil disculpas por la doble publicacin, me equivoqu al poner mal la


imagen al final sali pero... disculpas ^^.

Cit
ar
31/12/2011

#5

MrCarlos

Hola Luno

El
problema
que vas a
encontrar
con el
circuito
que
adjuntaste
en tu
mensaje,
es el
formado
por los 3
inversores
localizados
en la parte
baja del
esquema.
Ese
circuito, el
formado
por los 3
inversores,
es llamado
One-Shot.
Simulndol
o en
LiveWire
se
aproxima
ms a lo
que debe
hacer.

Simulndol
o en el
ISIS de
Proteus se
nota que
no lo sabe
interpretar.
Te
recomiend
o que
analices
ese
circuito en
los 2
simuladore
s por
medio de
un
osciloscopi
o.
Lo que
hace el
circuito
llamado
One-Shot
es lo
siguiente:
Cuando
baja la
seal de
entrada, la
salida del
inversor
que tiene

el
capacitor
en su
salida va
subiendo
de nivel
hasta
alcanzar el
nivel de
umbral del
74LS04,
cuando
llega a ese
nivel, el
segundo
inversor
siente un
uno en su
entrada y
cambia el
estado de
sus salida
a cero.
El inversor,
de la parte
superior,
solo
cumple su
cometido
invirtiendo
la seal de
entrada.
A la salida
del circuito
aparece un

pulso
positivo y
el ancho
de este
depende
del valor
del
capacitor.
saludos
a sus
ordenes

Cita
r

01/01/2012

Daniel Meza

#6

Cabe recalcar que uno de los pines sea 4 o 5 debe estar en 1


lgico para que el otro pueda contar o descontar segn sea el
caso

All est la clave...


Con respecto al circuito en livewire, me parece
sospechosa esa conexin de los inversores con un CI
comn como el 7404, a la larga podra ser que se
quemarn por su conexin de salidas en comn, para
evitar ese problema utiliza unos inversores con salida a
colector abierto como el 7405.. R7 (1k) har la funcin
de resistor de pull-up (que creo que es su razn de estar
all en ese circuito).
Saludos y buen inicio de ao

Citar

01/01/2012

Luno

#7

Gracias por sus respuesta lo tomar mucho en cuenta,


sin embargo sabe alguien como utilizar los flip flops en el
isis proteus por que no simula nada.... a comparacin con
el livewire que si lo hace...
??
PD:Felices Fiestas

01/01/
2012

Citar

#8

MrCar Hola Luno


los

Podras adjuntar el archivo .DSN que genera el ISIS de Proteus para


ver si descubro el Por Qu no funcionan los Flip-Flop's?.
saludos
a sus ordenes

Citar

02/01/
2012

#9

Luno

Hola MrCarlos ya no fue problema solucionar los FF ahora si funcionan.


Sin embargo, al implementarlo en el protoboard no me fnciona, revis

las conexiones y los cables estabban en buen estado, adems de los


IC's..
Adems implemente este circuito q colg fogonazo hace mucho
tiempo: Sensor para conteo de persona a un recinto
lo simul en livewire como en el isis, y los mismo que antes, asi
que..........
Ahora finalemente hize esto:

y si me func tanto en el Liv como en la realidad..... la nica


desventaja es que si la persona o el objeto se mantiene un tiempo
mayor al que establec en el 555 monoastable(para el 1er sensor) y
pasa luego por 2do sensor... ya no contara xD.... no importa... ya
ver otra solucin. Gracias por tu tiempo
---------- Actualizado despus de 15 minutos ----------

Corrijo el Pin DN (4) del 74192 debera estar conectado con el Q


negado y no con el Q.

Citar

03/01/2012

MrCarlos

#10

Hola Luno
Pero creo que te ests desviando de lo que mencionas en
tu mensaje original.
Supongo, por lo que mencionas all que hay una sola
entrada-salida. De tal suerte que cuando pasa un objeto
por ambos sensores el sistema que pretendes desarrollar
debe contar +1 o 1 dependiendo de qu sensor detect
el cruce del objeto.
Vamos a suponer que tienes, en un solo carril, Sensor
Afuera(S1), Sensor Adentro(S2).
Si se acciona S1 luego S2, estn entrando, debe contar
+1.
Si se acciona S2 luego S1, estn saliendo, debe contar
1.
Si el contador llega al mximo permitido debe indicarlo
con una alarma sonora o visible. Indicando que est
lleno.

ARDUINO + SENSOR
IR + CTRL REMOTO
arduino
control remoto

Este
proyecto
nos permitir controlar
dispositivos
conectados a la tarjeta Arduino a travs de una interfaz
infrarroja
y
usando
el
control
de
la televisin podremos encender las luces, ventiladores, o
lo que se te ocurra.

MATERIALES
1
1
1
1
4

Tarjeta Arduino (Uno, Nano o Mega)


Detector Infrarrojo TSOP4838
Capacitor de 47uF
Control Remoto IR
Leds

DESCRIPCIN
Arduino.Tarjeta
de
control
programable
que
nos permitir moldear nuestro proyecto para cada una de
nuestras necesidades, para este caso solo usaremos cuatro
salidas
y
una
entrada
digital,
en
el
esquema
de conexin podremos ver que pines o puertos usaremos,
recordemos que podemos usar cualquier puerto de la tarjeta
siempre y cuando sea digital.
TSOP4838.- Es un receptor infrarrojo de 38 kHz,
nos permitir recivir las seales del control remoto, para ello
pueden usar controles de TV, DVD u otros de la marca Sony,
Samsung, LG o Universales.

ESQUEMA DE CONEXIN

Como se puede ver en el diagrama estamos usando


el PIN2 para recibir la informacin generada por el receptor IR.

BSQUEDA DE CDIGOS DEL CONTROL REMOTO


Como primer paso tenemos que obtener los cdigos generados
por los controles, abrimos un nuevo Scketch en el Software de
Arduino
y
escribimos
el
siguiente cdigo:
/******************************************/*
#include
<IRremote.h>
int
ReceptorIR
=
2;
IRrecv
irrecv(ReceptorIR);
decode_results
Codigo;
void

setup()
{
Serial.begin(9600);
irrecv.enableIRIn();
}

void

loop()
{
if
(irrecv.decode(&Codigo))
{
Serial.print("0x");
Serial.println(Codigo.value,
HEX);
delay(50);
irrecv.resume();
}
}
/******************************************/*
Para que el compilador pueda correr sin problemas este cdigo,
debes tener instalada la libreraIRremote, una vez descargada
debes descomprimirla y pegar todo el contenido dentro de la
carpetalibreries de
Arduino.
Cuando el compilador no emita ningn error en el cdigo, sera
enviado a la tarjeta Arduino y debers abrir el Monitor
Serial que contiene el compilador, presionas un botn de tu
control remoto y podrs ver en el Monitor Serial el
cdigo hexadecimal que genera el botn al ser presionado.

En el monitor serial aparecieron los cdigos al presionar los


botones
1(0xFD609F),
2(0xFD906F)
y
3(0xFD807F).
Por el momento usaremos el control y al receptor infrarrojo
como interfaz de usuario, manipularemos el encendido de unos
leds conectados a los puertos digitales de nuestra tarjeta
Arduino.

Como pueden ver en el diagrama anterior los nodos (+) de los


leds estn conectados a los pines 8, 9 y 10 en los puertos
digitales
y
los ctodos (-).

Ahora crearemos un cdigo en el compilador de Arduino que nos


permita encender y apagar los leds desde el control remoto,
claro usando los cdigos que adquirimos en el programa
anterior.
Considerando que el control remoto es un men de opciones
disearemos el cdigo del programa usando Switch-Case.

/*****************************************************
****/*
#include
<IRremote.h>
int
ReceptorIR
=
2;
int
Led1=8;
int
Led2=9;
int
Led3=10;
IRrecv
irrecv(ReceptorIR);
decode_results
Codigos;
void
{

setup()
Serial.begin(9600);
irrecv.enableIRIn();
pinMode(Led1,OUTPUT);
pinMode(Led2,OUTPUT);
pinMode(Led3,OUTPUT);

}
void
{

loop()
if

(irrecv.decode(&Codigos))
switch

{
(Codigos.value)

{
case 0xFD609F: //codigo boton1
digitalWrite(Led1, HIGH);//Encender Led1
break;
case 0xFD906F: //codigo boton2
digitalWrite(Led2, HIGH);//Encender Led2
break;
case 0xFD807F: //codigo boton3
digitalWrite(Led3, HIGH);//Encender Led3
break;
case 0xFD902F: //codigo boton4
digitalWrite(Led1, LOW);//Apagar Led1
break;
case 0xFD912F: //codigo boton5
digitalWrite(Led2, LOW);//Apagar Led2
break;
case 0xFD805F: //codigo boton6
digitalWrite(Led3, LOW);//Apagar Led3
break;
}
irrecv.resume();
}

}
/*****************************************************
******/*
Si siguieron los pasos de este tutorial, ahorita deben estar
probando el encendido de sus leds e imaginando donde lo
aplicaran, en la siguiente entrada publicare como utilizar estas
salidas digitales para activar focos, ventiladores o cualquier otro
elemento de mayor potencia.

También podría gustarte