huanghyw 发表于 2014-7-5 17:01:51

如何解决Tone.cpp与IRremote.cpp冲突问题


在震动报警器示例代码中做了一下扩展,增加一个RGB LED,使报警的时候有红绿蓝三色进行闪烁。震动停止10秒钟之后,报警停止。
上面这些功能都实现了,除了使用倾斜检查来实现震动检测准确率不是特别高,其他的基本上正常。
最后想加入红外遥控器进行控制,但是导入IRremote.h后编译器检查代码时报错,看错误信息是有冲突,于是找到发生冲突的文件,看到冲突确实存在。
发生冲突的两个文件分别是“Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Tone.cpp”和“Arduino.app/Contents/Resources/Java/libraries/IRremote/IRremote.cpp”。
完整的报错信息如下:
core.a(Tone.cpp.o): In function `__vector_7':
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Tone.cpp:535: multiple definition of `__vector_7'
IRremote/IRremote.cpp.o:/Applications/Arduino.app/Contents/Resources/Java/libraries/IRremote/IRremote.cpp:311: first defined here

完整的代码如下:
#include <IRremote.h>

const float radianValue = 3.14 / 180;//conver angle to radian

const int rLedPin = 8;
const int gLedPin = 9;
const int bLedPin = 10;

const int alarmPin = 7;
boolean isAlarmWork = false;

const int detectionVabrationPin = 3;
int detectionVabrationCount = 0;

unsigned long detectionVabrationTime = 0;
unsigned const long alarmTimeOut = 1000 * 10;

const int infraredPin = 12;
IRrecv irrecv(infraredPin);
decode_results results;


void setup(){
pinMode(rLedPin, OUTPUT);
pinMode(gLedPin, OUTPUT);
pinMode(bLedPin, OUTPUT);

pinMode(alarmPin, OUTPUT);

pinMode(detectionVabrationPin, INPUT);
attachInterrupt(0, detectionVabration, RISING);

Serial.begin(9600);
}

void loop(){
alarmDoWork();
if(isAlarmWork){
    if(millis() - detectionVabrationTime > alarmTimeOut){
      isAlarmWork = false;
      Serial.println("end");
    }
    Serial.println(detectionVabrationCount);
}
}

void detectionVabration(){
isAlarmWork = true;
detectionVabrationCount ++;
detectionVabrationTime = millis();
}

void alarmDoWork(){
int ledIndex = 1;
for(int i=0; i<180; i++){
    if(!isAlarmWork){
      noTone(alarmPin);
      resetAllLed();
      break;
    }
    tone(alarmPin, int(2000 * sin(i * radianValue)));
    if(i % 10 == 0){
      if(ledIndex == 1){
      onlyShowRLed();
      ledIndex = 2;
      }
      else if(ledIndex == 2){
      onlyShowGLed();
      ledIndex = 3;
      }
      else if(ledIndex == 3){
      onlyShowBLed();
      ledIndex = 1;
      }
    }
    delay(10);
}
}

void onlyShowRLed(){
digitalWrite(rLedPin, HIGH);
digitalWrite(gLedPin, LOW);
digitalWrite(bLedPin, LOW);
}

void onlyShowGLed(){
digitalWrite(rLedPin, LOW);
digitalWrite(gLedPin, HIGH);
digitalWrite(bLedPin, LOW);
}

void onlyShowBLed(){
digitalWrite(rLedPin, LOW);
digitalWrite(gLedPin, LOW);
digitalWrite(bLedPin, HIGH);
}

void resetAllLed(){
digitalWrite(rLedPin, LOW);
digitalWrite(gLedPin, LOW);
digitalWrite(bLedPin, LOW);
}
这种问题大家开发过程中遇到过没,有什么好的解决方法吗?

wangyi2926 发表于 2014-7-9 12:54:21

我有一次用红外遥控接D3的LED,也遇到过类似的事情。经求助得知,红外的库文件里计时器占用了D3和D11针脚,你试着改一下LED的接线,或许有用。

Youyou 发表于 2014-7-10 14:48:23

你好,类似于楼上说的,两个库用的是同一个定时器,造成定时器冲突,两个库里面都写了同一个定时器的中断程序,这样就出现了同一个定时器却有两个中断程序,导致编译器不能正常编译。可以修改IR的库,换个定时器使用,在IRremoteint_h里面,找到这些语句:
// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc
#else
#define IR_USE_TIMER1   // tx = pin 9
//#define IR_USE_TIMER2   // tx = pin 3
#endif
这里我已经修改了,注释掉了#define IR_USE_TIMER2 ,使用了#define IR_USE_TIMER1,因此不会出现定时器冲突了。
重启IDE后即可正常编译。

33532997052017 发表于 2018-3-3 20:50:49

可以正常编译,但是我使用完tone之后,红外遥控就不控制了怎么办?不再接受码值了。。。

無数 发表于 2020-10-9 18:24:41

我把我的实验经过写在博客里了。
https://blog.csdn.net/GreatSimulation/article/details/108982522
页: [1]
查看完整版本: 如何解决Tone.cpp与IRremote.cpp冲突问题