Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.

NEO-6M GPS with NodeMCU ESP8266 — SoftwareSerial wiring and IST code

Wire a NEO-6M GPS to a NodeMCU ESP8266 on D5/D6 with SoftwareSerial and print latitude, longitude, satellites and IST time with TinyGPSPlus.

Arduino C++Verified — core esp8266 3.1.2, TinyGPSPlus 1.0.3, 3 Nov 2026Compile-only

Community draft — report a mistake

A NEO-6M gives a NodeMCU its position and accurate time — the core of vehicle trackers and location loggers that upload over Wi-Fi.

The GPS speaks serial at 9600 baud. The ESP8266’s only full hardware UART is busy with USB, so the module goes on SoftwareSerial: module TX to D5, module RX to D6. The sketch prints coordinates, the satellite count and the time converted to IST.

Wiring

NodeMCU ESP8266Only the pins used are shown · 3.3 V logicNEO-6M GPS module (GY-NEO6MV2)GNDVIND5D6VCCRXTXGND
Every connection
NodeMCU ESP8266NEO-6M GPS module (GY-NEO6MV2)WireNotes
VINVCCredThe GY-GPS6MV2 regulates to 3.3 V on board; 5 V from VIN gives it headroom.
GNDGNDblack
D5TXyellowModule TX → D5 (GPIO14), the SoftwareSerial RX. 3.3 V signal.
D6RXgreenD6 (GPIO12) → module RX. Only needed to send configuration commands.

3.3–5 V (on-board 3.3 V regulator) part, 3.3 V board. The module’s TX is a 3.3 V signal, which every board reads fine. Its RX pin is 3.3 V logic: from a 5 V Arduino TX, add a 1 kΩ / 2 kΩ divider. You only need RX if your sketch sends configuration commands.

Board quirks

  • The NodeMCU’s RX/TX pins are UART0, shared with the USB chip — wiring the GPS there breaks uploads and the Serial Monitor. UART1 is transmit-only (on D4). So the GPS goes on SoftwareSerial, which the ESP8266 core bundles (EspSoftwareSerial); no extra library to install.
  • SoftwareSerial’s RX needs a pin-change interrupt, so D0 (GPIO16) can’t be the RX pin. Keep to D5, D6 or D7, and stay at 9600 baud — with Wi-Fi active, higher software baud rates start dropping bytes.
  • Alternative: Serial.swap() moves the hardware UART0 to D7 (RX) / D8 (TX). It is rock solid but you lose USB serial output, so it suits finished projects, not debugging.
  • GPS time is UTC. The sketch adds 5 h 30 min for IST. The date can roll over at 18:30 UTC — add the same offset to the date if you log it.
  • The module’s TX/RX are 3.3 V logic, so both connect directly to the ESP8266 — no divider, unlike on a 5 V Uno.

Code

gps-nodemcu.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// NEO-6M GPS (GY-GPS6MV2) on a NodeMCU (ESP8266) using SoftwareSerial (EspSoftwareSerial, bundled
// with the ESP8266 core). VCC → VIN (5 V), GND → GND, module TX → D5 (GPIO14), module RX → D6 (GPIO12).
// The hardware UART (RX/TX pins) stays free for USB and the Serial Monitor.
#include <SoftwareSerial.h>
#include <TinyGPSPlus.h>

SoftwareSerial gpsSerial(D5, D6);  // (rx, tx) — RX needs a pin-change interrupt, so never D0
TinyGPSPlus gps;
unsigned long lastPrint = 0;

void setup() {
  Serial.begin(115200);
  Serial.println();
  gpsSerial.begin(9600);  // NEO-6M default; 9600 is also where SoftwareSerial is most reliable
  Serial.println("Waiting for GPS data (first fix outdoors: 30 s to a few minutes)");
}

void loop() {
  while (gpsSerial.available()) gps.encode(gpsSerial.read());
  if (millis() - lastPrint < 2000) return;
  lastPrint = millis();
  if (gps.charsProcessed() < 10) {
    Serial.println("No data from GPS - check module TX goes to D5");
    return;
  }
  if (!gps.location.isValid()) {
    Serial.printf("No fix yet - satellites in view: %d\n", (int)gps.satellites.value());
    return;
  }
  // GPS time is UTC; India is UTC+5:30.
  int mins = gps.time.hour() * 60 + gps.time.minute() + 330;
  Serial.printf("Lat %.6f  Lon %.6f  Sats %d  IST %02d:%02d:%02d\n", gps.location.lat(), gps.location.lng(),
                (int)gps.satellites.value(), (mins / 60) % 24, mins % 60, gps.time.second());
}

Library: TinyGPSPlus (Mikal Hart) — compiled with TinyGPSPlus 1.0.3.

Expected serial output

Serial Monitor · 115200Output
Waiting for GPS data (first fix outdoors: 30 s to a few minutes)
No fix yet - satellites in view: 3
No fix yet - satellites in view: 6
Lat 12.971599  Lon 77.594566  Sats 7  IST 14:32:08

Common errors

“No data from GPS”

TX and RX swapped — the module’s TX must go to D5. Check the module’s LED: it blinks once a second only after a fix, but stays dark without power.

Data arrives but never a fix

Indoors the NEO-6M rarely sees enough satellites. Take it near a window or outside for the first fix. Full fix.

Random resets with Wi-Fi on

A very long loop without yielding. Keep loop() short as shown — reading the GPS a byte at a time is fine. See Soft WDT reset.

↑↓ to move · Enter to open