Radio Head (ASK) and IRremote Incompatible?

Hello, everyone!

I have an Arduino Mega running with Voice Recognition for some time now, and I'm adding the ability to talk to my other Arduino Mega running across the house using Radio Head. I manage to get both communicating perfectly but I have one major problem.

I was already using an IR Led with the IR Remote library to send some commands to my Samsung TV and HT, that was working perfectly.

But when I added the Radio Head code, the IR stops working. I saw that both relays on Arduino timer's for work, but as I understand I'm already using one timer for each.

IR Remote:

// Arduino Mega
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  //#define IR_USE_TIMER1   // tx = pin 11
  #define IR_USE_TIMER2     // tx = pin 9
  //#define IR_USE_TIMER3   // tx = pin 5
  //#define IR_USE_TIMER4   // tx = pin 6
  //#define IR_USE_TIMER5   // tx = pin 46

Radio Head:

// RH_ASK on Arduino uses Timer 1 to generate interrupts 8 times per bit interval
// Define RH_ASK_ARDUINO_USE_TIMER2 if you want to use Timer 2 instead of Timer 1 on Arduino
// You may need this to work around other libraies that insist on using timer 1
// Should be moved to header file
//#define RH_ASK_ARDUINO_USE_TIMER2

The IR Led still blinks, but with less intesivity ("less brighter"), than without the Radio Head code (I remove the code, it start's working again) , and it isn't recognized anymore.

I already even tried to uncomment the timer2 from Radio Head with timer 3 or 4 from IR Remote, but none worked.

Any help, suggestions or tests will be much appreciated.

You can instruct radio head to use timer 2 instead of timer 1.

I don't have it in front of me atm but if you google "radio head ask use timer 2" you should find instructions

Thanks for your reply Qdeathstar.

Qdeathstar:
You can instruct radio head to use timer 2 instead of timer 1.

I don't have it in front of me atm but if you google "radio head ask use timer 2" you should find instructions

Yeah, I already tried it, as you can see, I think this is the part of the library to change the interrupt, already uncommented it to test...

Arank:
Radio Head:

// RH_ASK on Arduino uses Timer 1 to generate interrupts 8 times per bit interval

// Define RH_ASK_ARDUINO_USE_TIMER2 if you want to use Timer 2 instead of Timer 1 on Arduino
// You may need this to work around other libraies that insist on using timer 1
// Should be moved to header file
//#define RH_ASK_ARDUINO_USE_TIMER2

I already tried changing the IR Remote timer too, but couldn't find anyway to make both library's work together.

I tried Virtual Wire too, without any luck.

did you put that in the .h file? (Not in your sketch?)

Maybe is not a timer issue....

Post your code

Qdeathstar:
Post your code

Ok, sorry, here are two snippets of what I'm trying to do.

Acctually I want a 2 way communication, so both codes are pretty equal.

First one, receive an input command from Serial and send it via RF.

#include <SPI.h>
#include <RHReliableDatagram.h>
#include <RH_ASK.h>

#define RECEIVER_PIN 2
#define TRANSMITTER_PIN 8
#define ETHERNET_ADDRESS 1
#define EASYVR_ADDRESS 2

RH_ASK RadioHead(2000, RECEIVER_PIN, TRANSMITTER_PIN);
RHReliableDatagram RF(RadioHead, ETHERNET_ADDRESS);

void setup() {
  Serial.begin(115200);
  Serial.print(F("Initializing"));
  pinMode(TRANSMITTER_PIN, OUTPUT);
  Serial.println(F("..."));
  Serial.println(F("..."));
  if (!RF.init()) {
    Serial.println("RadioHead initializiation failed.");
  }
}

void loop() {
  if (RF.available()) {
    readRadioHead();
  }
  if (Serial.available()) {
    serialRead();
  }
}

void serialRead() {
  char input[64];
  char command[32];
  char value[32];
  if (Serial.available()) {
    Serial.readBytesUntil('\n', input, sizeof(input));
  }
  sscanf(input, "%31[^=]=%31s", command, value);
  if (strstr(command, "POWER") && atoi(value) == 1) sendRadioHead("POWER=1");
  else if (strstr(command, "PLAY") && atoi(value) == 1) sendRadioHead("PLAY=1");
}

boolean sendRadioHead(char send[64]) {
  char reply[64];
  byte size = sizeof(reply);
  if (RF.sendtoWait((byte *)send, strlen(send), EASYVR_ADDRESS)) {
    Serial.printf(F("Sending: %s"), send);
    if (RF.recvfromAckTimeout((byte *)reply, &size, 2000)) {
      Serial.printfn(F(" (Reply: %s.)"), reply);
      return true;
    }
    else {
      Serial.println(F(" (No reply)."));
    }
  }
  else {
    Serial.println(F("sendtoWait failed."));
  }
  return false;
}

boolean readRadioHead() {
  char receive[64];
  char reply[64];
  char command[32];
  char value[32];
  byte size = sizeof(receive);
  if (RF.recvfromAck((byte *)receive, &size)) {
    sscanf(receive, "%31[^=]=%31s", command, value);
    Serial.printf(F("Request: %s=%s"), command, value);
    if (RF.sendtoWait((byte *)reply, strlen(reply), ETHERNET_ADDRESS)) {
      Serial.printfn(F(" (Reply: %s.)"), reply);
      return true;
    }
    else {
      Serial.println(F(" (Reply failed)."));
    }
  }
  return false;
}

Second one, receive the input command from RF and send the IR command.

#include <SPI.h>
#include <Livolo.h>
#include <RHReliableDatagram.h>
#include <RH_ASK.h>
#include <IRremote.h>

#define RECEIVER_PIN 2
#define TRANSMITTER_PIN 8
#define ETHERNET_ADDRESS 1
#define EASYVR_ADDRESS 2

IRsend IR;
RH_ASK RadioHead(2000, RECEIVER_PIN, TRANSMITTER_PIN);
RHReliableDatagram RF(RadioHead, EASYVR_ADDRESS);

void setup() {
  Serial.begin(115200);
  Serial.print(F("Initializing"));
  pinMode(TRANSMITTER_PIN, OUTPUT);
  Serial.println(F("..."));
  if (!RF.init()) {
    Serial.println("RadioHead initializiation failed.");
  }
  delay(2500);
}

void loop() {
  if (RF.available()) {
    readRadioHead();
  }
}

boolean sendRadioHead(char send[64]) {
  char reply[64];
  byte size = sizeof(reply);
  if (RF.sendtoWait((byte *)send, strlen(send), ETHERNET_ADDRESS)) {
    Serial.printf(F("Sending: %s"), send);
    if (RF.recvfromAckTimeout((byte *)reply, &size, 2000)) {
      Serial.printfn(F(" (Reply: %s.)"), reply);
      return true;
    }
    else {
      Serial.println(F(" (No reply)."));
    }
  }
  else {
    Serial.println(F("sendtoWait failed."));
  }
  return false;
}

boolean readRadioHead() {
  char receive[64];
  char reply[64];
  char command[32];
  char value[32];
  byte size = sizeof(receive);
  if (RF.recvfromAck((byte *)receive, &size)) {
    sscanf(receive, "%31[^=]=%31s", command, value);
    Serial.printf(F("Request: %s=%s"), command, value);
    if (strstr(command, "POWER") && atoi(value) == 1) IR.sendSAMSUNG(0xE0E040BF, 32);
    else if (strstr(command, "PLAY") && atoi(value) == 1) IR.sendSAMSUNG(0xE0E0E21D, 32);
    if (RF.sendtoWait((byte *)reply, strlen(reply), ETHERNET_ADDRESS)) {
      Serial.printfn(F(" (Reply: %s.)"), reply);
      return true;
    }
    else {
      Serial.println(F(" (Reply failed)."));
    }
  }
  return false;
}

I'm using this RF modules:
Transmitter
Receiver

The transmitting / receiving part works "fine", but the IR part simply doesn't work, as I said the IR Led still blinks, but with less intesivity ("less brighter") and the commands aren't recognized by the TV or the HT anymore.

hmm, does it work now without the RH_ASK code?

Qdeathstar:
hmm, does it work now without the RH_ASK code?

Yes, it works normally.

Depending on how you have designed the circuit (?), it could be that when everything is connected there isn't enough current being supplied?

So how are you wiring/powering the RF & IR circuits.

AnalysIR:
Depending on how you have designed the circuit (?), it could be that when everything is connected there isn't enough current being supplied?

So how are you wiring/powering the RF & IR circuits.

Hi AnalysIR, thanks for your reply.

I'm powering everything directly from the Arduino, the RF transmitters / RF receveirs are powered using 3,3V a data pin and the ground.
And the IR emitter with 5V, a data pin with a 47ohm resistor (I was using a 100ohm, but both seens to work) and the ground.
I'm using a 12V 1A power supply.

Do you think it's possible that the current isn't enough?

If the Arduino is powered from 5V, you should power the IR receiver from 5v.

You should check/verify the max current you can draw from any pin & in total from the Arduino pins.

The min restor if you are driving an IR LED directly from a data pin is 75R (altrenatively use 100R). These things could combine to cause issues.

Might be a good idea to post a layout for your wiring (hand drawn is OK)

AnalysIR:
If the Arduino is powered from 5V, you should power the IR receiver from 5v.

You should check/verify the max current you can draw from any pin & in total from the Arduino pins.

The min restor if you are driving an IR LED directly from a data pin is 75R (altrenatively use 100R). These things could combine to cause issues.

Might be a good idea to post a layout for your wiring (hand drawn is OK)

I'm sorry, by transmitters / receivers I mean the RF modules (Transmitter/Receiver) that need to be powered from 3,3V.

I was using a 100ohm resistor, but I made some tests with the 47ohm. I tought that the problem might be the range, but it didn't change a thing actually.

I made a layout using Fritzing:

I'm using the EasyVR shield on the top of the Arduino Mega.

Based on a quick review, it all seems fine, subject to:

  • The max current draw on the 3V3 pin can be 50mA
  • I assume the transistor, is the IR receiver. This should be powered from 5V and it seems wired incorrectly in your diagram.

If you have some capacitors, putting one on the 3V3 line might be a good idea.
However, it doesnt look like current is an issue - so you need to look into timer conflicts.
It is possible to change the timer used by IRremote within the library.

You can do this by un-commenting/commenting the relevant lines in the library...IRremoteInt.h

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  //#define IR_USE_TIMER1   // tx = pin 11
  #define IR_USE_TIMER2     // tx = pin 9
  //#define IR_USE_TIMER3   // tx = pin 5
  //#define IR_USE_TIMER4   // tx = pin 6
  //#define IR_USE_TIMER5   // tx = pin 46

It uses Timer2 by defualt, so start with Timer5 and work your way back. Note the tx pin changes with the timer used.

AnalysIR:
Based on a quick review, it all seems fine, subject to:

  • The max current draw on the 3V3 pin can be 50mA
  • I assume the transistor, is the IR receiver. This should be powered from 5V and it seems wired incorrectly in your diagram.

If you have some capacitors, putting one on the 3V3 line might be a good idea.
However, it doesnt look like current is an issue - so you need to look into timer conflicts.
It is possible to change the timer used by IRremote within the library.

You can do this by un-commenting/commenting the relevant lines in the library...IRremoteInt.h

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)

//#define IR_USE_TIMER1  // tx = pin 11
  #define IR_USE_TIMER2    // tx = pin 9
  //#define IR_USE_TIMER3  // tx = pin 5
  //#define IR_USE_TIMER4  // tx = pin 6
  //#define IR_USE_TIMER5  // tx = pin 46



It uses Timer2 by defualt, so start with Timer5 and work your way back. Note the tx pin changes with the timer used.

That was my first shot, tried every timer and none seens to work with the Radio Head, I tried to change the Radio Head timer, and tried to use Virtual Wire too.

Arank:
Radio Head:

// RH_ASK on Arduino uses Timer 1 to generate interrupts 8 times per bit interval

// Define RH_ASK_ARDUINO_USE_TIMER2 if you want to use Timer 2 instead of Timer 1 on Arduino
// You may need this to work around other libraies that insist on using timer 1
// Should be moved to header file
//#define RH_ASK_ARDUINO_USE_TIMER2