Hi,
I am trying to write a quadcopter code - stuck on the following error
In function SoftwareSerial::read()':** **(.text+0x0): multiple definition of
__vector_3'
i get this error after including the software serial library
#include<Servo.h>
#include <PID_v1.h> //PID Library by Brett Beauregard ref:https://github.com/br3ttb/Arduino-PID-Library
//Arduino - MPU6050 Library ref : https://github.com/jarzebski/Arduino-MPU6050+
#include <Wire.h>
#include <I2Cdev.h>
#include <helper_3dmath.h>
#include <MPU6050_6Axis_MotionApps20.h>
#include <SoftwareSerial.h> //Software Serial Library for HC-05 Bluetooth Module - this module act as a Slave and sends the data to the master or receive the data from master
//SoftwareSerial BTSerial(A0,A1); // TX, RX
#define DEBUG
//MotorConnections
#define m0 4
#define m1 5
#define m2 6
#define m3 7
// Date : 20Mar - Changing the Motor value from Angle(i.e servo.write) to microSeconds(servo.writeMicroSeconds)
#define motorArmValue 1152 // 60
#define motorMinValue 1200 //65
#define motorMaxValue 1800 //130
#define motorArmDelay 2000 //wait after motors armed
#define throttleMinValue 1200
#define throttleMaxValue 1800
#define pitchPVal 0.5
#define pitchDVal 0
#define pitchIVal 0
#define rollPVal 0
#define rollDVal 0
#define rollIVal 0
#define yawPVal 0
#define yawDVal 0
#define yawIVal 0
//Flight Parameters
#define pitchMin -90
#define pitchMax 90
#define rollMin -90
#define rollMax 90
#define yawMin -180
#define yawMax 180
//#define pidPitchInfluence 20
//#define pidRollInfluence 20
//#define pidYawInfluence 20
//MPU 6050 Offsets
#define mpuGyroXOffset 98
#define mpuGyroYOffset 20
#define mpuGyroZOffset 34
#define mpuAccelXOffset -1034
#define mpuAccelYOffset -571
#define mpuAccelZOffset 884
volatile boolean recvPCInt = false;
Servo motor0;
Servo motor1;
Servo motor2;
Servo motor3;
//-------------------------------------------------------------------
//MPU variables
//Check example in Library for more details
//-------------------------------------------------------------------
MPU6050 mpu; // mpu interface object
uint8_t mpuIntStatus; // mpu statusbyte
uint8_t devStatus; // device status
uint16_t packetSize; // estimated packet size
uint16_t fifoCount; // fifo buffer size
uint8_t fifoBuffer[64]; // fifo buffer
Quaternion q; // quaternion for mpu output
VectorFloat gravity; // gravity vector for ypr
float ypr[3] = {0.0f, 0.0f, 0.0f}; // yaw pitch roll values
volatile bool mpuInterrupt = false; //interrupt flag
double pidPitchIn, pidPitchOut, pidPitchSetPoint = 0; //though in UNO there is no diff between float and double - PID library throwing error if type is float
double pidRollIn, pidRollOut, pidRollSetPoint = 0;
double pidYawIn, pidYawOut, pidYawSetPoint = 0;
PID pitchController(&pidPitchIn, &pidPitchOut, &pidPitchSetPoint, pitchPVal, pitchIVal, pitchDVal, REVERSE); //what is that reverse and forward ?
PID rollController(&pidRollIn, &pidRollOut, &pidRollSetPoint, rollPVal, rollIVal, rollDVal, REVERSE);
PID yawController(&pidYawIn, &pidYawOut, &pidYawSetPoint, yawPVal, yawIVal, yawDVal, DIRECT);
//used to store the pwm duration
volatile unsigned long pwmDuration[4];
volatile unsigned long pwmStart[4];
unsigned long pwmEnd[4];
//pinDeclaration for Rx
const byte rxCh[] = {8, 9, 10, 11};
const byte noOfChannels = sizeof(rxCh);
//portStatus
volatile int prevPortState[] = {0, 0, 0, 0};
volatile int presentPortState[4];
//Interrupt Service Routine will fire when for PinChange in PortB
ISR(PCINT0_vect) {
recvPCInt = true;
for (int ch = 0; ch < noOfChannels ; ch++) {
presentPortState[ch] = digitalRead(rxCh[ch]);
}//end of for looptr
for (int c = 0; c < noOfChannels ; c++) {
if (prevPortState[c] == 0 & presentPortState[c] == 1) {
//if previous state is 0 and present state is 1 (Raising Edge) then take the time stamp
pwmStart[c] = micros();
prevPortState[c] = 1; //update the prevPort State
} else if (prevPortState[c] == 1 & presentPortState[c] == 0) {
//if previous state is 1 and present state is 0 (Falling Edge) then calculate the width based on the change
pwmDuration[c] = micros() - pwmStart[c];
prevPortState[c] = 0; //update Present PortState
}
}//end of for loop
//portValue = PINB & 0x0f;//we are only intrested in first four bits
}
void updateMotors() {
int width = pwmDuration[2];
if (width < 1200 ) {
motor0.write(motorArmValue);
motor1.write(motorArmValue);
motor2.write(motorArmValue);
motor3.write(motorArmValue);
}
else
{
int throttle = map(width, throttleMinValue, throttleMaxValue, motorMinValue, motorMaxValue);
int m0Value = throttle - pidPitchOut; //- pidYawOut;
int m1Value = throttle - pidRollOut; //+ pidYawOut;
int m2Value = throttle + pidPitchOut; //- pidYawOut;
int m3Value = throttle + pidRollOut; //+ pidYawOut;
motor0.write(m0Value);
motor1.write(m1Value);
motor2.write(m2Value);
motor3.write(m3Value);
}//end of ifElse
}//end of update motors
void initializeMotors() {
motor0.attach(m0);
motor1.attach(m1);
motor2.attach(m2);
motor3.attach(m3);
#ifdef DEBUG
Serial.println("motors initialized");
#endif
}//end of initializeMotorsFunction
void armAllMotors() {
motor0.write(motorArmValue);
motor1.write(motorArmValue);
motor2.write(motorArmValue);
motor3.write(motorArmValue);
delay(motorArmDelay);
}//end of armAllMotors function
//ISR for MPU 6050
void dmpDataReady() {
mpuInterrupt = true;
}//end of dmpDataReady
void initMPU() {
Wire.begin();
mpu.initialize();
devStatus = mpu.dmpInitialize();
//MPU Offsets
mpu.setXGyroOffset(mpuGyroXOffset);
mpu.setYGyroOffset(mpuGyroYOffset);
mpu.setZGyroOffset(mpuGyroZOffset);
mpu.setXAccelOffset(mpuAccelXOffset);
mpu.setYAccelOffset(mpuAccelYOffset);
mpu.setZAccelOffset(mpuAccelZOffset);
if (devStatus == 0) {
mpu.setDMPEnabled(true);
attachInterrupt(digitalPinToInterrupt(2), dmpDataReady, RISING);
mpuIntStatus = mpu.getIntStatus();
packetSize = mpu.dmpGetFIFOPacketSize();
}//end of If
}//end of initMPU function
void updateAnglesFromMPU() {
//Check example from MPU6050 Library
mpuInterrupt = false;
mpuIntStatus = mpu.getIntStatus();
fifoCount = mpu.getFIFOCount();
if ((mpuIntStatus & 0x10) || fifoCount >= 1024) {
mpu.resetFIFO();
} else if (mpuIntStatus & 0x02) {
while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
mpu.getFIFOBytes(fifoBuffer, packetSize);
fifoCount -= packetSize;
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
}
}//end of getAnglesFromMPU
void initPID() {
rollController.SetOutputLimits(rollMin, rollMax);
pitchController.SetOutputLimits(pitchMin, pitchMax);
yawController.SetOutputLimits(yawMin, yawMax);
rollController.SetMode(AUTOMATIC);
pitchController.SetMode(AUTOMATIC);
yawController.SetMode(AUTOMATIC);
}//end of initPID
void computePID() {
pidYawIn = ypr[0]*180/M_PI; //Converts Radians to degrees ref - https://forum.arduino.cc/index.php?topic=446713.msg3078076#msg3078076
pidPitchIn = ypr[2]*180/M_PI; //Changed 1 to 2 Due to some problem in Orientation or sensor ? NEED TO FIX IT
pidRollIn = ypr[1]*180/M_PI;
rollController.Compute();
pitchController.Compute();
yawController.Compute();
}//end of computePID
void checkForBTInput(){
}//end of checkForBTInput
void setup() {
cli(); //Clear all interrupts
PCICR |= 1 << PCIE0; //Enable port B Registers i.e D8-D13
PCMSK0 |= 1 << PCINT2;// Pin10
sei(); //enable all interrupts
pinMode(10, INPUT);
digitalWrite(10, HIGH); //enable pull up in pin
//#ifdef DEBUG
Serial.begin(115200);
//#endif
// BTSerial.begin(38400); // HC-05 Default baudrate
initializeMotors();
armAllMotors();
initMPU();
initPID();
}//end of setup
void loop() {
while (!mpuInterrupt && fifoCount < packetSize) {
//Do nothing while mpu is not working
//they are saying it is a short delay .. i need a way to avoid this
// Serial.print("waiting for mpu");
}//end of while loop
updateAnglesFromMPU();
computePID();
updateMotors();
checkForBTInput();
}//end of loop
And I read on the other posts there is conflict on Servo Library and Software Serial Library - Is it rectified ? or shall i look in to alternatives ?