Problema al usar varios lectores IR al mismo tiempo (SOLUCIONADO)

Hola:
Estoy usando lectores IR tipo HX1838


Todo perfecto usando la libreria <IRremote.h> y un solo lector IR

Ejemplo del código usando uno solo:

#include <IRremote.h>

int RECV_PIN = 11;

IRrecv irrecv(RECV_PIN);
decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value
  }
  delay(100);
}

El problema es al usar dos lector al mismo tiempo, ajusto el codigo como tal, pero no me lee nada.
Pon aqui el codigo que uso para dos lectores IR:

#include <IRremote.h>

int RECV_PIN1 = 11;
int RECV_PIN2 = 10;

IRrecv irrecv1(RECV_PIN1);
decode_results results1;
IRrecv irrecv2(RECV_PIN2);
decode_results results2;

void setup()
{
  Serial.begin(9600);
  irrecv1.enableIRIn(); // Start the receiver
  irrecv2.enableIRIn(); // Start the receiver

}

void loop() {
  if (irrecv1.decode(&results1)) {
    Serial.println(results1.value, HEX);
    irrecv1.resume(); // Receive the next value
  }
if (irrecv2.decode(&results2)) {
    Serial.println(results2.value, HEX);
    irrecv2.resume(); // Receive the next value
  }
  delay(100);
}

Alguna idea de como se puede usar esta librería para mas de un Lector IR
Gracias

El problema es que, aparentemente, no puedes usar la librería de esa forma.
Te dejo la traducción de una FAQ de la página de GitHub de IRremote, referida al tema

Puede utilizar varios receptores de infrarrojos 
simplemente conectando los pines de salida de varios 
receptores de infrarrojos juntos.  
Los receptores de infrarrojos utilizan un transistor 
NPN como dispositivo de salida con solo una resistencia 
de 30k a VCC.  
Esto es casi un "colector abierto" y permite conectar 
varios pines de salida a un pin de entrada de Arduino.

Saludos

Muchas gracias. He de probar, aunque no se como arduino me va diferenciar entre los dos.

Miro y os cuento

Hi,
Consejo si buscas las especificaciones del sensor en las paginas finales explican como alambrar el sensor con las resistencias como te sugerio pepoye.Otra cosa que tienes que tener en consideracion es que ellos trabajan a una frecuecia de 38Khz. Tiene que darle tiempo para leeerllos.

Cuando leí esto me vino a la cabeza el recuerdo de NewPing y su ejemplo de 15 sensores. Como NewPing puede crear un array de Objetos, pues asi

NewPing sonar[SONAR_NUM] = {     // Sensor object array.
  NewPing(41, 42, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
  NewPing(43, 44, MAX_DISTANCE),
  NewPing(45, 20, MAX_DISTANCE),
  NewPing(21, 22, MAX_DISTANCE),
  NewPing(23, 24, MAX_DISTANCE),
  NewPing(25, 26, MAX_DISTANCE),
  NewPing(27, 28, MAX_DISTANCE),
  NewPing(29, 30, MAX_DISTANCE),
  NewPing(31, 32, MAX_DISTANCE),
  NewPing(34, 33, MAX_DISTANCE),
  NewPing(35, 36, MAX_DISTANCE),
  NewPing(37, 38, MAX_DISTANCE),
  NewPing(39, 40, MAX_DISTANCE),
  NewPing(50, 51, MAX_DISTANCE),
  NewPing(52, 53, MAX_DISTANCE)
};

Entonces porque IRremote no puede hacer lo mismo?

#define IR_NUM 5

int recv_pin[IR_NUM ]  ={5, 6, 7, 8, 9, 10};

IRrecv irrecv[IR_NUM ] = {
  IRrecv irrecv(recv_pin[0]);
  IRrecv irrecv(recv_pin[1]);
  IRrecv irrecv(recv_pin[2]);
  IRrecv irrecv(recv_pin[3]);
  IRrecv irrecv(recv_pin[4]);
}

decode_results results[IR_NUM);

supongo que el setup sería

void setup()
{
  Serial.begin(9600);
  for (int i = 0; i<IR_NUM; i++) {
      irrecv[i].enableIRIn(); // Start the receiver
  }
}

void loop() {

  for (int i = 0; i<IR_NUM; i++) {
      if (irrecv[i].decode(&results[i])) {
    Serial.println(results[i].value, HEX);
    irrecv[i].resume(); // Receive the next value
  }
  delay(100); // este delay considerando que son 5 mucho no me gusta
}

No lo he probado. Asi que puede fallar pero debería andar por ahi.

Muchas gracias chicos. Voy probar y os cuento

Hola:
Pues seguimos peleando con esto. Me dio error tu codigo surbyte asi que estoy intentandolo yo.
Y es que en principio no me parece complicado con el array, aqui os pongo el codio que uso

#include <IRremote.h>
int x;
int pinesIR[]={10,11};
int RECV_PIN =pinesIR[x];

IRrecv irrecv(RECV_PIN);
decode_results results;

void setup()
{  
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value
  }
  x=1  //Probamos a ver si le asigna el valor del pin 11, x=0 seria para el pin 10
}

Como veis estoy simplemente probando a cambiar el numero del pin del Recv PIN (solo estoy probando a usar dos pines)
Con la variable X cambio ese pin a traves del array. Pero se ve que no funciona
En cambio si le asigno el valor directamente si va ,es decir , asi…

int pinesIR[]={10,11};
int RECV_PIN =pinesIR[1]

asi ya entiende que tiene asignado el pin 11, si fuera un pinesIR[0] seria el pin 10. Asi me funciona.

¿por que no me deja con la varible x? que es justo lo que necesito para cambiar los pines en el loop

Porque en tu loop cambiaste el valor de x pero olvidaste reasignar el pin para el nuevo valor de x

RECV_PIN = pinesIR[x];

Prueba y nos cuentas

PD: Igual pienso que como mínimo deberías también reinicializar el receptor con cada cambio.

nada, sigue igual. Muchas gracias de todas maneras
A ver si veo la manera.

Yo sigo convencido que si los autores de la librería dicen que para conectar más de 1 receptor hay que hacerlo en el mismo pin, es porque de otra forma no se puede.
¿Quiénes pueden saberlo mejor que ellos?

En cuanto a cómo saber cuál es el que está recibiendo, como planteaste algunos post atrás, bueno, ahí entra la mano del programador.

Hi,
Una pregunta tu dices que quires leer varios IR a la misma vez no. estos sensores van estar en el mismo sitio o van a estar en diferentes sitios y quires leerlos en forma de scanner para ver cual de ellos te esta enviado senales. Cual es la idea de leerlos todos de una vez. Yo he estado pendiente ya que te an sugerido varias ideas y todovia no te ha trabajado. Por no entender cual es el proposito de tu projecto no he podido sugerirte como hacerlo y por eso estoy haciendo estas preguntas para tener una idea de que es lo que deseas hacer.

Hola:
Muchas gracias a todos por contestar. El proyecto en si en de una aspiradora electrica (roomba). Es el encargado le leer los objetos cercanos y las leecturas de un mando inalambrico
No tengo necesisas de utilizar una lector IR, con un foto transitor me valdria. Dado que el mando no creo que lo use
Pero es por aprovechar los componentes que trae y SOBRETODO por tozudez.

gatul:
Yo sigo convencido que si los autores de la librería dicen que para conectar más de 1 receptor hay que hacerlo en el mismo pin, es porque de otra forma no se puede.
¿Quiénes pueden saberlo mejor que ellos?

En cuanto a cómo saber cuál es el que está recibiendo, como planteaste algunos post atrás, bueno, ahí entra la mano del programador.

Voy probar a concectar al mismo pin a ver que se ve. Gracias

Hi,
Yo tengo varios IR y hice varias pruebas y esto fue lo que encontre. Primero el comando de leer el sensor si no recibe senal el resultado es de zero. Entonces puedes leer diferentes sensore si cambias el pin antes del leer el sensor. En otra palabras cambiarle el pin antes de leerlo. Adjunto sketch que lee 4 modlulos continuamente. Tratalo para ver si te trabaja. Yo estoy usando un solo modulo en el pin 7 los otros son dummies.

#include <IRremote.h>
byte modulo_sel = 0 ;
int IrReceiverPin[4] = {7, 8, 9, 10};
unsigned long key_value = 0;
//*********** infrared 1
decode_results results;

//*******************************************************
void setup() {
  Serial.begin(115200);
  IRrecv irrecv(IrReceiverPin[4]);
  IRrecv IrReceiver(0);
  irrecv.enableIRIn();                // start the IR-receiver 1
}
//**********************************************************
void loop() {
  // put your main code here, to run repeatedly:

  //******* mdulo a leer ****************
  IRrecv irrecv(IrReceiverPin[0]); //<<<<<<cambia el modulo antes de leerlo

  //***********************************

  if (irrecv.decode(&results)) {
    // Print the received value as a hexadecimal value
    Serial.print("data input = ");
    Serial.println(results.value, HEX);
    irrecv.resume();
  }
  modulo_sel++;
  if ( modulo_sel > 3)modulo_sel = 0;
  Serial.print("key_value = ");
  Serial.println(results.value, HEX );
  Serial.print("Leyendo modulo  = ");
  Serial.println(modulo_sel );
  delay(1000);      // pause 100ms
}

Hola voy probar a ver, de todas maneras mirando el sketch no se muy bien para que usas las variables:
modulo_sel
key_value

Voy probar estos dias y cuanto

Hi,
La variable modulo se usa para seleccionar los modulos sin mucho esfuerzo y el key_value es para guardar el ultimo valor despues que le doy print. Yo la uso para diagnostico pues si no la usas el print corre muy rapido y no puedes leerlo en la pantalla. Yo la borra despues del print en la pantalla para ver la proxima lectura.Solamenta para diagnoctico. Recueda esto es solamente una prueba para ver como se puede seleccionar varios sensores.

Disculpa que no respondí.
Tal como dijo Gatul olvidé que IR esta asociado a un TIMER y por eso no se puede llevar adelante la idea de un vector de objetos.
Sin embargo la rutina de interrupción muestrea el in contenido en la estructura irparams strcut.
Debes analizarla.

// Allow all parts of the code access to the ISR data
// NB. The data can be changed by the ISR at any time, even mid-function
// Therefore we declare it as "volatile" to stop the compiler/CPU caching it
EXTERN  volatile irparams_t  irparams;

Entonces, cuando creas una segunda o enésima instancia de IRrec, el pin en irparams es seteado a 1. Cada Instancia de IRrecv tratará de recibir datos por ese pin.

IRrecv::IRrecv (int recvpin)
{
 irparams.recvpin = recvpin;
 irparams.blinkflag = 0;
}

Entonces el camino es modificar la librería para que soporte multiples instancias.
Esta claro que ahora no se puede.

Todo esto por el lado del software.
Que tal esta idea mas simple
Y si pones todos los recepctores al mismo pin y solo le das energía por un pin dedicado, entonces ese pin se comportará como recpetor y no los demás. Tendrías lo mismo sin alterar nada.

Se entiende? 5 recpetores con su pin de recpeción al pin que corresponde como si fuera uno.
Los 5 pines de VCC los conectas a 5 pines de salida del Arduino.
Cuando queres leer el 1, pones en HIGH ese pin mientras los demas estan en LOW.

Muy simple no, y además muy electrónico!!

ostras, que estupenda idea. Si el que sabe, sabe. Dejame probar y os digo. El finde me pongo con ello.
Muchas gracias

¡¡¡AL FIN!!!
:wink:

Hola:
Pues ya esta solucionada la cosa.
Al final el jugar con con varios pines de salida para alimentar los diferentes IR no valio.
Se ve que al meter todos al mismo GND pues no funcionaban.
Asi que hice al reves alimente a todos al mismo tiempo, y fui jungado con sus respectivos GND. Probe a usar las salidas de arduino con GND (por comodidad), pero no dio resultado. Asi que use unos transitores a modo de interruptor para gestionar el GND de cada IR.
Mejor una imagen

Los pines salida son orientativos. Los valores de las resistencias no son los correctos. El sensor Ir es el ceramico naranja, pues no encotre el dibujo correcto.

Y aqui el codigo

#include <IRremote.h>
 
const int RECV_PIN = 11;
const int IRsalida1 = 9;
const int IRsalida2 = 8;


 
IRrecv irrecv(RECV_PIN);
decode_results results;
 
void setup()
{
   pinMode (IRsalida1,OUTPUT);
   pinMode (IRsalida2,OUTPUT);   
   Serial.begin(9600);
   irrecv.enableIRIn();
}
 
void loop(){
  if ((digitalRead(IRsalida1)) == HIGH){
   if (irrecv.decode(&results)){    
      Serial.println("sensor1");
      irrecv.resume();
    }
   }
  if ((digitalRead(IRsalida2)) == HIGH){
   if (irrecv.decode(&results)){    
      Serial.println("sensor2");
      irrecv.resume();
    }
   }
   digitalWrite(IRsalida1, LOW);  //Aqui cambiamos manualmente para probar a que Sensor Ir activamos
   digitalWrite(IRsalida2, HIGH);
   
   }

Muchas gracias a todos

Genial!
Gracias por contarnos tu solución, es muy valiosa.
Saludos