Change SoftwareSerial-Pins on runtime?

Hi to all,

I got stuck with a rather rare problem, but nevertheless a headache for me.

With my Arduinos (UNO/MEGA) I use different GSM-Shields. These shields request also different SoftwarSerial-pins, e.g. one shield works via pins 2 and 3, the other via pins 7 and 8.

As I do not want to recompile the sketch each time I change a GSM-shield (can happen, if the active shield has a failure), I want to figure out, which pins are used for the active shield.

The attached example is used for a shield, which works perfectly with pins 2 and 3. So if I try to make it function with pins 7 and 8, it does not work (this I can see by the missing response to the "AT"-command) and then I want to switch the pins to pins 2 and 3 by assigning another SoftwareSerial- variable (here myserial2 shall be assigned instead of the default myserial.

But obviously this assignment does not work - I cannot modify the pins on runtime (the output of "YYY" is only to debug the entry into the "modification-part".

So my question: How can I change the SoftwareSerial-pins on runtime????

#include <SoftwareSerial.h>
  SoftwareSerial mySerial2(2,3);  //OK
  SoftwareSerial mySerial(7,8);   //NOK
void setup()
{
  pinMode(9, OUTPUT);     // Simulation of "Power On" Button
  digitalWrite(9, HIGH);  // Simulation of "Power On" Button
  delay(3000);            // Simulation of "Power On" Button
  digitalWrite(9, LOW);   // Simulation of "Power On" Button
  delay(2000);            // Simulation of "Power On" Button
  Serial.begin(9600);
  Serial.println("Start Calling");
  mySerial.begin(9600);
  delay(1000);
  mySerial.println("AT"); //Send Request to GSM
  delay (1000);
  if (mySerial.available()<=0) // Did GSM answer?
  {
    Serial.println("YYYYY");
    mySerial=mySerial2;        // No, modify Ports <==========
    mySerial.begin(9600);
    delay(1000);
  }
}

void loop()
{
  if (mySerial.available())
    Serial.write(mySerial.read());
  if (Serial.available())
    mySerial.write(Serial.read());

}

Have a nice day - and hopefully an idea...

piqueremy

SoftwareSerial mySerial2(2,3); //OK
SoftwareSerial mySerial(7,8); //NOK

There is nothing wrong with that second declaration, except the name. You do NOT have a mySerial connected to those pins. Why not use a name that makes sense, based on what IS connected to those pins?

    mySerial=mySerial2;        // No, modify Ports <==========
    mySerial.begin(9600);

That does not make sense. You could just use mySerial2.begin().

  if (mySerial.available()<=0) // Did GSM answer?

The return value from available() can NEVER be less than 0.

Have a nice day - and hopefully an idea...

You could add a method to the SoftwareSerial class to allow changing pins.

Well,

thank you for your fast reply.

Just some comments:

  • as it's a sample sketch, I did not care about the naming.
  • As a long-term programmer (>40 yrs,starting with Assembler, then FORTRAN, BASIC,PASCAL,CHILL..) I got used to exclude the impossible as well.Even if mySerial.available() should not be <0, I got used (out of some bad experiences with long debugging sessions), to include the impossible as well. It does not hurt, except a compiler might think "Oh, what a stupid programmer....
  • If I use "mySerial2.begin()." I have to separate the following, rather large programm according to "mySerial" and "mySerial2". This would mean a rather big effort.

So I followed your last hint and added a method "Change_pins" to the SWS-Library and it works perfectly.

Maybe in an official version of the SoftwareSerial-library it can be implemented as well, even if this problem is a rather rare situation.
At the beginning my new method did not work, and after diving into the SoftwareSerial.cpp I found a method"end" - and this was the clue.

So I created another library "NewSoftwareSerial" (which contains the official "SoftwareSerial and my "Change_pins"-method) and included it into my sketch - and voila!

Thanks for your help and have a nice day:

Piqueremy

#include <NewSoftwareSerial.h>
//  NewSoftwareSerial mySerial(2,3);  //OK
  NewSoftwareSerial mySerial(7,8);   //NOK
void setup()
{
  mySerial.begin(9600);
  delay(1000);
  mySerial.println("AT"); //Send Request to GSM
  delay (1000);
  if (mySerial.available()<=0) // Did GSM answer?
  {
      mySerial.end();        
      mySerial.Change_pins(2,3);        // No, modify Ports <==========
      mySerial.begin(9600);
      delay(1000);
  }
  mySerial.println("AT"); //Send Request to GSM
  delay (1000);
  if (mySerial.available()<=0) // Did GSM answer?
  {
      pinMode(9, OUTPUT);     // Simulation of "Power On" Button
      digitalWrite(9, HIGH);  // Simulation of "Power On" Button
      delay(2000);            // Simulation of "Power On" Button
      digitalWrite(9, LOW);   // Simulation of "Power On" Button
      delay(1000);            // Simulation of "Power On" Button
  }
  mySerial.println("AT"); //Send Request to GSM
  delay (1000);
  Serial.begin(9600);
  if (mySerial.available()<=0) // Did GSM answer?
  {
    mySerial.end();        
    mySerial.Change_pins(7,8);        // No, modify Ports <==========
    mySerial.begin(9600);
    delay(1000);
  }
  Serial.println("Start Calling");
 }

void loop()
{
  if (mySerial.available())
    Serial.write(mySerial.read());
  if (Serial.available())
    mySerial.write(Serial.read());

}

NewSoftwareSerial.h (4.01 KB)

NewSoftwareSerial.cpp (13.4 KB)

keywords.txt (680 Bytes)

1 Like