2

I'm working on a project that involves both serial communication and GSM transmission. I'm using the SoftwareSerial library for RS232 communication, and GSM (SMS) transmission:

  • TX and RX for RS232 : Arduino Uno D3 and D4 pins
  • TX and RX for GSM module : Arduino Uno D7 and D8 pins

The project requires also the use of the EnableInterrupt library to enable interrupt in Arduino's analog pins, meaning that I DON'T USE EnableInterrupt for all of the Arduino's digital pins including D3, D4, D7 and D8.

However when running the program that includes the two libraries, this long error message shows up :

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

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

sketch\sketch_jun14a.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\sketch_jun14a.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\sketch_jun14a.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here

collect2.exe: error: ld returned 1 exit status

exit status 1
Erreur de compilation pour la carte Arduino/Genuino Uno

Clearly, there is a conflict between the two libraries, Is there any solution to remove this conflict and run the two libraries together ?

Thanks in advance !

  • With SoftwareSerial, you can use only one RX at a time. Could you replace the Arduino Uno with a Arduino Mega 2560 ? That one has 3 spare hardware serial ports. – Jot Jun 14 '17 at 13:18
1
  • SoftwareSerial uses all PinChange interrupts.
  • EnableInterrupts uses all PinChange interrupts.

You can see the conflict.

All you can do is to modify both libraries to remove support for the interrupts you don't need it to support - that way you share out the responsibility for handling the different interrupts between the two libraries.

0

I would suggest using different software serial libraries and pins. To apply this answer, I would suggest this configuration:

  • Connect your RS232 device to pins 0 & 1 and use Serial
  • Connect your GSM device to pins 8 & 9 and use AltSoftSerial (it must use those pins).

If you do not send anything to the RS232 device, you can still use Serial for debug statements. Don't even connect the TX pin to the RS232 device. You will have to disconnect the RX pin to upload new sketches over USB. Or, if the RS232 device receives formatted commands, it would ignore debug statments that don't look like commands. This has the added benefit that the Serial Monitor window will display the commands you do send to the RS232 device.

If you really need to use 3 serial ports, you will have to use this configuration:

  • Use Serial for whatever
  • Connect the RS232 or GSM device to pins 8 & 9 and use AltSoftSerial
  • Connect the other device to any two pins and use my NeoSWSerial.

AltSoftSerial is more efficient at transmitting than NeoSWSerial, so use AltSoftSerial for the device to which you send the most data. NeoSWSerial is limited to baud rates 9600, 19200 and 38400, so that may be a consideration.

SoftwareSerial is a terrible choice, because it disables interrupts for long periods of time, it can only listen to one port at a time, and it cannot transmit and receive at the same time.

AltSoftSerial and NeoSWSerial do not have these limitations, and they can co-exist to give you 2 extra serial ports. You should also be aware the NeoSWSerial disables interrupts while transmitting (not receiving). AltSoftSerial uses one of the TIMER resources, while NeoSWSerial simply uses the millis() timer.

ADDENDUM

To answer your original question about using the EnableInterrupt library at the same time as a software serial library:

If you are using the first configuration above, AltSoftSerial will not conflict with EnableInterrupt.

If you are using the second configuration, NeoSWSerial will conflict with EnableInterrupt. For this possibility, NeoSWSerial has an option to disable using all the Pin Change Interrupt ISRs. Uncomment this line and call the NeoSWSerial::rxISR from the appropriate enableInterrupt() callback function:

#include <NeoSWSerial.h>
NeoSWSerial oneDevice( RX_PIN, TX_PIN );

void myISR()
{
  NeoSWSerial::rxISR( *portInputRegister( digitalPinToPort( RX_PIN ) ) );
}

void setup()
{
  enableInterrupt( RX_PIN, myISR, CHANGE );
}

This puts EnableInterrupt in charge of the ISRs. If you want to try NeoSWSerial, it is available from the Arduino IDE Library Manager, under the menu Sketch -> Include Library -> Manage Libraries.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.