IRRemote library conflicts with tone() function

Hi,

I'm currently working on a project that combines an IR remote and a piezo sounder to play confirmation sounds.

To produce a beep on the sounder I use the command tone();

When I integrated this in my main sketch, when I got the right sounds. Tried to compile it and got the following error:

core.a(Tone.cpp.o): In function __vector_13': C:\Users\Vincent\Desktop\ARDUINO\arduino-1.0.1\hardware\arduino\cores\arduino/Tone.cpp:523: multiple definition of __vector_13'
IRremote\IRremote.cpp.o:C:\Users\Vincent\Desktop\ARDUINO\arduino-1.0.1\libraries\IRremote/IRremote.cpp:311: first defined here
c:/users/vincent/desktop/arduino/arduino-1.0.1/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../../avr/bin/ld.exe: Disabling relaxation: it will not work with multiple definitions

The IRremote.cpp files is attached

An example of a tone function I'll be using:

void PlayTone1() {
  tone(PiezoSounderPin, 3000, 8);
  delay(10);
  noTone(PiezoSounderPin);
}

Hope someone can help me with this... Thanks in advance

IRremote.cpp (27.5 KB)

1 Like

With a bit more scouting work i figured it out myself.

Apperently the function tone() uses timer 2 wich, by default, the IRremote also uses when using a ATmega2560 chip.

In the file IRremoteInt.h, you can define wich timer to use. Everything works now!

vlw kra, me ajudou muito.

thank guy....

vicvegax:
vlw kra, me ajudou muito.

thank guy....

You're welcome...

worked good to me too. i used timer 5 pin 46

Hi Karma
I am having the same trouble as you with the tone() not working with IR remote. Your comments look really useful except I don't know how to change an existing library. Could you please share your adapted library, with another pin (other than pin2) activated for the IR timer? Please that would be most useful.

Otherwise any advice on changing an existing library? When I try to open an .h file it does not allow it. So not able to get into the library to select the correct pin.

1 Like

Hi Jamsel, I just solved the problem too.

You need to go on your Arduino folder --> Libraries --> IR folder
then you need to find the IRremoteInt.h file. You can open with wordpad.
Try to find the part that says

"
// Define which timer to use
//
// Uncomment the timer you wish to use on your board.
// If you are using another library which uses timer2, you have options to
// switch IRremote to use a different timer.

..."

You need to find the line that has your Arduino type, mine is the UNO so I used this one:

// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc
#else
//#define IR_USE_TIMER1 //tx = pin 9
#define IR_USE_TIMER2 tx = pin 3

Now you put the "//" in the second line and remove them from the first line. Will look like that:

// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc
#else
#define IR_USE_TIMER1 tx = pin 9
//#define IR_USE_TIMER2 // tx = pin 3

Save the changes and your program should work great.

1 Like

Automotive thank you so much for your help!

Hi,

I'm quite new to Arduino things and tinker occasionally when I have time. Recently I followed a tutorial on using old TV remotes. http://goo.gl/62c1d8 and got as far as getting an LED to dim with the remote.

I thought I would then modify the sketch to include a bleep (using a piezo speaker) each time a button on the remote was pushed using tone(). No luck, got a compiler upload error, found this thread and did the mod to the IRremoteInt.h detailed above by nunesdi01. Uploaded to my Uno OK but then nothing worked including the dimming led.

LED dimming sketch:

#include <IRremote.h>
#define irPin 11
IRrecv irrecv(irPin);
decode_results results;

int ledPin = 9;
int brightness = 10;

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

   pinMode(ledPin, OUTPUT);
}

void loop() {
   if (irrecv.decode(&results)) {

       switch (results.value) {
         case 0x1000405:
            if(brightness < 255) {brightness = brightness+5;}
            analogWrite(ledPin, brightness);
            Serial.println(brightness);
            
            break;

         case 0x1008485:
            if(brightness > 0) {brightness = brightness-5;}
            analogWrite(ledPin, brightness);
            Serial.println(brightness);
            
            break;

         case 0x100BCBD:
            Serial.println("OFF");
            analogWrite(ledPin, 0);
            brightness = 20;
            
            break;
         }
   irrecv.resume();
   }
}

LED dimming sketch with tone() added to one button

#include <IRremote.h>
#define irPin 11
IRrecv irrecv(irPin);
decode_results results;

int ledPin = 9;
int brightness = 10;
int buzzer = 8;



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

   pinMode(ledPin, OUTPUT);
   pinMode(buzzer, OUTPUT);
   
}

void loop() {
   if (irrecv.decode(&results)) {

       switch (results.value) {
         case 0x1000405:
            if(brightness < 255) {brightness = brightness+5;}
            analogWrite(ledPin, brightness);
            Serial.println(brightness);
            tone(buzzer, 1000); // Send 1KHz sound signal...
            delay(1000);        // ...for 1 sec
            noTone(buzzer);  
                    
            break;

         case 0x1008485:
            if(brightness > 0) {brightness = brightness-5;}
            analogWrite(ledPin, brightness);
            Serial.println(brightness);
            
            break;

         case 0x100BCBD:
            Serial.println("OFF");
            analogWrite(ledPin, 0);
            brightness = 20;
            
            break;
         }
   irrecv.resume();
   }
}

I know I've done something wrong...can someone help me please?

Thanks

can somen sent a link for the <IRremoteINT.h> please

In the newer version of the IRremote library, the timer control is moved to the file boarddefs.h, which deals directly with board-specific functions. You will no longer be able to find the timer pin control in the other files if you have the new version.

3 Likes

Thank guy....

Hi, I changed the library as described above, switching to timer 1 rather than 2, but now I am getting a servo error that I wasn't getting before. Previously I was able to control my robot using the irremote.h library as well as the servo.h library. After changing to timer 1, I now am getting what's below. Can anyone help? I read the servo.h library and there is some instructions about the timers, but I don't understand what I should change. My code follows the error. Thank you!

/tmp/992817512/build/libraries/servo_1_1_2/avr/Servo.cpp.o (symbol from plugin): In function `ServoCount':

(.text+0x0): multiple definition of `__vector_11'

/tmp/992817512/build/libraries/IRremote-2.2.3/IRremote.cpp.o (symbol from plugin):(.text+0x0): first defined here

collect2: error: ld returned 1 exit status

exit status 1

// IRremote-2.2.3 - Version: Latest
#include <ir_Lego_PF_BitStreamEncoder.h>
#include <boarddefs.h>
#include <IRremoteInt.h>
#include <IRremote.h>

/*

The IR sensor's pins are attached to Arduino as so:
Pin 1 to Vout (pin 2 on Arduino)
Pin 2 to GND
Pin 3 to Vcc (+5v from Arduino)

*/

#include <Servo.h>

int IRpin = 4; // pin for the IR sensor
int buzzerPin = 7; //pin for buzzer
int LED = 13; // LED pin
int servoLeftpin = 9;
int servoRightpin = 12;
IRrecv irrecv(IRpin);
decode_results results;
Servo servoLeft; // Define left servo
Servo servoRight; // Define right servo

boolean LEDon = true; // initializing LEDon as true

void setup()
{
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
pinMode(LED, OUTPUT);
pinMode(buzzerPin, OUTPUT);
servoLeft.attach(servoLeftpin); // Set left servo to digital pin
servoRight.attach(servoRightpin); // Set right servo to digital pin
}

void loop()
{

if (irrecv.decode(&results))
{

irrecv.resume(); // Receive the next value
}

switch(results.value)
{

case 144:
forward();
reAttach();
break;

case 2192:
reverse();
reAttach();
break;

case 3216:
turnLeft();
reAttach();
break;

case 1168:
turnRight();
reAttach();
break;

case 656:
stopRobot();
break;

case 2064:
slowForward();
reAttach();
break;

case 3088:
slowTurnLeft();
reAttach();
break;

case 2576:
slowTurnRight();
reAttach();
break;

case 3600:
slowReverse();
reAttach();
break;

case 2704:
stopRobot();
break;

// case 16:
// sound();
// break;

default:
digitalWrite(LED, LOW);

}
}
// Motion routines for forward, reverse, turns, and stop
void forward() {
servoLeft.write(0);
servoRight.write(180);
}

void reverse() {
servoLeft.write(180);
servoRight.write(0);
}

void turnRight() {
servoLeft.write(180);
servoRight.write(180);
}

void turnLeft() {
servoLeft.write(0);
servoRight.write(0);
}

void stopRobot() {
servoLeft.detach();
servoRight.detach();
}

void slowForward() {
servoLeft.write(80);
servoRight.write(105);
}

void slowReverse() {
servoLeft.write(105);
servoRight.write(80);
}

void slowTurnRight() {
servoLeft.write(105);
servoRight.write(105);
}

void slowTurnLeft() {
servoLeft.write(80);
servoRight.write(80);
}

void reAttach() {
if(!servoLeft.attached())
servoLeft.attach(servoLeftpin);
if(!servoRight.attached())
servoRight.attach(servoRightpin);
}

//void sound() {
// tone(12,330,500);
// delay(500);
//tone(12,294,500);
//delay(500);
//tone(12,262,500);
//delay(500);
//tone(12,294,500);
//delay(500);
//tone(12,330,500);
//delay(500);
//tone(12,330,500);
//delay(500);
//tone(12,330,1000);
//delay(1500);
//}

You have a problem :wink: There are limited resources on a microcontroller. Get an Arduino that has more timers (if you currently use an Uno/Nano/Mini, 32U4 based or a Mega provide extra timers).

Or use something else instead of the tone library; switching a pin on and off at a certain 'rate' gives you a tone. An extremely simple example

void loop()
{
  digitalWrite(tonePin, LOW);
  delay(10);
  digitalWrite(tonePin, HIGH);
  delay(10);
}

gives a tone of roughly 50 Hz. There are limitations to this (even if you use a millis / micros based approach) so your mileage will vary :wink:

Thank you so much for your reply. Can you explain why this won't work? How can I tell which timers are being used by the servos? It looks like I can only use Timer 1 or 2 for the Tone function on Uno (which I am using). How many timers are there? Any way to specify the servos use other timers? So this means I cannot have a TV-remote controlled robot that has two servo wheels using the Uno and have it play a little tune using Tone? If I use the Mega, will the timers be allocated appropriately or do I need to alter the library? I'd like to know a little more info because I am leading a group of kids on this and want to explain to them. Don't worry, I am not charging these kids for this :wink: . I will try implementing your other method for playing a tune. How do you create different frequencies with it? Do you think I could play a simple tune ok?
Thanks again.

There are three timers on an 328P based board like the Uno. Timer0 is used for millis() and the other two are free.

All 3 timers are also used for PWM; I think that this usually does not pose issues (but I'm sure it can).

I'm quite sure a Mega will not have the problems although you might have to change the library files in similar fashion as you have done now.

And playing a tune using delay / millis() while moving will probably be too much asked; I was more thinking of a beep before the robot starts moving, not while the robot is moving.

DangerouslyExplosive:
In the newer version of the IRremote library, the timer control is moved to the file boarddefs.h, which deals directly with board-specific functions. You will no longer be able to find the timer pin control in the other files if you have the new version.

Worked!! Thanks

I am new to the forum so pardon my typing and english. :slight_smile:

I am making turntable for 360 photography. (on Arduino UNO)

I had working sketch for Canon (triggered with IR led) (ref and code from: GitHub - roboanat/photo-turntable: DIY Automatic photo turntable with Arduino)

I want to work same for Nikon & canon both so I find IR code for Nikon, which gives me problem with tone() code. Which solved by above help (changing timer2 to timer1) and its working fine with Nikon.

But it stop working for canon now.

I want to use same IR LED for both cameras, though both have different codes for it

Please find attached sketch file (which I altered as per my retirement)

Note: other supporting files/libraries are from above github link, i didnt change anything in those files, except "IRremoteInt.h" as per above topic.

Below are 2 IR signal for both cameras from attached file (rest of the sketch are tested OK)

// for canon ------------------------------ this code from original from github

void irStillsShot() {
int khz = 33; // 33kHz frequency
unsigned int irSignal[] = {480};
ir_led.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), khz);
delayMicroseconds(7330);
ir_led.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), khz);
}

// for nikon ---------------------------- this is from some other program for nikon

void shutterClick() {
tone(IRPin,38000);
delay(2);
noTone(IRPin);
delay(28);//original delay 28ms
tone(IRPin,38000);
delayMicroseconds(200);
noTone(IRPin);
delayMicroseconds(1500);
tone(IRPin,38000);
delayMicroseconds(200);
noTone(IRPin);
delayMicroseconds(3300);
tone(IRPin,38000);
delayMicroseconds(200);
noTone(IRPin); // 65ms delay before repeat
}


Note: IR is assign to pin 3.

Now ---- If i compile sketch as it is then it give tone() conflict error, coz tone() is conflict with timer2, may be it is in use.

But --- If I change timer2 to timer1 in "IRremoteInt.h" then nikon works fine but canon code have no LED working.

Now my main question is that in which code I am making mistake... in canon or in nikon. And is it possible to work like this with same LED? If yes then I might put my more time for the same. If not then I might have to use MEGA or make 2 different module for 2 cameras.

Hope I explain it proper and someone might help me with this.

Thanks in advance.

Firmware.ino (11.3 KB)

Was there some resolution identified to this issue ? I yes can you plz share?

JonRon:
Hi,

I'm quite new to Arduino things and tinker occasionally when I have time. Recently I followed a tutorial on using old TV remotes. http://goo.gl/62c1d8 and got as far as getting an LED to dim with the remote.

I thought I would then modify the sketch to include a bleep (using a piezo speaker) each time a button on the remote was pushed using tone(). No luck, got a compiler upload error, found this thread and did the mod to the IRremoteInt.h detailed above by nunesdi01. Uploaded to my Uno OK but then nothing worked including the dimming led.

LED dimming sketch:

#include <IRremote.h>

#define irPin 11
IRrecv irrecv(irPin);
decode_results results;

int ledPin = 9;
int brightness = 10;

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

pinMode(ledPin, OUTPUT);
}

void loop() {
  if (irrecv.decode(&results)) {

switch (results.value) {
        case 0x1000405:
            if(brightness < 255) {brightness = brightness+5;}
            analogWrite(ledPin, brightness);
            Serial.println(brightness);
           
            break;

case 0x1008485:
            if(brightness > 0) {brightness = brightness-5;}
            analogWrite(ledPin, brightness);
            Serial.println(brightness);
           
            break;

case 0x100BCBD:
            Serial.println("OFF");
            analogWrite(ledPin, 0);
            brightness = 20;
           
            break;
        }
  irrecv.resume();
  }
}




LED dimming sketch with tone() added to one button



#include <IRremote.h>
#define irPin 11
IRrecv irrecv(irPin);
decode_results results;

int ledPin = 9;
int brightness = 10;
int buzzer = 8;

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

pinMode(ledPin, OUTPUT);
  pinMode(buzzer, OUTPUT);
 
}

void loop() {
  if (irrecv.decode(&results)) {

switch (results.value) {
        case 0x1000405:
            if(brightness < 255) {brightness = brightness+5;}
            analogWrite(ledPin, brightness);
            Serial.println(brightness);
            tone(buzzer, 1000); // Send 1KHz sound signal...
            delay(1000);        // ...for 1 sec
            noTone(buzzer); 
                   
            break;

case 0x1008485:
            if(brightness > 0) {brightness = brightness-5;}
            analogWrite(ledPin, brightness);
            Serial.println(brightness);
           
            break;

case 0x100BCBD:
            Serial.println("OFF");
            analogWrite(ledPin, 0);
            brightness = 20;
           
            break;
        }
  irrecv.resume();
  }
}




I know I've done something wrong...can someone help me please?

Thanks

JonRon:
Hi,

I'm quite new to Arduino things and tinker occasionally when I have time. Recently I followed a tutorial on using old TV remotes. http://goo.gl/62c1d8 and got as far as getting an LED to dim with the remote.

I thought I would then modify the sketch to include a bleep (using a piezo speaker) each time a button on the remote was pushed using tone(). No luck, got a compiler upload error, found this thread and did the mod to the IRremoteInt.h detailed above by nunesdi01. Uploaded to my Uno OK but then nothing worked including the dimming led.

LED dimming sketch:

#include <IRremote.h>

#define irPin 11
IRrecv irrecv(irPin);
decode_results results;

int ledPin = 9;
int brightness = 10;

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

pinMode(ledPin, OUTPUT);
}

void loop() {
  if (irrecv.decode(&results)) {

switch (results.value) {
        case 0x1000405:
            if(brightness < 255) {brightness = brightness+5;}
            analogWrite(ledPin, brightness);
            Serial.println(brightness);
           
            break;

case 0x1008485:
            if(brightness > 0) {brightness = brightness-5;}
            analogWrite(ledPin, brightness);
            Serial.println(brightness);
           
            break;

case 0x100BCBD:
            Serial.println("OFF");
            analogWrite(ledPin, 0);
            brightness = 20;
           
            break;
        }
  irrecv.resume();
  }
}




LED dimming sketch with tone() added to one button



#include <IRremote.h>
#define irPin 11
IRrecv irrecv(irPin);
decode_results results;

int ledPin = 9;
int brightness = 10;
int buzzer = 8;

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

pinMode(ledPin, OUTPUT);
  pinMode(buzzer, OUTPUT);
 
}

void loop() {
  if (irrecv.decode(&results)) {

switch (results.value) {
        case 0x1000405:
            if(brightness < 255) {brightness = brightness+5;}
            analogWrite(ledPin, brightness);
            Serial.println(brightness);
            tone(buzzer, 1000); // Send 1KHz sound signal...
            delay(1000);        // ...for 1 sec
            noTone(buzzer); 
                   
            break;

case 0x1008485:
            if(brightness > 0) {brightness = brightness-5;}
            analogWrite(ledPin, brightness);
            Serial.println(brightness);
           
            break;

case 0x100BCBD:
            Serial.println("OFF");
            analogWrite(ledPin, 0);
            brightness = 20;
           
            break;
        }
  irrecv.resume();
  }
}




I know I've done something wrong...can someone help me please?

Thanks

JonRon:
Hi,

I'm quite new to Arduino things and tinker occasionally when I have time. Recently I followed a tutorial on using old TV remotes. http://goo.gl/62c1d8 and got as far as getting an LED to dim with the remote.

I thought I would then modify the sketch to include a bleep (using a piezo speaker) each time a button on the remote was pushed using tone(). No luck, got a compiler upload error, found this thread and did the mod to the IRremoteInt.h detailed above by nunesdi01. Uploaded to my Uno OK but then nothing worked including the dimming led.

LED dimming sketch:

#include <IRremote.h>

#define irPin 11
IRrecv irrecv(irPin);
decode_results results;

int ledPin = 9;
int brightness = 10;

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

pinMode(ledPin, OUTPUT);
}

void loop() {
  if (irrecv.decode(&results)) {

switch (results.value) {
        case 0x1000405:
            if(brightness < 255) {brightness = brightness+5;}
            analogWrite(ledPin, brightness);
            Serial.println(brightness);
           
            break;

case 0x1008485:
            if(brightness > 0) {brightness = brightness-5;}
            analogWrite(ledPin, brightness);
            Serial.println(brightness);
           
            break;

case 0x100BCBD:
            Serial.println("OFF");
            analogWrite(ledPin, 0);
            brightness = 20;
           
            break;
        }
  irrecv.resume();
  }
}




LED dimming sketch with tone() added to one button



#include <IRremote.h>
#define irPin 11
IRrecv irrecv(irPin);
decode_results results;

int ledPin = 9;
int brightness = 10;
int buzzer = 8;

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

pinMode(ledPin, OUTPUT);
  pinMode(buzzer, OUTPUT);
 
}

void loop() {
  if (irrecv.decode(&results)) {

switch (results.value) {
        case 0x1000405:
            if(brightness < 255) {brightness = brightness+5;}
            analogWrite(ledPin, brightness);
            Serial.println(brightness);
            tone(buzzer, 1000); // Send 1KHz sound signal...
            delay(1000);        // ...for 1 sec
            noTone(buzzer); 
                   
            break;

case 0x1008485:
            if(brightness > 0) {brightness = brightness-5;}
            analogWrite(ledPin, brightness);
            Serial.println(brightness);
           
            break;

case 0x100BCBD:
            Serial.println("OFF");
            analogWrite(ledPin, 0);
            brightness = 20;
           
            break;
        }
  irrecv.resume();
  }
}




I know I've done something wrong...can someone help me please?

Thanks

mmotiramani:
Was there some resolution identified to this issue ? I yes can you plz share?

Reply #6 ?