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());
}
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.
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());
}