From 5c274ebd8c9660198e2a9a792278ed7e78a10940 Mon Sep 17 00:00:00 2001 From: Bob Date: Sat, 6 Dec 2025 10:25:11 -0800 Subject: [PATCH] gps pps docs --- doc/esp32-c5-gps-sync-guide.html | 924 +++++++++++++++++++++++++++++++ doc/esp32-c5-pinout-simple.html | 583 +++++++++++++++++++ 2 files changed, 1507 insertions(+) create mode 100644 doc/esp32-c5-gps-sync-guide.html create mode 100644 doc/esp32-c5-pinout-simple.html diff --git a/doc/esp32-c5-gps-sync-guide.html b/doc/esp32-c5-gps-sync-guide.html new file mode 100644 index 0000000..7684e5e --- /dev/null +++ b/doc/esp32-c5-gps-sync-guide.html @@ -0,0 +1,924 @@ + + + + + + ESP32-C5 GPS Synchronization Guide + + + +
+

ESP32-C5 GPS Synchronization Guide

+
Precision Timing for WiFi Collapse Detection with iperf2 Correlation
+
+ +
+

Overview

+

This guide demonstrates how to synchronize an ESP32-C5-DevKitC-1-N8R4 to GPS time using a GPS module with PPS (Pulse Per Second) output. This enables precise timestamp correlation between WiFi collapse detector events and iperf2 latency measurements running on a GPS-synced Raspberry Pi 5.

+ +
+ Key Features: +
    +
  • Monotonic clock for interval measurements (never jumps backward)
  • +
  • GPS UTC timestamp for correlation with iperf2 data
  • +
  • Microsecond-precision PPS synchronization
  • +
  • Suitable for 32+ device deployments
  • +
+
+
+ +
+

Required Hardware

+ + +
+ Note on USB Ports:
+ The ESP32-C5 has TWO USB-C ports: +
    +
  • UART USB (Right): USB-to-UART bridge - recommended for programming and serial monitor
  • +
  • ESP32 USB (Left): Native USB on chip (GPIO13/14) - supports USB 2.0 and JTAG debugging
  • +
+ For development, use the UART USB port (right side) as it's more reliable for flashing and monitoring. +
+ +
+ ✓ GT-U7 & ESP32-C5 Compatibility:
+ The MakerFocus GT-U7 operates at 3.6V-5V and is fully compatible with the ESP32-C5's 3.3V power output. You can safely connect GT-U7's VCC directly to the ESP32's 3V3 pin (J1 Pin 1). The GT-U7's logic levels are also 3.3V/5V tolerant, making it a perfect match. +
+
+ +
+

Pin Connections

+ +

ESP32-C5 Pinout

+ + +

Wiring Diagram

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
GT-U7 GPS PinESP32-C5 PinHeader LocationGPIO Number
VCCPin 1J1 (Left Side)3V3 (3.3V works perfect!)
GNDPin 15J1 (Left Side)GND
TXD (NMEA Data)Pin 8J3 (Right Side)GPIO4 (RX)
PPS (Pulse/Second)Pin 6J1 (Left Side)GPIO1
RXD (Optional)Pin 9J3 (Right Side)GPIO5 (TX)
+ +

Visual Connection Guide

+
+
+GT-U7 GPS Module         ESP32-C5-DevKitC-1 Board
+----------------         ═══════════════════════════════════════
+
+                         ┌─── J1 (LEFT) ──┐      ┌── J3 (RIGHT) ──┐
+VCC (3.3V-5V) ────────→  │ Pin 1:  3V3    │      │                │
+                         │ Pin 2:  RST    │      │                │
+                         │ Pin 3:  GPIO2  │      │                │
+                         │ Pin 4:  GPIO3  │      │                │
+                         │ Pin 5:  GPIO0  │      │                │
+PPS (pulse)   ────────→  │ Pin 6:  GPIO1  │      │                │
+                         │ Pin 7:  GPIO6  │      │                │
+                         │ Pin 8:  GPIO7  │      │                │
+                         │ Pin 9:  GPIO8  │      │                │
+                         │ Pin 10: GPIO9  │      │                │
+                         │ Pin 11: GPIO10 │      │                │
+                         │ Pin 12: GPIO26 │      │                │
+                         │ Pin 13: GPIO25 │      │                │
+                         │ Pin 14: 5V     │      │                │
+GND           ────────→  │ Pin 15: GND    │      │                │
+                         │ Pin 16: NC     │      │                │
+                         └────────────────┘      │                │
+                                                 │ Pin 1:  GND    │
+                                                 │ Pin 2:  TX     │
+                                                 │ Pin 3:  RX     │
+                                                 │ Pin 4:  GPIO24 │
+                                                 │ Pin 5:  GPIO23 │
+                                                 │ Pin 6:  NC     │
+                                                 │ Pin 7:  GPIO27 │
+TXD (data out) ──────────────────────────→  │ Pin 8:  GPIO4  │
+RXD (optional) ←────────────────────────────│ Pin 9:  GPIO5  │
+                                                 │ Pin 10: NC     │
+                                                 │ Pin 11: GPIO28 │
+                                                 │ Pin 12: GND    │
+                                                 │ Pin 13: GPIO14 │
+                                                 │ Pin 14: GPIO13 │
+                                                 │ Pin 15: GND    │
+                                                 │ Pin 16: NC     │
+                                                 └────────────────┘
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+GT-U7 IPEX ANTENNA:
+• Connect active antenna to GT-U7's IPEX connector
+• Place antenna with clear view of sky for best reception
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+REQUIRED CONNECTIONS (4 wires):
+  1. GT-U7 VCC  →  J1 Pin 1  (3V3)
+  2. GT-U7 GND  →  J1 Pin 15 (GND)
+  3. GT-U7 TXD  →  J3 Pin 8  (GPIO4)
+  4. GT-U7 PPS  →  J1 Pin 6  (GPIO1)
+
+
+ +
+ ⚠️ Important Notes: +
    +
  • Use 3.3V power only - do NOT connect to 5V
  • +
  • GPIO2, GPIO3, GPIO7, GPIO25-28 are strapping pins - avoid for general use
  • +
  • N8R4 variant has 4MB PSRAM using internal pins - GPIO4/5 are safe
  • +
+
+
+ +
+

Software Implementation

+ +

Project Structure

+
+your_project/
+├── CMakeLists.txt
+└── main/
+    ├── CMakeLists.txt
+    ├── main.c
+    ├── gps_sync.h
+    └── gps_sync.c
+        
+ +

gps_sync.h - Header File

+
#pragma once
+
+#include <stdint.h>
+#include <time.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/semphr.h"
+
+typedef struct {
+    int64_t monotonic_us;   // Never jumps backward
+    int64_t gps_us;         // GPS UTC time in microseconds
+    bool synced;            // true if GPS has valid fix
+} gps_timestamp_t;
+
+// Initialize GPS sync system
+void gps_sync_init(void);
+
+// Get current timestamp
+gps_timestamp_t gps_get_timestamp(void);
+
+// Check if GPS is synced
+bool gps_is_synced(void);
+ +

gps_sync.c - Implementation

+
#include "gps_sync.h"
+#include "driver/gpio.h"
+#include "driver/uart.h"
+#include "esp_timer.h"
+#include "esp_log.h"
+#include <string.h>
+#include <time.h>
+
+#define GPS_UART_NUM     UART_NUM_1
+#define GPS_RX_PIN       GPIO_NUM_4
+#define GPS_TX_PIN       GPIO_NUM_5
+#define PPS_GPIO         GPIO_NUM_1
+#define GPS_BAUD_RATE    9600
+#define UART_BUF_SIZE    1024
+
+static const char *TAG = "GPS_SYNC";
+
+// GPS sync state
+static int64_t monotonic_offset_us = 0;
+static volatile int64_t last_pps_monotonic = 0;
+static volatile time_t next_pps_gps_second = 0;
+static bool gps_has_fix = false;
+static SemaphoreHandle_t sync_mutex;
+
+// PPS interrupt - captures exact monotonic time at second boundary
+static void IRAM_ATTR pps_isr_handler(void* arg) {
+    last_pps_monotonic = esp_timer_get_time();
+}
+
+// Parse GPS time from NMEA sentence
+static bool parse_gprmc(const char* nmea, struct tm* tm_out, bool* valid) {
+    if (strncmp(nmea, "$GPRMC", 6) != 0 && strncmp(nmea, "$GNRMC", 6) != 0) {
+        return false;
+    }
+    
+    char *p = strchr(nmea, ',');
+    if (!p) return false;
+    
+    // Time field
+    p++;
+    int hour, min, sec;
+    if (sscanf(p, "%2d%2d%2d", &hour, &min, &sec) != 3) {
+        return false;
+    }
+    
+    // Status field (A=valid, V=invalid)
+    p = strchr(p, ',');
+    if (!p) return false;
+    p++;
+    *valid = (*p == 'A');
+    
+    // Skip to date field (8 commas ahead from time)
+    for (int i = 0; i < 7; i++) {
+        p = strchr(p, ',');
+        if (!p) return false;
+        p++;
+    }
+    
+    // Date field: ddmmyy
+    int day, month, year;
+    if (sscanf(p, "%2d%2d%2d", &day, &month, &year) != 3) {
+        return false;
+    }
+    
+    year += (year < 80) ? 2000 : 1900;
+    
+    tm_out->tm_sec = sec;
+    tm_out->tm_min = min;
+    tm_out->tm_hour = hour;
+    tm_out->tm_mday = day;
+    tm_out->tm_mon = month - 1;
+    tm_out->tm_year = year - 1900;
+    tm_out->tm_isdst = 0;
+    
+    return true;
+}
+
+// GPS processing task
+static void gps_task(void* arg) {
+    char line[128];
+    int pos = 0;
+    
+    while (1) {
+        uint8_t data;
+        int len = uart_read_bytes(GPS_UART_NUM, &data, 1, 100 / portTICK_PERIOD_MS);
+        
+        if (len > 0) {
+            if (data == '\n') {
+                line[pos] = '\0';
+                
+                struct tm gps_tm;
+                bool valid;
+                if (parse_gprmc(line, &gps_tm, &valid)) {
+                    if (valid) {
+                        time_t gps_time = mktime(&gps_tm);
+                        
+                        xSemaphoreTake(sync_mutex, portMAX_DELAY);
+                        next_pps_gps_second = gps_time + 1;
+                        xSemaphoreGive(sync_mutex);
+                        
+                        vTaskDelay(pdMS_TO_TICKS(300));
+                        
+                        xSemaphoreTake(sync_mutex, portMAX_DELAY);
+                        if (last_pps_monotonic > 0) {
+                            int64_t gps_us = (int64_t)next_pps_gps_second * 1000000LL;
+                            int64_t new_offset = gps_us - last_pps_monotonic;
+                            
+                            if (monotonic_offset_us == 0) {
+                                monotonic_offset_us = new_offset;
+                            } else {
+                                // Low-pass filter: 90% old + 10% new
+                                monotonic_offset_us = (monotonic_offset_us * 9 + new_offset) / 10;
+                            }
+                            
+                            gps_has_fix = true;
+                            
+                            ESP_LOGI(TAG, "GPS sync: %04d-%02d-%02d %02d:%02d:%02d, offset=%lld us",
+                                    gps_tm.tm_year + 1900, gps_tm.tm_mon + 1, gps_tm.tm_mday,
+                                    gps_tm.tm_hour, gps_tm.tm_min, gps_tm.tm_sec,
+                                    monotonic_offset_us);
+                        }
+                        xSemaphoreGive(sync_mutex);
+                    } else {
+                        gps_has_fix = false;
+                    }
+                }
+                
+                pos = 0;
+            } else if (pos < sizeof(line) - 1) {
+                line[pos++] = data;
+            }
+        }
+    }
+}
+
+void gps_sync_init(void) {
+    ESP_LOGI(TAG, "Initializing GPS sync");
+    
+    sync_mutex = xSemaphoreCreateMutex();
+    
+    uart_config_t uart_config = {
+        .baud_rate = GPS_BAUD_RATE,
+        .data_bits = UART_DATA_8_BITS,
+        .parity = UART_PARITY_DISABLE,
+        .stop_bits = UART_STOP_BITS_1,
+        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
+        .source_clk = UART_SCLK_DEFAULT,
+    };
+    
+    ESP_ERROR_CHECK(uart_driver_install(GPS_UART_NUM, UART_BUF_SIZE, 0, 0, NULL, 0));
+    ESP_ERROR_CHECK(uart_param_config(GPS_UART_NUM, &uart_config));
+    ESP_ERROR_CHECK(uart_set_pin(GPS_UART_NUM, GPS_TX_PIN, GPS_RX_PIN, 
+                                 UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
+    
+    gpio_config_t io_conf = {
+        .intr_type = GPIO_INTR_POSEDGE,
+        .mode = GPIO_MODE_INPUT,
+        .pin_bit_mask = (1ULL << PPS_GPIO),
+        .pull_up_en = GPIO_PULLUP_ENABLE,
+        .pull_down_en = GPIO_PULLDOWN_DISABLE,
+    };
+    ESP_ERROR_CHECK(gpio_config(&io_conf));
+    
+    ESP_ERROR_CHECK(gpio_install_isr_service(0));
+    ESP_ERROR_CHECK(gpio_isr_handler_add(PPS_GPIO, pps_isr_handler, NULL));
+    
+    xTaskCreate(gps_task, "gps_task", 4096, NULL, 5, NULL);
+    
+    ESP_LOGI(TAG, "GPS sync initialized (RX=GPIO%d, PPS=GPIO%d)", GPS_RX_PIN, PPS_GPIO);
+}
+
+gps_timestamp_t gps_get_timestamp(void) {
+    gps_timestamp_t ts;
+    
+    xSemaphoreTake(sync_mutex, portMAX_DELAY);
+    ts.monotonic_us = esp_timer_get_time();
+    ts.gps_us = ts.monotonic_us + monotonic_offset_us;
+    ts.synced = gps_has_fix;
+    xSemaphoreGive(sync_mutex);
+    
+    return ts;
+}
+
+bool gps_is_synced(void) {
+    return gps_has_fix;
+}
+ +

main.c - Example Usage

+
#include <stdio.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "esp_log.h"
+#include "gps_sync.h"
+
+static const char *TAG = "MAIN";
+
+void log_collapse_event(float nav_duration_us, int rssi) {
+    gps_timestamp_t ts = gps_get_timestamp();
+    
+    // CSV format: monotonic_us, gps_us, synced, nav_duration, rssi
+    printf("COLLAPSE,%lld,%lld,%d,%.2f,%d\n",
+           ts.monotonic_us,
+           ts.gps_us,
+           ts.synced ? 1 : 0,
+           nav_duration_us,
+           rssi);
+}
+
+void app_main(void) {
+    ESP_LOGI(TAG, "Starting GPS sync");
+    
+    gps_sync_init();
+    
+    ESP_LOGI(TAG, "Waiting for GPS fix...");
+    while (!gps_is_synced()) {
+        vTaskDelay(pdMS_TO_TICKS(1000));
+    }
+    ESP_LOGI(TAG, "GPS synced!");
+    
+    while (1) {
+        gps_timestamp_t ts = gps_get_timestamp();
+        
+        ESP_LOGI(TAG, "Time: mono=%lld gps=%lld synced=%d",
+                ts.monotonic_us, ts.gps_us, ts.synced);
+        
+        // Example: log collapse event
+        if (ts.monotonic_us % 10000000 < 100000) {
+            log_collapse_event(1234.5, -65);
+        }
+        
+        vTaskDelay(pdMS_TO_TICKS(1000));
+    }
+}
+ +

CMakeLists.txt

+
idf_component_register(SRCS "main.c" "gps_sync.c"
+                      INCLUDE_DIRS ".")
+
+ +
+

Building and Flashing

+ +

Setup ESP-IDF Environment

+
# Install ESP-IDF (if not already installed)
+# Follow: https://docs.espressif.com/projects/esp-idf/en/latest/esp32c5/get-started/
+
+# Set target to ESP32-C5
+idf.py set-target esp32c5
+
+# Build the project
+idf.py build
+
+# Flash to device
+idf.py flash
+
+# Monitor output
+idf.py monitor
+ +
+ Expected Output: +
+I (500) GPS_SYNC: Initializing GPS sync (RX=GPIO4, PPS=GPIO1)
+I (1000) MAIN: Waiting for GPS fix...
+I (5000) GPS_SYNC: GPS sync: 2025-12-06 18:30:45, offset=1733424645123456 us
+I (5001) MAIN: GPS synced!
+I (6000) MAIN: Time: mono=123456789 gps=1733424645123456 synced=1
+COLLAPSE,123456789,1733424645123456,1,1234.50,-65
+            
+
+
+ +
+

Integration with iperf2

+ +

On Raspberry Pi 5 (iperf2 Server)

+

Your Pi is already GPS-synced. Run iperf2 with timestamps:

+
# Server mode with histograms and trip-times
+iperf -s --histograms --trip-times -i 0.1
+
+# Or as client testing against a target
+iperf -c target_ip --histograms --trip-times -i 0.1
+ +

Correlation Analysis

+

Both systems now share GPS time. Example Python analysis:

+
import pandas as pd
+import matplotlib.pyplot as plt
+
+# Load ESP32 collapse events
+esp32_events = pd.read_csv('collapse_events.csv', 
+                           names=['event', 'mono_us', 'gps_us', 'synced', 'nav_dur', 'rssi'],
+                           parse_dates=['gps_us'], 
+                           date_parser=lambda x: pd.to_datetime(int(x), unit='us'))
+
+# Load iperf2 data
+iperf_data = pd.read_csv('iperf_histograms.csv', 
+                         parse_dates=['timestamp'])
+
+# Merge on GPS timestamp (within 100ms window)
+merged = pd.merge_asof(iperf_data.sort_values('timestamp'), 
+                       esp32_events.sort_values('gps_us'),
+                       left_on='timestamp',
+                       right_on='gps_us',
+                       tolerance=pd.Timedelta('100ms'),
+                       direction='nearest')
+
+# Plot latency vs collapse events
+fig, ax1 = plt.subplots(figsize=(12, 6))
+ax1.plot(merged['timestamp'], merged['latency_ms'], 'b-', label='Latency')
+ax1.set_ylabel('Latency (ms)', color='b')
+
+ax2 = ax1.twinx()
+collapse_times = merged[merged['event'] == 'COLLAPSE']['timestamp']
+ax2.scatter(collapse_times, [1]*len(collapse_times), color='r', marker='x', s=100, label='Collapse')
+ax2.set_ylabel('Collapse Events', color='r')
+
+plt.title('WiFi Latency vs Collapse Detection Events')
+plt.show()
+
+ +
+

Deployment for 32+ Devices

+ +

Mass Configuration Script

+

Flash and configure multiple ESP32s with unique static IPs:

+
#!/bin/bash
+# flash_all.sh
+
+START_IP=192.168.1.100
+PORT_BASE=/dev/ttyUSB
+
+for i in {0..31}; do
+    DEVICE=${PORT_BASE}${i}
+    IP=$((START_IP + i))
+    
+    echo "Flashing device $i at $DEVICE with IP 192.168.1.$IP"
+    
+    # Set device-specific config
+    idf.py -p $DEVICE -D DEVICE_ID=$i -D STATIC_IP=192.168.1.$IP flash
+    
+    sleep 2
+done
+
+echo "All devices flashed!"
+ +

Physical Setup Recommendations

+ +
+ +
+

Troubleshooting

+ +

No GPS Fix

+ + +

PPS Not Working

+ + +

Time Drift

+ +
+ +
+

Technical Details

+ +

Timing Accuracy

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ComponentAccuracyNotes
GT-U7 GPS PPS Output±50-100nsCompatible with NEO-6M timing specs
ESP32 Interrupt Latency1-5μs typicalIRAM_ATTR reduces latency
esp_timer_get_time()1μs resolutionAccuracy ±10-20ppm (crystal dependent)
Overall System~5-10μsSufficient for latency histogram correlation
+ +

Monotonic vs GPS Time

+
+ Monotonic Time (monotonic_us): +
    +
  • Never jumps backward or forward
  • +
  • Used for measuring intervals and durations
  • +
  • Not affected by GPS sync adjustments
  • +
  • Example: Navigation duration, event spacing
  • +
+
+ GPS Time (gps_us): +
    +
  • UTC time from GPS satellites
  • +
  • Used for correlation with iperf2 and other systems
  • +
  • Can have small adjustments as GPS sync improves
  • +
  • Example: Absolute timestamp for event correlation
  • +
+
+
+ +
+

Additional Resources

+ +
+ + + + \ No newline at end of file diff --git a/doc/esp32-c5-pinout-simple.html b/doc/esp32-c5-pinout-simple.html new file mode 100644 index 0000000..82f08ab --- /dev/null +++ b/doc/esp32-c5-pinout-simple.html @@ -0,0 +1,583 @@ + + + + + + ESP32-C5-DevKitC-1 v1.2 - Simple Pinout + + + +
+

ESP32-C5-DevKitC-1 v1.2

+
Quick Reference Pinout Guide
+ + +
+
+
🔌
+
ESP32 USB (Left)
+
Native USB on GPIO13/14
+
USB 2.0 • JTAG Debug
+
+ + +
+ + +
+

GPS Module Wiring - MakerFocus GT-U7

+
+ ✓ GT-U7 Specifications: +
    +
  • Operating Voltage: 3.6V - 5V (3.3V works perfectly!)
  • +
  • Logic Level: 3.3V or 5V compatible
  • +
  • Baud Rate: 9600 (default)
  • +
  • Compatible with: NEO-6M (uses same NMEA format)
  • +
  • Includes: IPEX active antenna, EEPROM, USB interface
  • +
+
+ +
+
GT-U7 VCC
+
+
J1 Pin 1 (3V3)
+
+ +
+
GT-U7 GND
+
+
J1 Pin 15 (GND)
+
+ +
+
GT-U7 TXD (data)
+
+
J3 Pin 8 (GPIO4)
+
+ +
+
GT-U7 PPS (pulse)
+
+
J1 Pin 6 (GPIO1)
+
+ +
+
GT-U7 RXD (optional)
+
+
J3 Pin 9 (GPIO5)
+
+
+ + +
+ +
+

Left Side (J1)

+ +
+
1
+
3V3
+
Power 3.3V → GT-U7 VCC
+
+ +
+
2
+
RST
+
Reset (Active Low)
+
+ +
+
3
+
GPIO2
+
MTMS ⚠ Strapping • I2C_SDA • ADC1_CH1
+
+ +
+
4
+
GPIO3
+
MTDI ⚠ Strapping • I2C_SCL • ADC1_CH2
+
+ +
+
5
+
GPIO0
+
LP_UART_DTRN
+
+ +
+
6
+
GPIO1
+
← GT-U7 PPS • ADC1_CH0
+
+ +
+
7
+
GPIO6
+
ADC1_CH5 • FSPICLK
+
+ +
+
8
+
GPIO7
+
⚠ Strapping • FSPID • SDIO_DATA1
+
+ +
+
9
+
GPIO8
+
SDIO_DATA0
+
+ +
+
10
+
GPIO9
+
SDIO_CLK
+
+ +
+
11
+
GPIO10
+
FSPICS0 • SDIO_CMD
+
+ +
+
12
+
GPIO26
+
⚠ Strapping Pin
+
+ +
+
13
+
GPIO25
+
⚠ Strapping Pin
+
+ +
+
14
+
5V
+
Power 5V In/Out
+
+ +
+
15
+
GND
+
Ground → GT-U7 GND
+
+ +
+
16
+
NC
+
No Connection
+
+
+ + +
+

Right Side (J3)

+ +
+
1
+
GND
+
Ground
+
+ +
+
2
+
TX
+
UART0 TXD • GPIO11
+
+ +
+
3
+
RX
+
UART0 RXD • GPIO12
+
+ +
+
4
+
GPIO24
+
General Purpose I/O
+
+ +
+
5
+
GPIO23
+
General Purpose I/O
+
+ +
+
6
+
NC
+
GPIO15 (used by PSRAM on N8R4)
+
+ +
+
7
+
GPIO27
+
⚠ Strapping • RGB LED
+
+ +
+
8
+
GPIO4
+
← GT-U7 TXD • LP_UART_RXD • ADC1_CH3
+
+ +
+
9
+
GPIO5
+
→ GT-U7 RXD (optional) • LP_UART_TXD • ADC1_CH4
+
+ +
+
10
+
NC
+
No Connection
+
+ +
+
11
+
GPIO28
+
⚠ Strapping Pin
+
+ +
+
12
+
GND
+
Ground
+
+ +
+
13
+
GPIO14
+
USB_D+ • SDIO_DATA2
+
+ +
+
14
+
GPIO13
+
USB_D- • SDIO_DATA3
+
+ +
+
15
+
GND
+
Ground
+
+ +
+
16
+
NC
+
No Connection
+
+
+
+ + +
+
+
+
Power (3V3, 5V)
+
+ +
+
+
Ground (GND)
+
+ +
+
+
GPIO Pins
+
+ +
+
+
Special (UART, USB)
+
+ +
+
+
⚠ Strapping Pins
+
+ +
+
+
GPS Connections
+
+
+ +
+

⚠ Important Notes

+
    +
  • MakerFocus GT-U7: This module works with 3.3V to 5V. Using ESP32's 3.3V pin is perfect and safe!
  • +
  • Antenna: GT-U7 comes with IPEX active antenna - connect it to the module's IPEX connector for best GPS reception.
  • +
  • First GPS fix: Cold start takes 30-60 seconds outdoors with clear sky view. Subsequent fixes are much faster.
  • +
  • Strapping Pins (⚠): GPIO2, 3, 7, 25, 26, 27, 28 control boot behavior. Avoid using for external connections.
  • +
  • For programming: Use the UART USB port (right side). More reliable than native USB.
  • +
  • N8R4 has PSRAM: GPIO15 (J3 Pin 6) is not available - used internally for PSRAM.
  • +
+
+ +
+

Reference: ESP32-C5-DevKitC-1 v1.2 Official Documentation

+
+
+ + \ No newline at end of file