Conflict defining interrupt rutines using RH_ASK

Hello !
I am in the proccess of making a project using hardware we designed ourselves.
Primarily we use the standard avr libraries and a couple of header files we made ourselves.
The car should be able to switch from the automatic driving code driveControl(); and an wireless controllable solution.
The problem is the moment we want to utilize the RH_ASK.h library to make the car controllable wirelessly. I get this error statement

WInterrupts.c.o (symbol from plugin)*: In function attachInterrupt

Error linking for board ATmega2560 (Mega 2560) (Arduino Mega)
(.text+0x0)*: multiple definition of __vector_2
Projekt_endelig.cpp.o (symbol from plugin)*: (.text+0x0): first defined here
 
WInterrupts.c.o (symbol from plugin)*: In function attachInterrupt
(.text+0x0)*: multiple definition of __vector_4
Projekt_endelig.cpp.o (symbol from plugin)*: (.text+0x0): first defined here
 
collect2.exe*: error: ld returned 1 exit status

The odd thing is that the RH_ASK driver utilizes the TIMER1_COMPA interrupt, but this infers that it is my external interrupts INT1_vect and INT3_vect that has multiple definitions. Sure enough if I comment out the two external interrupts, the program will compile.
Below is the main program.
I hope anyone has any insight in this problem! :smiley:

Main file:



#define F_CPU 16000000
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>
#include <RH_ASK.h>
#include <SPI.h>
#include "Timer3_driver.h"
#include "driveControl.h"
#include "motor.h"
#include "led.h"


#define ROCKET_SWITCH 22					//Rocket switch PIN

#define TIMER_N 53036						//Timer trappe værdi. 

//*******************************************************************************//
/****************************************************************/
RH_ASK rfDriver;							//Reciever driver objekt
volatile unsigned char reflexCounter = 0;	//Global variable for placement of car
volatile bool state = true;					//Bool state used to control the variable in interrupt routines
/****************************************************************/
void initPortForInt();
/****************************************************************/


//interrupt rutine for the first reflex
//The routine starts the timer and adds 1 to reflexCounter

ISR(INT1_vect)
{
	if (state)
	{
		state = false;
		startTimerInt(TIMER_N);
		reflexCounter++;
	}
}

//interrupt rutine for the second reflex
//The routine starts the timer and adds 1 to reflexCounter
ISR(INT3_vect)
{
	if (state)
	{
		state = false;
		startTimerInt(TIMER_N);
		reflexCounter++;
	}
}

//Timer overflow routine, to ensure two inputs can't enter at the same time
//Stops timer at sets state to true
ISR(TIMER3_OVF_vect)
{
	stopTimerInt();
	state = true;
}


//Setup of all ports and drivers
void setup()
{
	//init reciever
	rfDriver.init();
	//Init portB for leds on shield
	initLEDport();
	//init ports for interrupts
	initPortForInt();
	//init timer for reflex
	initTimer();
	//Init motor control
	initMotorPWMandToggle();
	//Init light control
	
	//Init sound control
	
	//Init global interrupt
	sei();		
	Serial.begin(9600);
	
	//Led sequence that assures car is ready to go
	initOkay();
	//make sure it starts at 0
	reflexCounter = 0;
}


void loop()
{
	while (digitalRead(ROCKET_SWITCH))
	{
		driveControl(reflexCounter);

	}
	while (!digitalRead(ROCKET_SWITCH))
	{
		
		uint8_t buf[7];
		uint8_t buflen = sizeof(buf);

		// Check if received packet is correct size
		if (rfDriver.recv(buf, &buflen))
		{
			unsigned char speed[3] = { buf[0],buf[1],buf[2] };
			unsigned char buttonPressed[3] = { (buf[3] - '0'),(buf[4] - '0'), (buf[5] - '0') };
			int sumOfSpeed = atoi(speed);
			if (sumOfSpeed > 200)
			{
				//forward(sumOfSpeed, 0, 0);
				Serial.print("forward: ");
				Serial.print(sumOfSpeed);
				Serial.print("\n");
			}
			if (sumOfSpeed < 200)
			{
				//backward(sumOfSpeed, 0, 0);
				Serial.print("backward: ");
				Serial.print(sumOfSpeed);
				Serial.print("\n");
			}
			for (int i = 0; i <= 2; i++)
			{
				Serial.print("Button nr. ");
				Serial.print(i);
				Serial.print("\n");
				Serial.print(buttonPressed[i]);
				Serial.print("\n");
			}

			// Message received with valid checksum
			Serial.print("Message Received: ");
			for (int i = 0; i <= 7; i++)
			{
				Serial.print(buf[i] - '0');
				Serial.print(" ");
			}
		}

	}
}




void initPortForInt()
{
	//init PORT D pin til input
	DDRD = 0;

	//Pin 46 (PD3) benyttes til INT 3
	//Pin 45 (PD2) benyttes til INT 2

	DDRE = 0;


	//init PORT A pins til input
	DDRA = 0;
	//Pin 22 (PA0) benyttes til Rocket_switch. Bestemmelse af driveControl eller remoteControl
	//initialise interrupt
	//Enable INT2, INT3 interrupt
	EIMSK |= 0b00001100;
	//Enable rising edge interrupt request for INT 2 and INT 3						
	EICRA |= 0b11110000;
	//Init Timer interrupts og prescaler
}

Which Arduino are you using?

You can force it to use Timer 2 instead by enabling the define RH_ASK_ARDUINO_USE_TIMER2 near the top of RH_ASK.cpp

wouldn't that make your life easier?

I'm using a Mega 2560.
I tried that and it gives me the exact same error :confused:

what's this library? does it make use of the ISR for timer 3?

It manually engages the Timer3 in normal mode and sets up interrupt for it.
I use it to create a delay between the inputs of the INT2 and INT3, so reflexCounter can't increment within a specific time limit.

#include <avr/io.h>
#include <avr/interrupt.h>

void initTimer()
{
	TCCR3A = 0b00000000;					//init timer3 normal mode
	TCCR3B = 0b00000000;
}
void startTimerInt(unsigned int N)
{
	TCNT3 = N;		//trin
	TCCR3B |= 0b00000100;	//prescaler
	TIMSK3 |= 0b00000001;	//set interrupt
}

void stopTimerInt()
{
	TCCR3B &= 0b11111000;	//prescaler 0 (no clock)
	TIMSK3 &= 0b11111110;	//Deactivate interrupt
	TIFR3 |= 0b00000001;	//make sure overflow flag is put down
}

what about.

what does it use ?

According to the AVR datasheet, those two vectors are for two of the external interrupts:
Vector 2 = INT0 (PORTD Bit 0) Pin 21
Vector 4 = INT2 (PORTD Bit 2) Pin 19

The interrupt numbers in the datasheet and __vector__# differ by 1.

__vector_2 = vector 3 in datasheet = INT1
__vector_4 = vector 5 in datasheet = INT3

So: Pin 20 and Pin 18.

Yes these are interrupts i use for other applications. I've tried using INT 2 and 4 and such, and get the same error.
What could cause this? The RH_ASK shouldn't effect these two interrupts

Rather than trying to override the Arduino library by defining external interrupts yourself, just use attachInterrupt().

Change:

	//Enable INT2, INT3 interrupt
	EIMSK |= 0b00001100;
	//Enable rising edge interrupt request for INT 2 and INT 3						
	EICRA |= 0b11110000;

to:

    attachInterrupt(2, INT2Handler, RISING);
    attachInterrupt(3, INT3Handler, RISING);

and

//interrupt rutine for the first reflex
//The routine starts the timer and adds 1 to reflexCounter

ISR(INT1_vect)
{
	if (state)
	{
		state = false;
		startTimerInt(TIMER_N);
		reflexCounter++;
	}
}

//interrupt rutine for the second reflex
//The routine starts the timer and adds 1 to reflexCounter
ISR(INT3_vect)
{
	if (state)
	{
		state = false;
		startTimerInt(TIMER_N);
		reflexCounter++;
	}
}

to

//interrupt rutine for the first reflex
//The routine starts the timer and adds 1 to reflexCounter
void INT1Handler()
{
	if (state)
	{
		state = false;
		startTimerInt(TIMER_N);
		reflexCounter++;
	}
}

//interrupt rutine for the second reflex
//The routine starts the timer and adds 1 to reflexCounter
void INT3Handler()
{
	if (state)
	{
		state = false;
		startTimerInt(TIMER_N);
		reflexCounter++;
	}
}

I will try this out! Thank you

This worked perfectly! Thank you for the help :smiley:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.