GPS Breakout v3 on MKR Zero with Serial2

So I had a GPS Breakout v3 programmed on a Pro Micro and I'll post my code below here:

#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>

SoftwareSerial mySerial(14, 13); // (TX, RX)
Adafruit_GPS GPS(&mySerial);

void setup()
{
  Serial.begin(9600);
  delay(5000);
  Serial.println("Adafruit GPS library basic test!");

  GPS.begin(9600);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
  GPS.sendCommand(PGCMD_ANTENNA);
  delay(1000);
  mySerial.println(PMTK_Q_RELEASE);
}

uint32_t timer = millis();
void loop()
{
  char c = GPS.read();
  if ((c))
  if (GPS.newNMEAreceived()) {
  if (!GPS.parse(GPS.lastNMEA()))
      return;
  }
 
  if (millis() - timer > 2000) {
    timer = millis();

    if (GPS.fix) {
      Serial.print(GPS.latitudeDegrees, 4);
      Serial.print(", ");
      Serial.println(GPS.longitudeDegrees, 4);

    }
  }
}

But I realised that I needed a different board so we decided to switch to an MKR Zero. I see that this board doesn't work the same with the SoftwareSerial.h library though, so I need to find a different way. I found somewhere that you can define 4 pins and make it a Serial2 port or whatever it's called. This is the code I found:

// Serial2 pin and pad definitions (in Arduino files Variant.h & Variant.cpp)
#define PIN_SERIAL2_RX       (34ul)               // Pin description number for PIO_SERCOM on D12
#define PIN_SERIAL2_TX       (36ul)               // Pin description number for PIO_SERCOM on D10
#define PAD_SERIAL2_TX       (UART_TX_PAD_2)      // SERCOM pad 2
#define PAD_SERIAL2_RX       (SERCOM_RX_PAD_3)    // SERCOM pad 3

// Instantiate the Serial2 class
Uart Serial2(&sercom1, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX);

void setup()
{
  Serial2.begin(115200);          // Begin Serial2
}

void loop()
{ 
  if (Serial2.available())        // Check if incoming data is available
  {
    byte byteRead = Serial2.read();    // Read the most recent byte 
    Serial2.write(byteRead);      // Echo the byte back out on the serial port
  }
}

void SERCOM1_Handler()    // Interrupt handler for SERCOM1
{
  Serial2.IrqHandler();
}

Can anyone help me combine these sketches or find a different solution? I tried putting the GPS loop inside of the if(Serial2.available()) statement and I put the adafruit library up top and the setup as usual but it didn't seem to work :frowning:

Has the MKR Zero not got a hardware UART on pins 13 an4 14 referred to as Serial1 which could be used for communication with the GPS ?

I'm not a pro yet, could you tell me how to check that? Where would I find that?

See Serial - Arduino Reference and https://www.arduino.cc/en/Guide/ArduinoMKRZero

Is this the part you are referring to?

Serial ports on the MKRZero

The MKRZero has a number of facilities for communicating with a computer or other microcontrollers. The USB connector exposes as a virtual serial port that can be controlled by writing and reading to the Serial object. Pins 13/14, instead, expose a Hardware serial port mapped to Serial1 object. Opening and closing the USB Serial port at a baud rate other than 1200bps will not reset the 101. To use the serial monitor, and see what your sketch does from the beginning, you'll need to add few lines of code inside the setup(). This will ensure the Curie module will wait for the serial port to open before executing the sketch: while (!Serial) ; Pressing the Reset button on the MKRZero causes the microcontroller to reset as well as resetting the USB communication.

This interruption means that if the serial monitor is open, it's necessary to close and reopen it to restart the communication.

Oh I understand what you mean now. Yes, port 13 and 14 are RX and TX. Could you explain what code to use to make the GPS work on those?
The code I had worked on the hardware RX and TX pins for the Pro Micro, but not for this board.

Serial1.begin(9600);  //open port to communicate with GPS

if (Serial1.available())  //test if GPS data is available
{
  char gpsChar = Serial1.read();  //get a byte
  Serial.println(gpsChar);  //print character to Serial monitor
}
#include <Adafruit_GPS.h>
Adafruit_GPS GPS(&Serial1);

void setup()
{
  Serial1.begin(115200);
  delay(5000);
  Serial.println("Adafruit GPS library basic test!");

  GPS.begin(9600);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
  GPS.sendCommand(PGCMD_ANTENNA);
  delay(1000);
  Serial.println(PMTK_Q_RELEASE);
}

uint32_t timer = millis();
void loop()
{
  if (Serial1.available())  //test if GPS data is available
  {
    char c = GPS.read();
    if ((c))
      if (GPS.newNMEAreceived()) {
        if (!GPS.parse(GPS.lastNMEA()))
          return;
      }

    if (millis() - timer > 2000) {
      timer = millis();

      if (GPS.fix) {
        Serial.print(GPS.latitudeDegrees, 4);
        Serial.print(", ");
        Serial.println(GPS.longitudeDegrees, 4);

      }
    }
  }
  else {
    Serial.println("Serial1 is unavailable"); delay(2000);
  }
}

Is this what you mean? On Serial1?

Looking at your original code for the Pro Micro it looks like all you need to do is to delete the #include of SoftwareSerial and the creation of the mySerial object then to replace references to mySerial in the sketch with Serial1 but I am not familiar with the Adafruit_GPS library

You need, of course, to connect the GPS to pins 13 and 14

Thank you, I think I did that already, but I had RX and TX mixed up so I changed em and it worked!
I have another question though, because I'm trying to use it at the same time as a BME680 and they work individually, but not together. Can you see what's wrong?

#include <Adafruit_GPS.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"

#define BME_CS 12

#define SEALEVELPRESSURE_HPA (1011.41)

#define GPSSerial Serial1
Adafruit_GPS GPS(&GPSSerial);

float servoAltitude = 0;
uint32_t timer = millis();

Adafruit_BME680 bme(BME_CS);

void setup() {
  Serial.begin(9600);
  Serial.println("MKR Zero + BME680 & GPS test");

  GPS.begin(9600);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
  GPS.sendCommand(PGCMD_ANTENNA);
  delay(1000);
  GPSSerial.println(PMTK_Q_RELEASE);

  bme.setTemperatureOversampling(BME680_OS_8X);
  bme.setHumidityOversampling(BME680_OS_2X);
  bme.setPressureOversampling(BME680_OS_4X);
  bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
  bme.setGasHeater(320, 150);
}

void loop() {

// Parsing

  char c = GPS.read();
  if ((c))
    if (GPS.newNMEAreceived()) {
      if (!GPS.parse(GPS.lastNMEA()))
        return;
    }

  if (millis() - timer > 2000) {
    timer = millis();

// GPS

    if (GPS.fix) {
      Serial.print(GPS.latitudeDegrees, 4);
      Serial.print(", ");
      Serial.println(GPS.longitudeDegrees, 4);
    }

// BME680

    Serial.print("Temperature = ");
    Serial.print(bme.temperature);
    Serial.println(" *C");

    Serial.print("Pressure = ");
    Serial.print(bme.pressure / 100.0);
    Serial.println(" hPa");

    Serial.print("Humidity = ");
    Serial.print(bme.humidity);
    Serial.println(" %");

    Serial.print("Gas = ");
    Serial.print(bme.gas_resistance / 1000.0);
    Serial.println(" KOhms");

    Serial.print("Approx. Altitude = ");
    Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
    Serial.println(" m");
    Serial.print("\n");
  }
}

How is the BME680 connected to the Arduino ?

I fixed it already :slight_smile: thanks

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.