IRemote sending and receiving in the same sketch - problem

Hello, I’m trying to make an universal remote to guide all of my HiFi appliances but found strange problem and couldn’t find any solution since.

I’m running a simple sketch that is supposed to listen for commands fom one remote and than send over IR led different signal. The case I’m having is that it works … but only ONCE.

Here is my code:

#include <IRremote.h>

IRsend irsend;
int RECV_PIN = 9;
IRrecv irrecv(RECV_PIN);
decode_results results;

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

void loop() {
  
     if (irrecv.decode(&results)) {
       switch (results.value) {
         case 0xC1AA09F6: // ON OFF
            for (int i = 0; i < 3; i++) {
            irsend.sendSony(0xa81, 12); // Amp ON/OFF
            delay(40);            
            }
            Serial.println("On-off");
            break;
 
         case 0x5EA108F7: // tuner in
            for (int a = 0; a < 3; a++) {
            irsend.sendSony(0x841, 12); // tuner
            delay(40);            
            }
            Serial.println("TUNER");
           break;
            
         case 0x5EA18877: // tv in
            for (int b = 0; b < 3; b++) {
            irsend.sendSony(0x241, 12); // tv in
            delay(40);
            }
            Serial.println("TV");
            break;
         }
   irrecv.resume();
   }
}

Now if you replace the “irsend.sendSony(bla bla bla)” with any other function the loop will work repeatadly but for some case it stops responding after one case is finished (succesfully sending the signal over IR led). When the program is loaded, it waits for the signal and when it gets it, it accurately sends the corresponding signal through IR led. But only once. I suspect that this must be a problem of the library handling both sending and receiving in the same time becasue this sketch will work repeatadly for every button if we change this one line of code:

#include <IRremote.h>

IRsend irsend;
int RECV_PIN = 9;
IRrecv irrecv(RECV_PIN);
decode_results results;

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

void loop() {
  
     if (irrecv.decode(&results)) {
       switch (results.value) {
         case 0xC1AA09F6: // ON OFF
            for (int i = 0; i < 3; i++) {
           Serial.println("on"); // HERE IS THE CHANGE
            delay(40);            
            }
            Serial.println("On-off");
            break;
 
         case 0x5EA108F7: // tuner in
            for (int a = 0; a < 3; a++) {
            Serial.println("tuner"); // HERE IS THE CHANGE
            delay(40);            
            }
            Serial.println("TUNER");
           break;
            
         case 0x5EA18877: // tv in
            for (int b = 0; b < 3; b++) {
            Serial.println("tv");  // HERE IS THE CHANGE
            delay(40);
            }
            Serial.println("TV");
            break;
         }
   irrecv.resume();
   }
}

Does anybody know what is happening or have any solution?

IRRemote Shirriff library?

Troubleshooting section:
"The library does not support simultaneous sending and receiving of codes; transmitting will disable receiving."

Wow, that's a straightforeward and fast answer - great thanks.

Hmmm... do you see any solution? Mayby I can restart the receiving part after something was transmitted?

Sorry, I don't know. But if you send, you need to use enableIRSend() or a similar function.
You can also search on internet, I think someone have a solution. Or a new library.

Thanks for the reply. You pointed me in right direction. Searching for send&receive ir library I've found this:

Seams like targettio, needed the library to be able to send and receive in the same sketch and so ... he changed the original one to do it:)

I will test this later today. After testing I will post some info in here - for anybody searching.

Hmmm… didn’t work the way I expected.

I get many compiler errors at first. I managed to kill some of those but I still get one.

The problem is as compiler states:

In file included from test_send_rec_ir.ino:3:
C:\Program Files (x86)\Arduino\libraries\IRremote/IRremoteInt.h:123: error: ‘uint8_t’ does not name a type
C:\Program Files (x86)\Arduino\libraries\IRremote/IRremoteInt.h:124: error: ‘uint8_t’ does not name a type
C:\Program Files (x86)\Arduino\libraries\IRremote/IRremoteInt.h:125: error: ‘uint8_t’ does not name a type
C:\Program Files (x86)\Arduino\libraries\IRremote/IRremoteInt.h:128: error: ‘uint8_t’ does not name a type

That’s all from the compiler.

The code that returns this is:

#include <IRremote.h>
#include <IRremoteInt.h>

IRsend irsend;
int RECV_PIN = 9;
IRrecv irrecv(RECV_PIN);
decode_results results;

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

void loop() {
  
     if (irrecv.decode(&results)) {
       Serial.println(results.value, HEX);
       switch (results.value) {
         case 0xC1AA09F6: // ON OFF
            for (int i = 0; i < 3; i++) {
            irsend.sendSony(0xa81, 12); // Amp ON/OFF
            delay(40);            
            }
            Serial.println("On-off");
            break;
 
         case 0x5EA108F7: // tuner in
            for (int a = 0; a < 3; a++) {
            irsend.sendSony(0x841, 12); // tuner
            delay(40);            
            }
            Serial.println("TUNER");
            break;
            
         case 0x5EA18877: // tape 2
            for (int b = 0; b < 3; b++) {
            irsend.sendSony(0x241, 12); // tape 2
            delay(40);
            }
            Serial.println("TV");
            break;
            
         }
   irrecv.resume();
   }
}

Couldn’t find any information how to fix this and what is causing this problem. Any clue how to fix?

OK - I’ve managed that thanks to johnwasser’s comment in other thread. I changed:
#include <WProgram.h>
to
#include <Arduino.h>
in IRRemoteInt.h.

And the program compiled well, but - still it works the same way as it did with the original library. Only one time the code gets received and than the IR led sends and … that’s it. No more reaction for any input from remote.
Arghhh…

Perhaps you need to call enableIRIn() again after sending.

PaulS:
Perhaps you need to call enableIRIn() again after sending.

This man has it right (as usual).

Call enableIRIn() straight after the send and before the resume(). That should do it. I haven’t played with an arduino for a long time, but I understand the library is a little out of date (#include <Arduino.h>). I will see if I can update them some time.

Here is an example from my own code:

#include <IRremote.h>
#include "STVDecCode.h"
#include "ONKYO605DecCode.h"
#include "FakeMCEDec.h"

int RECV_PIN = 8;

IRrecv irrecv(RECV_PIN);
IRsend irsend;
decode_results results;

int STATUS_PIN = 13;
unsigned long codeValue; // The code value if not raw

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

void loop() 
{
  if (irrecv.decode(&results)){
    Serial.println(results.value, DEC);
    codeValue = results.value;
    
    //VOL UP
    if (codeValue == STV_VOL_UP_DEC or codeValue == FMCE_Vol_Up_DEC or codeValue == 2976128878){
      digitalWrite(STATUS_PIN, HIGH);      
      for (int i = 0; i < 2; i++) {
        irsend.sendNEC(ONKYO605_Reciever_Vol_Up_DEC, 32);
        delay(100);
      }
      Serial.println("VOl Up Sent");
      digitalWrite(STATUS_PIN, LOW);
      irrecv.enableIRIn();
    }
    
    //VOL DOWN 
    if (codeValue == STV_VOL_DOWN_DEC or codeValue == FMCE_Vol_Down_DEC or codeValue == 3433199758){
      digitalWrite(STATUS_PIN, HIGH);
      for (int i = 0; i < 2; i++) {
        irsend.sendNEC(ONKYO605_Reciever_Vol_Down_DEC, 32);
        delay(100);
      }
      Serial.println("VOl Down Sen");
      digitalWrite(STATUS_PIN, LOW);
      irrecv.enableIRIn();
    }
    
    //MUTE
    if (codeValue == STV_MUTE_DEC or codeValue == FMCE_MUTE_DEC or codeValue == 1815191114){
      digitalWrite(STATUS_PIN, HIGH);
      for (int i = 0; i < 2; i++) {
        irsend.sendNEC(1270259807, 32);
        delay(100);
      }
      Serial.println("Mute Sent");
      digitalWrite(STATUS_PIN, LOW);
      irrecv.enableIRIn();
    }  
    irrecv.resume(); // resume receiver
  }
  
}

Wow, many thanks for the feedback to both of you. I will check it after work.

Hope that works:)

I was so desperate that already was thinking about:
a) restarting arduino after each "send"
b) useing RF remote just for sending the initial and than sending ir signal not to deal with send and receive togheter in one sketch.

Also I realized that your "keywords.txt" don't work anymore and i fixed that (spacebars instead of tabs). I will post the working one when I get home.

Arfuino 1.0 changed a bunch of things. Undoubtly there are a number of problems with all my old stuff.

It WORKS!

The code that works -

#include <IRremote.h>
#include <IRremoteInt.h>

IRsend irsend;
int RECV_PIN = 9;
IRrecv irrecv(RECV_PIN);
decode_results results;

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

void loop() {
  
     if (irrecv.decode(&results)) {
       Serial.println(results.value, HEX);
       switch (results.value) {
         case 0xC1AA09F6: // ON OFF
            for (int i = 0; i < 3; i++) {
            irsend.sendSony(0xa81, 12); // Amp ON/OFF
            irrecv.enableIRIn();
            delay(40);            
            }
            Serial.println("On-off");
            break;
 
         case 0x5EA108F7: // tuner in
            for (int a = 0; a < 3; a++) {
            irsend.sendSony(0x841, 12); // tuner
            irrecv.enableIRIn();
            delay(40);            
            }
            Serial.println("TUNER");
            break;
            
         case 0x5EA18877: // tape 2
            for (int b = 0; b < 3; b++) {
            irsend.sendSony(0x241, 12); // tape 2
            irrecv.enableIRIn();
            delay(40);
            }
            Serial.println("TV");
            break;
            
         }
   irrecv.enableIRIn();
   irrecv.resume();
   }
}

And below the library with changed IRremoteInt.h and keywords.txt to work on Arduino 1.0
www.meggot.nazwa.pl/TEMP/IRremote.zip
Auto cleaning on FTP will delete it in 30 days.

Thank you for help.

Hi @ethelder, thank you for your testing work.
Have you tried your code with only one enableIR, the last, removing the three enableIR in the if ?

Just checked it (one irrecv.enableIRIn(); just before irrecv.resume(); - WORKS as well:)

BTW - I'm moving to another stage of testing for this project. If you would like to help me as well with the circuit than:
http://forum.arduino.cc/index.php?topic=199099.0

Thanks in advance.

I want to receive remote TV signal by Arduino and send it back to Ardino to tv the program code show me?

Thank you ethelder for posting this.
I've been trying to do the same thing with a projector and stereo system for days and it hasn't worked until I used your code.
I really appropriate it. :slight_smile:

You've made 2020 just a tad bit more bearable from way back in 2013.

Edit: Never mind, Apparently all my devices are NEC and my projector won't receive the signal even though I can see it sending through my phone camera.

The boarddefs.h file contains these two macros:

#define TIMER_DISABLE_INTR  (TIMSK2 = 0)
#define TIMER_ENABLE_INTR   (TIMSK2 = _BV(OCIE2A))

When sending IR, one of the first steps is turning off the overflow interrupt used for IR Receive:

void  IRsend::enableIROut (int khz)
{
#ifdef USE_SOFT_CARRIER
	periodTime = (1000U + khz/2) / khz; // = 1000/khz + 1/2 = round(1000.0/khz)
	periodOnTime = periodTime * DUTY_CYCLE / 100U - PULSE_CORRECTION;
#endif
	
	// Disable the Timer2 Interrupt (which is used for receiving IR)
	TIMER_DISABLE_INTR; //Timer2 Overflow Interrupt

It should be sufficient to turn the interrupt back on just before calling irrecv.resume():

   TIMER_ENABLE_INTR;
   irrecv.resume();

johnwasser:
It should be sufficient to turn the interrupt back on just before calling irrecv.resume():

   TIMER_ENABLE_INTR;

irrecv.resume();

You're awesome! This has been the solution I was looking for - Only thing is there is a conflict between IR Remote by Shiriff and the Piezo buzzer timer, so I've changed the IR Remote board definition from timer2 to timer1 for my arduino UNO. After I transmit and IR signal and do:

TIMER_ENABLE_INTR;
irrecv.resume()

I get an issue with the buzzer again - I'm sure it has something to do with the timer but not sure how to fix it. Basically how the buzzer sounds before and after sending an IR signal is different - the sound produced becomes elongated for some reason.

darkhero567:
I get an issue with the buzzer again - I'm sure it has something to do with the timer but not sure how to fix it. Basically how the buzzer sounds before and after sending an IR signal is different - the sound produced becomes elongated for some reason.

The code you posted above does not mention a buzzer. If you would like help figuring out what might be wrong, please post your latest sketch.

#include <IRremote.h>
#include <IRremoteInt.h>

#include <boarddefs.h>
#include <ir_Lego_PF_BitStreamEncoder.h>
#include "pitches.h"

const int RECV_PIN = 8;
const int EMIT_PIN = 3;
const int Buzzer = 4;
const int Speaker = 12;
const int Button_PIN = 13;
// Define IR Receiver and Results Objects
IRrecv irrecv(RECV_PIN);
IRsend irsend;
decode_results results;

int buttonstate = 0;

//player stats
int health = 100;
int dmg = 16;
int dmgdelay = 300;
boolean dead = false;


void setup(){
  // Serial Monitor @ 9600 baud
  Serial.begin(9600);
  // Enable the IR Receiver
  irrecv.enableIRIn();
  pinMode(Button_PIN, INPUT);
  pinMode(EMIT_PIN, OUTPUT);
}

void loop(){
  receiveIR();
  isDead();

  checkButton();
    if(buttonstate == HIGH){
        irsend.sendSony(0xa81, 12); // Amp ON/OFF
        delay(40); 
        TIMER_ENABLE_INTR;
    }
}

void checkButton(){
  buttonstate = digitalRead(Button_PIN);
}

void isDead(){
  if(health > 0){
    dead = false;
  }else{
    dead = true;
    health = 0;
    tone(Buzzer, 3333);
    delay(500);
    noTone(Buzzer);
  }
}

void spacegun(int maximum){
  for(int i =0; i < maximum; i++){
    tone(Speaker, 330);
    delayMicroseconds(i);
    noTone(Speaker);
    delayMicroseconds(i);
  }
}


void receiveIR(){
  if (irrecv.decode(&results)){
        Serial.println(results.value, HEX);
        switch(results.value){
          case 0x8A8: //button number 4 on remote
          case 0x18A8:
          case 0xBEB9FC8:
          case 0x49B0F625://hit
            if(!dead){
            health -= dmg;
            spacegun(600);
            Serial.print("Health");
            Serial.println(health);
            }
        break; 
          case 0x8AD: // button number 6 on remote
          case 0x18AD: // heal/respawn
            health = 100;
            tone(Buzzer, 660);
            delay(400);
            noTone(Buzzer);
        break;
    }
      irrecv.resume();
  }
  }

Here is my code. There’s known issues between the Tone function and Shiriffs Library which was fixed by changing the boarddef.h file timer from 2 to 1.

The issue occurs after I press the button on my board as that triggers the IR led to transmit. Then if I trigger “spacegun(600);” that uses the tone function again it sounds elongated.