Connecting a GPS to ESP32

What should have been a walk in the park is turning into a rabbit hole with no success.

I have two different GPS modules (Neo-6M, Neo-M8N) and I'm trying to connect one of them to an ESP32 WRover.

The problem I have is that no matter what code or Rx,Tx wiring I'm using, I can't get the GPS to send data to the serial monitor.

The LED on the GPS is blinking slowly (once a sec) and I guess that means that the power to the GPS is correct (I used the 3.3V from the ESP32 board and the board in connected to the computer via USB)

I started with the below code, where I tried changing the Rx,Tx pins several times and also the Baud rate.

I started with this code
#define RXD2 16
#define TXD2 17
#define GPS_BAUD 9600

HardwareSerial gpsSerial(2);

void setup(){
  Serial.begin(115200);
  Serial.println("setup started");
  gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RXD2, TXD2);
  Serial.println("Serial 2 started at 9600 baud rate");
}

void loop(){
  while (gpsSerial.available() > 0){
    char gpsData = gpsSerial.read();
    Serial.print(gpsData);
  }
  delay(1000);
  Serial.println("-------------------------------");
}
That's the output I get
ets Jun 8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x33 (SPI_FAST_FLASH_BOOT)

configsip: 0, SPIWP:0xee

clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00

mode:DIO, clock div:1

load:0x3fff0030,len:4832

load:0x40078000,len:16460

load:0x40080400,len:4

load:0x40080404,len:3504

entry 0x400805cc

setup started

Serial 2 started at 9600 baud rate

-------------------------------

-------------------------------

-------------------------------

I also tried using the TinyGPSPlus.h library and its examples, but I can't get passed the part where I need to include <SoftwareSerial.h>, it's probably not part of the ESP32 board libraries and I can't install it manually as well.

that's the code I tried using with the library
#include <TinyGPSPlus.h>
#include <SoftwareSerial.h>
/*
   This sample sketch demonstrates the normal use of a TinyGPSPlus (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 TinyGPSPlus 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 TinyGPSPlus with an attached GPS module"));
  Serial.print(F("Testing TinyGPSPlus 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();
}

Try this code, there are some changes, your original code wont work well at all;

#define RXD2 16
#define TXD2 17
#define GPS_BAUD 9600

HardwareSerial gpsSerial(2);

void setup()
{
  Serial.begin(115200);
  Serial.println("setup started");
  gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RXD2, TXD2);
  Serial.println("Serial 2 started at 9600 baud rate");
}

void loop()
{
  while (gpsSerial.available() > 0)
  {
    char gpsData = gpsSerial.read();
    Serial.print(gpsData);
  }
}

Dont bother with TinyGPSplus library code unto the code above produces a recognizable output on the Serial monitor.

Tried - still not working, here's the output I get (just to make sure I tried also switching the Rx,Tx).

rst:0x1 (POWERON_RESET),boot:0x33 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:4832
load:0x40078000,len:16460
load:0x40080400,len:4
load:0x40080404,len:3504
entry 0x400805cc
setup started
Serial 2 started at 9600 baud rate

using a ESP32 this works with a GPS_GY-NEO6MV2 NEO-6M

// ESP32  Serial1 to GPS_GY-NEO6MV2 NEO-6M module

// GPS VCC to ESP32  3.3V
// GPS GND to ESP32 GND
// GPS RX to ESP32 ESP32 G15
// GPS TX to ESP32 G16

#define RXD1 16
#define TXD1 15

void setup() {
  // initialize both serial ports:
  Serial.begin(115200);
  Serial1.begin(9600, SERIAL_8N1, RXD1, TXD1);
  Serial.println();
  Serial.println("ESP32 serial1 GPS test Rx pin 16 Tx pin 15");
}

void loop() {
  // read from port 1, send to port 0:
  if (Serial1.available()) {
    int inByte = Serial1.read();
    Serial.write(inByte);
  }

  // read from port 0, send to port 1:
  if (Serial.available()) {
    int inByte = Serial.read();
    //Serial.write(inByte);
    Serial1.write(inByte);
  }
}

serial monitor output

ESP32 serial1 GPS test Rx pin 16 Tx pin 15
$GPGGA,153740.649,,,,,0,00,25.5,,,,,,*6B
$GPGLL,,,,,153740.649,V,M*76
$GPGSA,A,1,,,,,,,,,,,,,25.5,25.5,25.5*02
$GPGSV,3,1,10,02,20,152,,06,14,030,,11,30,066,,12,41,084,*75
$GPGSV,3,2,10,22,36,269,,25,72,083,,26,08,274,,29,58,192,*79
$GPGSV,3,3,10,31,47,297,,32,25,232,*70
$GPRMC,153740.649,V,,,,,,,150123,,,M*45
$GPVTG,,,,,,,,,M*33
$GPZDA,153740.649,15,01,2023,00,00*5F
$GPTXT,01,01,01,ANTENNA OPEN*25
$GPGGA,153741.649,,,,,0,00,25.5,,,,,,*6A
$GPGLL,,,,,153741.649,V,M*77
$GPGSA,A,1,,,,,,,,,,,,,25.5,25.5,25.5*02
$GPGSV,3,1,10,02,20,152,,06,14,030,,11,30,066,,12,41,084,*75
$GPGSV,3,2,10,22,36,269,,25,72,083,,26,08,274,,29,58,192,*79
$GPGSV,3,3,10,31,47,297,,32,25,232,*70
$GPRMC,153741.649,V,,,,,,,150123,,,M*44
$GPVTG,,,,,,,,,M*33
$GPZDA,153741.649,15,01,2023,00,00*5E
$GPTXT,01,01,01,ANTENNA OPEN*25
$GPGGA,153742.649,,,,,0,00,25.5,,,,,,*69
$GPGLL,,,,,153742.649,V,M*74
$GPGSA,A,1,,,,,,,,,,,,,25.5,25.5,25.5*02
$GPGSV,3,1,10,02,20,152,,06,14,030,,11,30,066,,12,41,084,26*71
$GPGSV,3,2,10,22,36,269,,25,72,083,,26,08,274,,29,58,192,30*7A

2 Likes

Didn't work for me.
I now tried changing the ESP32 to a different one (just in case), also added some debug printouts to your code

Code
// ESP32  Serial1 to GPS_GY-NEO6MV2 NEO-6M module

// GPS VCC to ESP32  3.3V
// GPS GND to ESP32 GND
// GPS RX to ESP32 ESP32 G15
// GPS TX to ESP32 G16

#define RXD1 16
#define TXD1 17

void setup() {
  // initialize both serial ports:
  Serial.begin(115200);
  Serial.println();
  Serial.println("setup");
  Serial1.begin(9600, SERIAL_8N1, RXD1, TXD1);
  Serial.println("ESP32 serial1 GPS test Rx pin 16 Tx pin 15");
}

void loop() {
  // read from port 1, send to port 0:
  if (Serial1.available()) {
    int inByte = Serial1.read();
    Serial.write(inByte);
    Serial.println("-IF 1-");
    Serial.println(inByte);
  }

  // read from port 0, send to port 1:
  if (Serial.available()) {
    int inByte = Serial.read();
    //Serial.write(inByte);
    Serial1.write(inByte);
    Serial.println("-IF 2-");
  }
  Serial.println("loop");
  delay(2000);
}
Printout
36
loop
G-IF 1-
71
loop
P-IF 1-
80
loop
R-IF 1-
82
loop
M-IF 1-
77
loop
C-IF 1-
67
loop
,-IF 1-
44
loop
,-IF 1-
44
loop
V-IF 1-
86
loop
,-IF 1-
44
loop

the println() could be printing the integer ASCII code
try casting it to char

    Serial.println((char)inByte);

Correct, but I don't know how to get from this to the actual GPS data

71 G
80 P
82 R
77 M
67 C

So a $GPRMC NMEA sentence ..........

Serial.write(inByte);

As per the examples posted.

Or better yet,

Why is inByte an int rather than a char?

I didn't take this line off the code, it's still there.

Also, SOMETIMES it prints out the same as I posted above even if the GPS module is not connected at all

You are connecting GPS Tx to ESP Rx, right?

@srnet's Post #8 indicates things are working.

Correct

I also changed back to the original ESP32 I first experimented with and it prints out just "loop" it doesn't enter the IF at all.

Sorry for this long and pointless thread.

I changed the ESP32 to a different one (3rd I've tried) and now it works well.
I'm getting a full printout with the below code

Code
#define RXD2 16
#define TXD2 15
#define GPS_BAUD 9600

HardwareSerial gpsSerial(2);

void setup()
{
  Serial.begin(115200);
  Serial.println("setup started");
  gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RXD2, TXD2);
  Serial.println("Serial 2 started at 9600 baud rate");
}

void loop()
{
  while (gpsSerial.available() > 0)
  {
    char gpsData = gpsSerial.read();
    Serial.print(gpsData);
  }
  delay(2000);
  Serial.println("loop");
}

Ok, apparently all of my ESP32 work with this code BUT some will only work when Rx is set to a GPIO other than 16, while other ESP32 will accept any GPIO.

Also, only 3 wires are needed to check the communication between the ESP32 and the GPS
GPS VCC --> ESP32 3.3V
GPS Gnd --> ESP32 Gnd
GPS Tx --> ESP32 GPIO16 or GPIO32 (depends on the ESP32 type)

Why?! IDK

Because the GPS only outputs data on a schedule.
The only time that you would send it data would be to enable/disable sentences.

Can you tell us what "this code is" ?

I have no idea at all what "this code is".

My IDK was regarding the fact that different ESP32 boards needed different GPIO (not all worked with GPIO 16)

1 Like

Sure, it's the code I posed on post #15.

#define RXD2 16 //Some ESP32 will not work with GPIIO-16 and willwork with GPIO-32
#define TXD2 15
#define GPS_BAUD 9600

HardwareSerial gpsSerial(2);

void setup()
{
  Serial.begin(115200);
  Serial.println("setup started");
  gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RXD2, TXD2);
  Serial.println("Serial 2 started at 9600 baud rate");
}

void loop()
{
  while (gpsSerial.available() > 0)
  {
    char gpsData = gpsSerial.read();
    Serial.print(gpsData);
  }
  delay(2000);
  Serial.println("loop");
}