How to eliminate softwareserial from a sketch

How would I make this work with the gps on regular hardware serial, say Serial3 (pins 15,14) on a mega 2560?

Or is there any reason it shouldn't work on a mega assigning sofwareserial to whatever digital pins I want, including those used for Serial3 for instance? For some reason it doesn't work for me. The adafruit gps example that uses hardware serial works just fine. Tinygps, I am stumped by.

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
/*
   This sample sketch demonstrates the normal use of a TinyGPS++ (TinyGPSPlus) object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/
static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 4800;

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);

void setup()
{
  Serial.begin(115200);
  ss.begin(GPSBaud);

  Serial.println(F("DeviceExample.ino"));
  Serial.println(F("A simple demonstration of TinyGPS++ with an attached GPS module"));
  Serial.print(F("Testing TinyGPS++ library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
  Serial.println(F("by Mikal Hart"));
  Serial.println();
}

void loop()
{
  // This sketch displays information every time a new sentence is correctly encoded.
  while (ss.available() > 0)
    if (gps.encode(ss.read()))
      displayInfo();

  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
    Serial.println(F("No GPS detected: check wiring."));
    while(true);
  }
}

void displayInfo()
{
  Serial.print(F("Location: ")); 
  if (gps.location.isValid())
  {
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(","));
    Serial.print(gps.location.lng(), 6);
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F("  Date/Time: "));
  if (gps.date.isValid())
  {
    Serial.print(gps.date.month());
    Serial.print(F("/"));
    Serial.print(gps.date.day());
    Serial.print(F("/"));
    Serial.print(gps.date.year());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F(" "));
  if (gps.time.isValid())
  {
    if (gps.time.hour() < 10) Serial.print(F("0"));
    Serial.print(gps.time.hour());
    Serial.print(F(":"));
    if (gps.time.minute() < 10) Serial.print(F("0"));
    Serial.print(gps.time.minute());
    Serial.print(F(":"));
    if (gps.time.second() < 10) Serial.print(F("0"));
    Serial.print(gps.time.second());
    Serial.print(F("."));
    if (gps.time.centisecond() < 10) Serial.print(F("0"));
    Serial.print(gps.time.centisecond());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.println();
}

It's actually not as hard as you are making it. The GPS library simply decodes strings that you feed it character by character. Normally the strings are fetched by reading from a GPS device via a serial port. In the example you posted it uses software serial by defining a serial object providing the pin numbers to use. To use the hardware Serial3 on your Mega, you should remove:

  • the inclusion of SoftwareSerial.h
  • the constants RXPin and TXPin
  • the software serial initialization SoftwareSerial ss(RXPin, TXPin);
    Then change:
  • the line ss.begin(GPSBaud); to Serial3.begin(GPSBaud);
  • all softwareserial activity by changing "ss." to "Serial3.".

One would use a similar idea if one was reading from an i2c or SPI connected GPS device, but serial connected GPS devices are much more common.

This small sketch uses Serial1, but does not use the TinyGPS library.
Wire your GPS to pins 18 and 19

Pin 18 (Tx) to GPS (Rx)
Pin 19 (Rx) to GPS (Tx).

compile, upload, fire up the Serial Monitor and set it to 115200 baud.
If you see a bunch of garble, send the digits 0 through 4, one at a time, with No Line Ending. When you start seeing GPS sentences, you'll know you have the right baud rate.

unsigned long baud[] = {4800, 9600, 19200, 57600, 115200};
byte indx = 0;

void setup() {
  Serial.begin(115200);
  Serial1.begin(baud[0]);
  inform();
}

void loop() {
    if (Serial.available()) {
      char ch = Serial.read();
      Serial.print("\n***********************************  ");
      Serial.println (ch);
      if (ch >= '0' && ch <= '4') {
        indx = ch - '0';
        Serial1.end();
        delay(500);
        inform();
        Serial1.begin(baud[indx]);
      }
    }

    if (Serial1.available()) {
      char inbyte = Serial1.read();
      Serial.print(inbyte);
    }
}

void inform() {
  Serial.print("\nGPS serial is set to ");
  Serial.print(baud[indx]);
  Serial.println(" baud");
}

Thanks. Got both examples working with Serial3.

Is there any restriction against using Softwareserial on a Mega and assigning it the pins that are used for Serial3? For some reason I haven't been successful in making it work that way.

Software serial does not work on all pins - which pins it works on depends on the type of chip used.

Mark

Is there any restriction against using Softwareserial on a Mega and assigning it the pins that are used for Serial3?

Yes. You should never be doing SoftwareSerial on hardware serial pins. Even if it works under limited conditions, it makes you look stupid.

Good to know. Thanks again.