Home › Forums › Other Data Loggers › SDI12/Software Serial library conflicts: Arduino-based data logger › Reply To: SDI12/Software Serial library conflicts: Arduino-based data logger
Because you’re using a Mega, by far the easiest way to get around that is to not use SoftwareSerial. The Mega has 4 hardware serial ports. [Serial: 0 (RX) and 1 (TX); Serial 1: 19 (RX) and 18 (TX); Serial 2: 17 (RX) and 16 (TX); Serial 3: 15 (RX) and 14 (TX).] Unless there’s a real necessity to use software to emulate a serial port, you should always, always, always use a hardware serial port. It will be more stable, more accurate in sending and receiving data, has more bit/parity options, and won’t conflict with other libraries. This is true on *all* Arduino boards, no matter what you’re trying to communicate with. Hardware serial is better. I’ve found several instruments that just cannot handle the instability with software port emulation but will work fine on a hardware serial port. (Looking at you S::CAN…)
If you’re already using all of the hardware serial ports on the Mega, or you’re trying to do everything on an Uno, which has only one hardware serial port (already dedicated to USB programming), the second best thing is to use another library called “AltSoftSerial.” That library is based on timer interrupts instead of pin change interrupts so it’s more stable/accurate than SoftwareSerial and will not conflict with SDI-12 or others. Unfortunately, it only works on very specific pins on each board, so you have to make sure those pins are free.
If you still really want to use SoftwareSerial, you have to use versions of both the SoftwareSerial and SDI-12 libraries that have been modified so as not to hog the interrupt vectors. Exactly how you modify them depends on which pin you want to use for SDI-12 and for SoftwareSerial. If you’re set on pins 62/A8 and 63/A9 for software serial on the Mega, those are both on port K/PCINT2_vect. So you probably want to tell the SoftwareSerial library that it’s only allowed to control that one vector. Do do this, open the file SoftwareSerial.cpp and find and modify the section defining interrupts like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// Lines in this block are commented out // because PCINT0, PCINT1, and PCINT3 // are not used by SoftwareSerial for this // project. //#if defined(PCINT0_vect) //ISR(PCINT0_vect) //{ // SoftwareSerial::handle_interrupt(); //} //#endif //#if defined(PCINT1_vect) //ISR(PCINT1_vect) //{ // SoftwareSerial::handle_interrupt(); //} //#endif #if defined(PCINT2_vect) ISR(PCINT2_vect) { SoftwareSerial::handle_interrupt(); } #endif //#if defined(PCINT3_vect) //ISR(PCINT3_vect) //{ // SoftwareSerial::handle_interrupt(); //} //#endif |
Then you have to figure out which interrupt whatever pin you want to use for SDI-12 is on, and then find the same section of code in SDI-12.cpp and comment out all the interrupt vectors except whichever one controls the pin that you’re using for SDI-12. If you’re already claiming PCINT2_vect for SoftwareSerial, you will not be able to use pins A8-A15 for SDI-12 because those pins are all on PCINT2_vect. If you make those modifications, you should be able compile the libraries together.
Just another note:
The errors saying “Multiple libraries were found for “SD.h”” and “Multiple libraries were found for “Adafruit_Sensor.h”” have nothing to do with SoftwareSerial or SDI-12. Go thorough your library folder and delete those duplicate libraries or you might get some unexpected errors or oddly behaving code. If you’re shopping for an SD card library, I prefer SDFat.