Go Down

Topic: Compilation Error (Read 2926 times) previous topic - next topic

Boothy920Q

Feb 11, 2017, 08:01 am Last Edit: Feb 11, 2017, 08:09 am by Boothy920Q
Hi
When I run this code
Code: [Select]

#include <NewPing.h>

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



int RunSonarTime = 0;



int IRpin = 9;  // pin for the IR sensor
IRrecv irrecv(IRpin);
decode_results results;

NewPing sonar(12, 13, 200);//sonar pins (trigger pin, echo pin, max distance)


long inches;//set sonar length

//sets a motors
int enableA = 11;
int pinA1 = 5;
int pinA2 = 6;

//sets b motors
int enableB = 10;
int pinB1 = 4;
int pinB2 = 3;





void setup() {
  pinMode(enableA, OUTPUT);
  pinMode(pinA1, OUTPUT);
  pinMode(pinA2, OUTPUT);//set a motor

  pinMode(enableB, OUTPUT);
  pinMode(pinB1, OUTPUT);//sets b motors
  pinMode(pinB2, OUTPUT);

  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver

  inches = sonar.ping_in();
}


//enable motors
void motorAOn()
{
  digitalWrite(enableA, HIGH);
}

void motorBOn()
{
  digitalWrite(enableB, HIGH);
}

//disable motors
void motorAOff()
{
  digitalWrite(enableB, LOW);
}

void motorBOff()
{
  digitalWrite(enableA, LOW);
}

//motor A controls
void motorAForward()
{
  digitalWrite(pinA1, HIGH);
  digitalWrite(pinA2, LOW);
}

void motorABackward()
{
  digitalWrite(pinA1, LOW);
  digitalWrite(pinA2, HIGH);
}

//motor B controls
void motorBForward()
{
  digitalWrite(pinB1, HIGH);
  digitalWrite(pinB2, LOW);
}

void motorBBackward()
{
  digitalWrite(pinB1, LOW);
  digitalWrite(pinB2, HIGH);
}

//coasting and braking
void motorACoast()
{
  digitalWrite(pinA1, LOW);
  digitalWrite(pinA2, LOW);
}

void motorABrake()
{
  digitalWrite(pinA1, HIGH);
  digitalWrite(pinA2, HIGH);
}

void motorBCoast()
{
  digitalWrite(pinB1, LOW);
  digitalWrite(pinB2, LOW);
}

void motorBBrake()
{
  digitalWrite(pinB1, HIGH);
  digitalWrite(pinB2, HIGH);
}
//Define high-level H-bridge commands
void enableMotors()
{
  motorAOn();
  motorBOn();
}

void disableMotors()
{
  motorAOff();
  motorBOff();
}

void forward(int time)
{
  motorAForward();
  motorBForward();
  delay(time);
}

void backward(int time)
{
  motorABackward();
  motorBBackward();
  delay(time);
}

void turnLeft(int time)
{
  motorABackward();
  motorBForward();
  delay(time);
}

void turnRight(int time)
{
  motorAForward();
  motorBBackward();
  delay(time);
}

void coast(int time)
{
  motorACoast();
  motorBCoast();
  delay(time);
}

void brake(int time)
{
  motorABrake();
  motorBBrake();
  delay(time);
}



void loop() {

  //int RunSonarTime = 0;

  analogWrite(enableA, 200);
  analogWrite(enableB, 200);

  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);

    while (RunSonarTime = 1) {
      if (inches < 4) {
        analogWrite(enableA, 255);
        analogWrite(enableB, 255);
        coast(200);
        turnLeft(600);
        coast(200);
      }
      else {
        forward(1);

      }
    }

    if (results.value == 0xA3C8EDDB) { //button + = set var +1
      RunSonarTime = RunSonarTime + 1;
      delay(100);
    }

     if (results.value == 0xF076C13B) { //button - = set var -1
      RunSonarTime = RunSonarTime - 1;
      delay(100);
    }

    if (results.value == 0x3D9AE3F7) { //button 2 = Forward.
      enableMotors();
      forward(1000);
      brake(100);
      delay(100);
    }

    if (results.value == 0x8C22657B) { //Button 4 = Left
      enableMotors();
      turnRight(180);
      brake(100);
      delay(100);
    }

    if (results.value == 0x449E79F) { //Button 6 = Right
      enableMotors();
      turnLeft(180);
      brake(100);
      delay(100);
    }

    if (results.value == 0x1BC0157B) { //Button 8 = Backward
      enableMotors();
      backward(250);
      brake(100);
      delay(100);
    }

    if (results.value == 0x488F3CBB) { //Button 5 = Stop
      enableMotors();
      digitalWrite(pinB1, HIGH);
      digitalWrite(pinB2, HIGH);
      digitalWrite(pinA1, HIGH);
      digitalWrite(pinA2, HIGH);
      delay(100);
    }

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


I get an error message which I don't understand and have gone through many hours trying to fix

Code: [Select]
libraries\IR\IRremote.cpp.o (symbol from plugin): In function `MATCH(int, int)':

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

libraries\NewPing\NewPing.cpp.o (symbol from plugin):(.text+0x0): first defined here

exit status 1
Error compiling for board Arduino/Genuino Uno.


If anyone could help it would be greatly appreciated

UKHeliBob

It looks like the NewPing and IRremote libraries are using the same interrupt.  I don't know what to suggest to fix the problem.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

pert

I'm sure the NewPing library is great but really it's not hard at all to interface with the ultrasonic sensors without using interrupts. There are other libraries you could use but the ones I looked at are not much more than a call to pulseIn(). If you use pulseIn() you will want to set a sane timeout value otherwise the thing will block for a whole second if no ping is received.

sterretje

#3
Feb 11, 2017, 05:09 pm Last Edit: Feb 11, 2017, 05:15 pm by sterretje
It looks like the NewPing and IRremote libraries are using the same interrupt.  I don't know what to suggest to fix the problem.
Analyse the libraries :D

I get an error message which I don't understand and have gone through many hours trying to fix

Code: [Select]
libraries\IR\IRremote.cpp.o (symbol from plugin): In function `MATCH(int, int)':

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

libraries\NewPing\NewPing.cpp.o (symbol from plugin):(.text+0x0): first defined here

exit status 1
Error compiling for board Arduino/Genuino Uno.

As UKHeliBob indicated, you have an interrupt conflict (and it's easy to solve if you know how).

The below is for a 328P based micro (Uno, Nano, ...). First get the datasheet of the processor to find out which interrupt relates to __vector_7.  There is a table in the datasheet
1 0x0000(1) RESET External Pin, Power-on Reset, Brown-out Reset and Watchdog System Reset
2 0x0002 INT0 External Interrupt Request 0
3 0x0004 INT1 External Interrupt Request 1
4 0x0006 PCINT0 Pin Change Interrupt Request 0
5 0x0008 PCINT1 Pin Change Interrupt Request 1
6 0x000A PCINT2 Pin Change Interrupt Request 2
7 0x000C WDT Watchdog Time-out Interrupt
8 0x000E TIMER2 COMPA Timer/Counter2 Compare Match A
9 0x0010 TIMER2 COMPB Timer/Counter2 Compare Match B

The vectors start counting from 0, the table starts at 1 (so you have to subtract 1 from the number in the first column).

Ah, so this is timer related and the problem is with timer 2; more speific TIMER2_COMPA. Now you know that, you can start digging through the two conflicting libraries and find where. I started with the NewPing library but I did not see a quick way to change the timer that is used (compared to the IRremote library that I'm slightly more familiar with) so continued with the IRremote library).

The next thing to do is to look for TIMER2_COMPA (all capital) in all library files of the IRremote library. You will find it in IRremoteInt.h (line 242 in my version of the library).
Code: [Select]

//---------------------------------------------------------
// Timer2 (8 bits)
//
#if defined(IR_USE_TIMER2)

#define TIMER_RESET
#define TIMER_ENABLE_PWM    (TCCR2A |= _BV(COM2B1))
#define TIMER_DISABLE_PWM   (TCCR2A &= ~(_BV(COM2B1)))
#define TIMER_ENABLE_INTR   (TIMSK2 = _BV(OCIE2A))
#define TIMER_DISABLE_INTR  (TIMSK2 = 0)
#define TIMER_INTR_NAME     TIMER2_COMPA_vect

If you dig through IRremote.cpp, you will find that TIMER_INTR_NAME that is used for the ISR so you now know that your on the right track.

Now note the line #if defined(IR_USE_TIMER2). Somewhere IR_USE_TIMER2 must be defined so the next step is to dig through the library files to find it. You will find it the first time in IRremoteInt.h on line 158 (for the version of the library that I use).
Code: [Select]
//------------------------------------------------------------------------------
// 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.
//

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


The complete section that contains this line starts at line 147. Note the comment on the first few lines; this is where you can define which timer to use. Now you must follow that block to find what applies to your microprocessor.

Mega, no; Teensy 1.0, no etc etc. For the 328P processor, you will end at this (line 221)
Code: [Select]
// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc
// ATmega48, ATmega88, ATmega168, ATmega328
#else
//#define IR_USE_TIMER1   // tx = pin 9
#define IR_USE_TIMER2     // tx = pin 3

#endif

Change the two lines after the else to use timer 1 instead of timer 2
Code: [Select]
#define IR_USE_TIMER1   // tx = pin 9
//#define IR_USE_TIMER2     // tx = pin 3

and save the file.

I advise that you add a comment to that section so you know what changed and why.

Next compile your code and the error should be gone.

Notes:
1a)
No guarantee that your code will work after that; I think it will. Please test and provide feedback.
1b)
I'm not sure of the comment    // tx = pin 9. I think it's only used if you use the library for an IR transmitter. I leave it up to you to test.
2)
If you have existing code in other projects that use the IRremote library and you recompile that code, it will also use timer 1; this might conflict with other things in that project.
3)

Sorry for the long post; it might look a little complicated but I considered it important that you understand the procedure that can be followed to solve the problem.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Boothy920Q

Thanks Sterretje for your hep however when i went to find IR_USE_TIMER2 and TIMER2_COMPA I couldn't locate them in my IRremote library.Do you know why?

sterretje

To my knowledge, you should be able to find TIMER2_COMPA as it's very much a standard name; I have no idea why you can't find it. This is the file where I found it: C:\Users\yourusername\Documents\Arduino\libraries\IRremote\IRremoteInt.h (on a windows system).

Where is your IRremote library located? You might be using a different library or or a different version of the same one as I use. That can at least explain why you don't find IR_USE_TIMER2.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Boothy920Q

#6
Feb 12, 2017, 08:37 am Last Edit: Feb 12, 2017, 08:46 am by Boothy920Q
I have mine here C:\Program Files (x86)\Arduino\libraries and it is named IR(The folder it is in)

sterretje

Ok, that's probably another library; I think there is one included with the Arduino install but can't currently check. I seem to remember that I 'removed' it.

Modifying that one might be a lot trickier.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Boothy920Q

Is it possible if you could send the file edited or unedited and I will put that in my library and see if that works?

pert

Ok, that's probably another library; I think there is one included with the Arduino install but can't currently check. I seem to remember that I 'removed' it.
The library included with the Arduino IDE is RobotIRremote. The include file is IRremote.h. So that's probably not the one Boothy920Q is using.

sterretje

The RobotIRremote library is either a stripped down version of or a the base for the library that I gave the description for: Infrared remote library for Arduino: send and receive infrared signals with multiple protocols.

Now the question arises why Boothy920Q has the IR and the NewPing library in the Arduino installation directory and not somewhere in C:\Users\yourusername\Documents\Arduino\libraries\?

Anyway Boothy920Q, if you have the RobotIRremote library installed, only do steps 1 and 6 from the below.

1)
Move your current IR library out if the Arduino installation directory
2)
Download either the above linked library or the RobotIRremote library.
3)
Extract the library files.
4)
Create a directory IRremote in C:\Users\yourusername\Documents\Arduino\libraries\
5)
Copy all extracted files (for the RobotIRremote library, they are in the subdirectory src) to the newly created directory.
6)
Fix the problem as described before. Compile and you should be good to go.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Boothy920Q

Thanks
I have followed those steps but now i am getting this error

Code: [Select]

C:\Program Files (x86)\Arduino\libraries\IRremote\src\IRremoteTools.cpp:5:16: error: 'TKD2' was not declared in this scope

 int RECV_PIN = TKD2; // the pin the IR receiver is connected to

                ^

exit status 1
Error compiling for board Arduino/Genuino Uno.


Do you have any suggestions to fix this?

sterretje

#12
Feb 13, 2017, 10:44 am Last Edit: Feb 13, 2017, 10:47 am by sterretje
Either remove the two 'tools' files (.h and .cpp) or add a #define TKD2 N (where N is a pin number of choice, I don't think it matters much for your case) in the IRremoteTools.cpp file.

This only seems to happen with the RobotIRremote library; I used the first approach and it compiles (indicating that the content of the two files is not used in the final code)
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Boothy920Q

This is what IRremoteTools.cpp looks like:
Code: [Select]
#include "IRremote.h"
#include "IRremoteTools.h"
#include <Arduino.h>
#define TKD2 9
int RECV_PIN = TKD2; // the pin the IR receiver is connected to
IRrecv irrecv(RECV_PIN); // an instance of the IR receiver object
decode_results results; // container for received IR codes

void beginIRremote(){
irrecv.enableIRIn(); // Start the receiver
}

bool IRrecived(){
return irrecv.decode(&results);
}

void resumeIRremote(){
    irrecv.resume(); // resume receiver
}

unsigned long getIRresult(){
return results.value;
}


And I now get this error

Code: [Select]


libraries\IRremote\IRremoteTools.cpp.o (symbol from plugin): In function `RECV_PIN':

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

sketch\Robot-Ir_2.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here

libraries\IRremote\IRremoteTools.cpp.o (symbol from plugin): In function `RECV_PIN':

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

sketch\Robot-Ir_2.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here

libraries\NewPing\NewPing.cpp.o (symbol from plugin): In function `intFunc2':

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

libraries\IRremote\IRremote.cpp.o (symbol from plugin):(.text+0x0): first defined here

exit status 1
Error compiling for board Arduino/Genuino Uno.

pert

Why are you using the stupid RobotIRremote library? Unless you have an Arduino Robot use https://github.com/z3t0/Arduino-IRremote.

Why isn't your RobotIRremote library in a folder named RobotIRremote?

Go Up