Send & Receiving I.R. signals with the same Arduino Uno

Happy holidays All,

For the past few weeks I have been struggling with send and receiving I.R. codes from the same Arduino.

I am trying to develop a self contained vision system that can send a discreet signal out while also being able to detect if said signal bounces off an object. Initially my hope was that I could have the main loop cycle through sending out the signals while periodically scanning for signals via interrupts, but this did not work. I wrote the following code however it cannot seem to detect and I cannot figure out what I am missing.

I have tried to test my program by pointing an appropriately coded universal remote at the Uno just to see if it can detect signals from an independent source and while the signal is sometimes read, most of the time it does not detect the signal.

I suspect that either the code is sent before the I.R. receiver can react or that the I.R. receiver scan is so quick that it misses the signal or perhaps a combination of the two.

I also tried adding a timed loop to keep the I.R. receiver scanning for several milliseconds, but this did not work either.

Is there something fundamental that I am missing here?

// Send & Receive I.R. signals from Arduino Fio Rev. 2, JBL code 000 (NEC 32 bit protocol)

//       Hex.      Decimal
// 0 = 38863BC0 = 948321216
// 1 = 38863BE0 = 948321248
// 2 = 38863BD0 = 948321232
// 3 = 38863BF0 = 948321264
// 4 = 38863BC8 = 948321224
// 5 = 38863BE8 = 948321256

#include <IRremote.h>			            // use the library

const byte irReceiverPin = 9;                       // Pin the receiver is connected to.
IRrecv irrecv(irReceiverPin);		            // create instance of irrecv which points to Digital Pin 2.
IRsend irsend;
decode_results results;
long clock = 0;

byte LEDGround[] = {5, 8, 9, 10, 11, 12};           // Array which cycles (gound path) of Infrared LEDs. (Can the I.R Detectors be tied to I.R LED ground nodes?)
byte ReceiverPin[] = {7, 15, 16, 17, 18, 19};       // Array which cycles I.R. REceivers "On" & "Off"
long irKeyCodes[] = {
  0x38863BC0,   // 0 Key
  0x38863BE0,   // 1 Key
  0x38863BD0,   // 2 Key
  0x38863BF0,   // 3 Key
  0x38863BC8,   // 4 Key
  0x38863BE8,   // 5 Key
  0x38863BD8,   // 6 Key
  0x38863BF8,   // 7 Key
  0x38863BC4,   // 8 Key
  0x38863BE4,   // 9 Key

};


void setup()

{
  //pinMode(irReceiverPin, INPUT);                  // Not required???
  Serial.begin(9600);                               // Established serial communication at a rate of 9600 Baud
  irrecv.enableIRIn();			            // start the IR receiver
  //attachInterrupt(0, analyze, FALLING);             // Interrupt triggered by I.R. Receiver (Pin 2)
}


void loop()
{                                                   // Start of Main Loop
  for (byte i = 0; i < 6; i++)                      // Start of loop which cycles througn I.R. LED array.
  {
    irsend.sendNEC(irKeyCodes[i], 32);              // Sends 0 - 5 I.R. Codes, 32 value equals number of Bits. Is NES code 32 Bit?
    irrecv.enableIRIn();			    // start the IR receiver, needs to be restarted, terminated when I.R. is sent above.
  }                                                 // End of Main Loop


  clock = (millis() + 200);
  {
  while (clock > millis())
  {
  if (irrecv.decode(&results))		            // Have we received an IR signal?
  
  {
    switch(results.value)
    {
    case 0x38863BC0: 
      Serial.println("0"); 
      break;  // 0
    case 0x38863BE0: 
      Serial.println("1"); 
      break;  // 1
    case 0x38863BD0: 
      Serial.println("2"); 
      break;  // 2
    case 0x38863BF0: 
      Serial.println("3"); 
      break;  // 3
    case 0x38863BC8: 
      Serial.println("4"); 
      break;  // 4
    case 0x38863BE8: 
      Serial.println("5"); 
      break;  // 5
    case 0x38863BD8:
      Serial.println("6"); 
      break;  // 6 
    case 0x38863BF8:
      Serial.println("7"); 
      break;  // 7
    case 0x38863BC4:
      Serial.println("8"); 
      break;  // 8
    case 0x38863BE4:
      Serial.println("9"); 
      break;  // 9
    }
  }
  }
  irrecv.resume();			            // reveive the next value
  }
}

Thanks,

Z

  for (byte i = 0; i < 6; i++)                      // Start of loop which cycles througn I.R. LED array.
  {
    irsend.sendNEC(irKeyCodes[i], 32);              // Sends 0 - 5 I.R. Codes, 32 value equals number of Bits. Is NES code 32 Bit?
    irrecv.enableIRIn();			    // start the IR receiver, needs to be restarted, terminated when I.R. is sent above.
  }                                                 // End of Main Loop

It does NOT make sense to enable input while sending. Stop doing that. Send all the data first, and THEN enable input.

You are over-using global variables. clock does NOT need to be global.

What are you sending data to? If you think that you can send while not listening, and then listen and hope to hear an echo send hours ago, I'm afraid you are sadly mistaken.

What's the message in the signal?- is it important that you send a TV-remote-like message and get it back intact? I see you're using the received code in your sketch to print 1,2, 3 etc, but is that a real need?

If not, why bother?- you could just use an IR LED to send a beam and get it back (or not) to tell you there's something there (or not).

Thank you both for the quick replies,

PaulS,

I read that the irsend command disables the irrecv command so my intent was send out the current signal and then immediately start looking for it before advancing on to the next signal in the array.

I had assumed that I would have to look in between signals because my thinking was that the first signals would decay long before the last ones were sent. Is this not correct?

I will have to look into global variables as I am not sure where I am going wrong here.

Regarding your comment about sending while not listening... I am definitely hoping to send while listening. This is the root of my project/problem. Just to be clear I am trying to listen from the very device that I am also sending from.

JimboZA,

I am send a "remote like message" only because when I use a straight 30KHz signal the I.R. receiver detects too much noise. This has forced me to send discreet codes. I am open to simpler solutions obviously so if I am missing something please say something. I can post the 30KHz code if anyone is curious.

Very best regards,

Z

Well you could use an off-the-shelf proximity sensor like this.

I am aware of these units but unfortunately they are too large and heavy for my project.

Regardless, I effectively have built these myself and I was not able to come up with a way to discriminate between noise and a legitimate signal.

This guy seems to have had good results with a simple modulated beam with no message encoded, although you seem to have tried that?

(I note you say 30kHz?)

ZeusDashing:
I am aware of these units but unfortunately they are too large and heavy for my project.

How about this tiny little one from Pololu?

I had assumed that I would have to look in between signals because my thinking was that the first signals would decay long before the last ones were sent. Is this not correct?

There is a difference between enabling input and actually reading input.

JimboZA,

The Pololu solution is interesting but how would this help me filter unwanted noise?

PaulS,

I think that you are onto something big. One question for you, if I am not reading correctly then how is it that I sporadically detect my universal remote but not the Uno that is actually sending the signal?

Z

ZeusDashing:
system that can send a discreet signal out while also being able to detect if said signal bounces off an object.

Maybe I am I still half asleep, but how do you expect to be able to detect a signal that arrives back at the Arduino within a nanosecond?

Ping systems use sound waves, not light.

...R

Hello Robin2,

That is exactly my point which is why I have the 200 millisecond loop in place. I wanted to make sure the I.R. receiver was active long enough to see the event.

I believe it is possible to send an receive from the same Arduino unit only because I have a older version of my program which can detect objects but struggles with noise detection issues.

Thank,

Z

I believe it is possible to send an receive from the same Arduino unit

Of course it is.

It is not possible, though, to receive what is being sent. You are either sending or listening. Both at the same time is not possible.

Understood but why is the code able to send & receive reliably?

#include <IRremote.h>

//#define IRLED 3
#define SigLED 13

IRsend irsend;

byte LEDGround[] = {5, 8, 9, 10, 11, 12};          // Array which cycles (gound path) of Infrared LEDs. (Can the I.R Detectors be tied to I.R LED ground nodes?)
byte ReceiverPin[] = {7, 15, 16, 17, 18, 19};      // Array which cycles I.R. REceivers "On" & "Off"

//byte Count;

long ScanTime = 0;


// -----------------------------------------------------------------------------------------------------------

void setup()

{
  pinMode(SigLED, OUTPUT);                          // Establishes Pin 13 as an outout pin. Used to indicate if 30 KHz beam has been detected or not.
  irsend.enableIROut(32);                           // Sets I. R. frequency (PWM) at 30 KHz. Part of IRremote library. Value of 32 produces 30 KHz pules using Fio.
  irsend.mark(0);                                   // Do not understand how this effects "mark" or "pause"

  Serial.begin(9600);                               // Initialize serial communication at 9600 Baud rate.

  pinMode(3, OUTPUT);                               // Establishes Pin 3 as an input pin (Trigger for 2N2222).

  for (byte i = 1; i < 6; i++)                      // Initializes I.R. LED Emitters and I.R. Detectors
  {
    pinMode(LEDGround[i], OUTPUT);                  // Configures all I.R. LEDs as "Outputs".
    digitalWrite(LEDGround[i], LOW);                // Opens circuit paths for I.R. LEDs via the 2N2222 initializing all the I.R. LEDs.
    pinMode(ReceiverPin[i], INPUT);                 // Configures all I.R. Receivers as "Intputs". Does not use internal 20K Pull-up resistor.
    digitalWrite(ReceiverPin[i], HIGH);             // Powers up all I.R. Receivers.
  }
}


// -----------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------

void loop()

{                                                  // Start of Main Loop
  for (byte i = 0; i < 6; i++)                     // Start of loop which cycles througn I.R. LED array.
    {
      digitalWrite(LEDGround[i], HIGH);            // Supplies current to next I.R. LED in array.
      delay(10);                                   // Time to allow I.R. LED to reach full illumination. Was 100.
      ScanTime = (millis() + 50);                  // Calculates new value for ScanTime. Was 50.

      {
        while (ScanTime > millis())                // Start of "While" loop.

          if ((digitalRead(ReceiverPin[i]) == 0) && (digitalRead(LEDGround[i]) == LOW))      // Reads I. R. Receiver Pin, If equal to Zero then an object is present.
          {
            ObjectDetected(ReceiverPin[i]);
            digitalWrite(SigLED, !digitalRead(ReceiverPin[i]));
          }


        if ((digitalRead(ReceiverPin[i]) == 1) && (digitalRead(LEDGround[i]) == LOW))        // Reads I. R. Receiver Pin, If equal to One then no object is present.
        {
          Serial.println("Scanning");
          digitalWrite(SigLED, !digitalRead(ReceiverPin[i]));
        }

        digitalWrite(LEDGround[i], LOW);           // Stops current to I.R. LED.
        //delay(100);
      }                                            // End of "While" loop.
    }                                              // End of loop which cycles througn I.R. LED array.
}                                                  // End of Main Loop


// -----------------------------------------------------------------------------------------------------------

void ObjectDetected(byte Direction)

{

  switch (Direction)

  {
  case 7:                     // When var equals 7 object detected above
    Serial.println("U");      // Send "U" to Serial Port.      
    break;

  case 15:                    // When var equals 15 object detected in front
    Serial.println("F");      // Send "F" to Serial Port.
    break;

  case 16:                    // When var equals 16 object detected to left
    Serial.println("L");      // Send "L" to Serial Port.
    break;

  case 17:                    //When var equals 17 object detected to right
    Serial.println("R");      // Right
    break;

  case 18:                    // When var equals 18 object detected in behind
    Serial.println("B");      // Back
    break;

  case 19:                    // When var equals 19 object detected in below
    Serial.println("D");      // Down
    break;
  }

}

The only problem that I have with this code is that it cannot filter noise and I get false positives.

ZeusDashing:
Understood but why is the code able to send & receive reliably?

The only problem that I have with this code is that it cannot filter noise and I get false positives.

I think you need to study these two sentences carefully.

...R

IRremote (& IRLib) is not designed to receive and send at the same time. As has been mentioned previously, rx is turned off when sending and has to be re-enabled once you need to receive again.

However, it is possible to receive what you are sending on the same Arduino - if you have the appropriate code. But it makes no sense to do this as you already know what was sent so why bother, it just uses up resources. Although the signal arrives back at the speed of light - the lag passing thru the IR reciever is between 30->150uSecs.

Wouldn't it be easy to test IR LED's and transmission if you could send and receive the same signal through a single code?

Wouldn't it be easy to test IR LED's and transmission if you could send and receive the same signal through a single code?

@kaushikwavhal Yes, if you want to write code to do this.

It is probably easier to test against the taget device, like a TV.

You can check the IR LED with a DMM or digital camera(see google) or even an oscilloscope.

After that, the best test is to test against the target device.

Hi,

Not sure if I'm duplicating my post. Post it yesterday but couldn't find it now. Its why I'm doing it again. Sorry.
I want to build a remote mail detection in a physical mailbox. Using in the mail box Arduino Nano Artmega168, RF24 for communication (which is working) and KY005 and KY022 IR TX/RX sensors. At home using a Arduino UNO which is getting RF24 messages.

I want to use IR sensors so when beam is interrupted it because I got mail.
In Arduino NANO IR TX is working sending always Codes, RX LED is always flashing (even when data pin is removed/disconnected) but nothing is decoded. When I use a remote IR command it detects each of the buttons I prsss but not the code itself I'm sending in my code.

Any help is more than welcome

Thanks
Joaquim

josadossantos:
Not sure if I'm duplicating my post. Post it yesterday but couldn't find it now.

It's here.

Please don't double Post

...R