Hello Eric,
The GNSS port on the V4 board has its VDD-3V3 supply line controlled by the VGNSS_Ctrl signal tied to GPIO 36. Was the pin explicitly driven LOW in your previous sketch?
If not, the L76K module receives zero power and produces no output. Meshtastic handles this automatically at boot — a plain Arduino sketch does not.
Here is a working sketch with every pin confirmed directly from the hardware documentation :
#include <Arduino.h>// ── GPS UART Pins
#define GPS_RX_PIN 16 // RX_GPS → Board RX ← GPS TX
#define GPS_TX_PIN 21 // TX_GPS → Board TX → GPS RX
#define GPS_BAUD 9600 // L76K factory default baud rate// ── GPS Control Pins
#define GPS_RST_PIN 15 // RST_GPS : HIGH = run, LOW = reset
#define GPS_WAKE_PIN 18 // WAKE_UP : HIGH = active mode
#define GPS_PPS_PIN 17 // PPS : 1Hz pulse (input, optional)// ── Power Control
#define VGNSS_CTRL 36 // LOW = GNSS port powered ON// Use UART1 for GPS (leaves UART0 free for USB debug)
HardwareSerial GPSSerial(1);// ── Setup
void setup() { // 1. Start USB Serial — wait for CDC connection (ESP32-S3)
Serial.begin(115200);
while (!Serial) { delay(10); }
delay(500); Serial.println(“\n============================================”);
Serial.println(" Heltec WiFi LoRa 32 V4 — L76K GPS Test “);
Serial.println(”============================================“);
Serial.println(“Pins: RX=GPIO16 TX=GPIO21 PWR=GPIO36”);
Serial.println(”--------------------------------------------\n"); // 2. Power ON the GNSS port via VGNSS_Ctrl (GPIO 36, LOW = ON)
// This enables the P-channel MOSFET Q7 (AO3401A) which feeds
// VDD_3V3 to Pin 1 of the P3 GNSS connector.
pinMode(VGNSS_CTRL, OUTPUT);
digitalWrite(VGNSS_CTRL, LOW);
Serial.println(“[OK] GNSS power enabled (GPIO36 → LOW)”); // 3. Release GPS reset — RST_GPS is active LOW, so drive HIGH
// to put the L76K into normal run mode.
pinMode(GPS_RST_PIN, OUTPUT);
digitalWrite(GPS_RST_PIN, HIGH);
Serial.println(“[OK] GPS reset released (GPIO15 → HIGH)”); // 4. Assert wake signal — keep the L76K out of standby mode.
pinMode(GPS_WAKE_PIN, OUTPUT);
digitalWrite(GPS_WAKE_PIN, HIGH);
Serial.println(“[OK] GPS wake asserted (GPIO18 → HIGH)”); // 5. Configure PPS as input (optional — useful for timing)
pinMode(GPS_PPS_PIN, INPUT);
Serial.println(“[OK] PPS pin configured (GPIO17 → INPUT)”); // 6. Allow the L76K time to fully power up and stabilise.
// The module needs ~1 s after power-on before it starts
// outputting NMEA sentences.
delay(1000); // 7. Start UART1 on the schematic-verified pins.
GPSSerial.begin(GPS_BAUD, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);
Serial.println(“[OK] GPS UART1 started (9600 baud, 8N1)”);
Serial.println(“\n[..] Waiting for NMEA sentences…”);
Serial.println(“--------------------------------------------”);
}
void loop() { // Forward every byte received from the L76K to the Serial Monitor.
// Even without a satellite fix you should see a continuous stream
// of NMEA sentences (e.g. $GNRMC, $GNGGA, $GPGSV …) immediately.
while (GPSSerial.available()) {
Serial.write(GPSSerial.read());
}
}
What You Should See (Serial Monitor at 115200 baud):
Heltec WiFi LoRa 32 V4 — L76K GPS Test
Pins: RX=GPIO16 TX=GPIO21 PWR=GPIO36
[OK] GNSS power enabled (GPIO36 → LOW)
[OK] GPS reset released (GPIO15 → HIGH)
[OK] GPS wake asserted (GPIO18 → HIGH)
[OK] PPS pin configured (GPIO17 → INPUT)
[OK] GPS UART1 started (9600 baud, 8N1)
[..] Waiting for NMEA sentences…
$GNRMC,V,N*4D
$GNGGA,0,00,99.99,*56
$GPGSV,1,1,00,0*49
A valid position fix (status A in $GNRMC) requires being outdoors with a clear sky view, and may take 5–10 minutes on a cold start.
If boot messages show, still no GPS data, try swapping GPIO 16 ↔ 21 in the sketch.
If there is no output at all, confirm that GPIO 36 is driven LOW.
Please let us know whether the NMEA stream appears after uploading this sketch.
Best regards.