Go Down

Topic: Using software serial - compile errors and possible conflict? (Read 56 times) previous topic - next topic

DryRun

Hello,

I have been trying to implement software serial into my robot project using Arduino UNO R3 but the compilation keeps giving errors. However, it works fine with hardware serial via the pin 0 and 1. The problem is that i need to be able to send and receive data via HC-05 Bluetooth module and i don't want to use the hardware serial as it requires always unplugging the Bluetooth module every time to upload a new sketch from Arduino IDE.

I've done some research and i found that the cause might be something to do with interrupts and conflicts with the PinChangeInt library and the SoftwareSerial library. However, i am unable to find ways to fix it, as i don't know much about how to manipulate interrupts by editing library files...

From these posts: https://forum.arduino.cc/index.php?topic=323637.0 and https://arduino.stackexchange.com/questions/39523/using-softwareserial-library-with-enableinterrupt i've figured out that maybe i should simply use another software serial library, so i substituted it for AltSoftSerial but the robot does not work except if i have the USB cable plugged in. Then, i tried with another library, NeoSWSerial and it gave similar issues. So, i'm thinking that my only option is to edit the library files to make them compatible with each other... but i have no idea what to change.

It would be really useful if someone could make a version of the SoftwareSerial library that would play nice with other libraries which also use interrupts.

Here is my code:
Code: [Select]
#include <MsTimer2.h>        //internal timer 2
#include <PinChangeInt.h>    //this library can make all pins of arduino UNO as external interrupt
#include <SoftwareSerial.h>

SoftwareSerial mySerial(13, 11); // RX, TX

const int right_R1=8;   
const int right_R2=12;
const int PWM_R=10;
const int left_L1=7;
const int left_L2=6;
const int PWM_L=9;

float pwm1=0,pwm2=0, new_pwm;

//////////////////interrupt speed count/////////////////////////////
#define PinA_left 5  //external interrupt
#define PinA_right 4   //external interrupt
volatile long count_right = 0;
volatile long count_left = 0;

//////////////////////pulse count/////////////////////////
int lz = 0;
int rz = 0;
int rpluse = 0;
int lpluse = 0;
int pulseright,pulseleft;


//Bluetooth//
int front = 0;//backward variable
int back = 0;//forward variable
int left = 0;//turn left
int right = 0;//turn right
char val;

void setup()
{

  pinMode(right_R1,OUTPUT);       
  pinMode(right_R2,OUTPUT);
  pinMode(left_L1,OUTPUT);
  pinMode(left_L2,OUTPUT);
  pinMode(PWM_R,OUTPUT);
  pinMode(PWM_L,OUTPUT);


  digitalWrite(right_R1,1);
  digitalWrite(right_R2,0);
  digitalWrite(left_L1,0);
  digitalWrite(left_L2,1);
  analogWrite(PWM_R,0);
  analogWrite(PWM_L,0);

  pinMode(PinA_left, INPUT); 
  pinMode(PinA_right, INPUT);


  Serial.begin(9600);                       //open the serial monitor, set the baud rate to 9600
 
  mySerial.begin(9600);
  delay(1500);
 

  //5ms; use timer2 to set timer interruption (noteļ¼šusing timer2 will affect the PWM output of pin3 pin11)
  MsTimer2::set(5, interruptFunc);    //5ms;  execute the function once
  MsTimer2::start();    //start interrupt
}

void loop()
{
  if(mySerial.available())
  {
    val = mySerial.read();      //assign the value read from serial port to val
    //mySerial.println(val);
    switch(val)             //switch statement
    {
      case 'F': front= 250; break;     
      case 'B': back= -250; break;       //go back
      case 'L': left=1; break;    //turn left
      case 'R': right=1; break;                         //turn right
      case 'S': front=0,back=0,left=0,right=0;break;    //stop
    }
  }
 
  //external interrupt; used to calculate the wheel speed
  attachPinChangeInterrupt(PinA_left, Code_left, CHANGE);     
  attachPinChangeInterrupt(PinA_right, Code_right, CHANGE); 
}

/////////////////////Hall count/////////////////////////
//left speed encoder count
void Code_left()
{
  count_left ++;
}
//right speed encoder count
void Code_right()
{
  count_right ++;
}

////////////////////pulse count///////////////////////
void countpluse()
{
  lz = count_left; 
  rz = count_right;

  count_left = 0;     
  count_right = 0;

  lpluse = lz;
  rpluse = rz;

  if ((pwm1 < 0) && (pwm2 < 0))                     //judge the car's moving direction; if backward (PWM /motor voltage is negative), pulse is a negative number.
  {
    rpluse = -rpluse;
    lpluse = -lpluse;
  }
  else if ((pwm1 > 0) && (pwm2 > 0))                 //if backward (PWM /motor voltage is positive), pulse is a positive number.
  {
    rpluse = rpluse;
    lpluse = lpluse;
  }
  else if ((pwm1 < 0) && (pwm2 > 0))                 //judge the car's moving direction; if turn left, the right pulse is positive; left pulse is negative.
  {
    rpluse = rpluse;
    lpluse = -lpluse;
  }
  else if ((pwm1 > 0) && (pwm2 < 0))               //judge the car's moving direction; if turn right, the right pulse is negative ; left pulse is positive.
  {
    rpluse = -rpluse;
    lpluse = lpluse;
  }


  pulseright += rpluse;
  pulseleft += lpluse;
}

/////////////////////////////////interrupt////////////////////////////
void interruptFunc()
{
  sei();  //allow overall interrupt
  countpluse();        //pulse plus subfunction
  PWM();
}

////////////////////////////PWM end value/////////////////////////////
void PWM()
{

  pwm2=-new_pwm;           //assign the end value of PWM to motor
  pwm1=-new_pwm;
 

 if(pwm2>=0)         //determine the motor's turning and speed by the negative and positive of PWM
  {
    digitalWrite(left_L1,LOW);
    digitalWrite(left_L2,HIGH);
    analogWrite(PWM_L,pwm2);
  }
  else
  {
    digitalWrite(left_L1,HIGH);
    digitalWrite(left_L2,LOW);
    analogWrite(PWM_L,-pwm2);
  }

  if(pwm1>=0)
  {
    digitalWrite(right_R1,LOW);
    digitalWrite(right_R2,HIGH);
    analogWrite(PWM_R,pwm1);
  }
  else
  {
    digitalWrite(right_R1,HIGH);
    digitalWrite(right_R2,LOW);
    analogWrite(PWM_R,-pwm1);
  }
}


Here is the error copied from the Arduino IDE 1.8.9:
Code: [Select]
Arduino: 1.8.9 (Windows 7), Board: "Arduino/Genuino Uno"

libraries\SoftwareSerial\SoftwareSerial.cpp.o (symbol from plugin): In function `SoftwareSerial::read()':

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

sketch\2SoftwareSerialFixONLY.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here

libraries\SoftwareSerial\SoftwareSerial.cpp.o (symbol from plugin): In function `SoftwareSerial::read()':

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

sketch\2SoftwareSerialFixONLY.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here

libraries\SoftwareSerial\SoftwareSerial.cpp.o (symbol from plugin): In function `SoftwareSerial::read()':

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

sketch\2SoftwareSerialFixONLY.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here

collect2.exe: error: ld returned 1 exit status

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

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Robin2

My guess is that SoftwareSerial wants to use the same pinChange interrupt vector as your PinChangeInterrupt. Maybe moving it to different I/O pins would help.

Or try using one of the other software serial libraries such as NeoSWserial or (my mind has gone blank!)

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Go Up