¿Brújula GPS para tus salidas al cerro?

¿Alguna vez te perdiste en un sendero del cajón del Maipo y quisiste tener una brújula que recordara dónde dejaste el auto? Eso es exactamente lo que resuelve este proyecto: una brújula GPS portátil, alimentada por batería, que guarda waypoints (puntos guardados) y te apunta hacia ellos. La idea original viene de los hermanos Ruiz en Adafruit, inspirados en el ítem del juego Minecraft que apunta a la cama del jugador. Acá la adaptamos a hardware que sí encuentras en Chile: ESP32, módulo GPS NEO-6M y pantalla OLED, manteniendo intacta la experiencia de guardar y elegir destinos desde un menú con dos botones.

Al final vas a tener una brújula con menú navegable, modo claro y modo oscuro, soporte para declinación magnética chilena (aproximadamente +5° en Santiago, varía por región) y unidades configurables entre kilómetros y millas. La autonomía con una LiPo de 2000 mAh ronda las 6 horas de uso continuo.

¿Por qué cambiamos el hardware?

El proyecto original usa una Feather RP2350 con un breakout GPS PA1010D, IMU LSM6DSOX más LIS3MDL y un TFT FeatherWing de 3.5 pulgadas. Todo Adafruit, todo importado y con un costo total cercano a USD 100. En Chile, la combinación equivalente con ESP32 más NEO-6M más MPU9250 más OLED SSD1306 cuesta menos de un tercio y entrega lo mismo en funcionalidad: GPS con NMEA, magnetómetro de tres ejes para el rumbo y una pantalla legible en exterior.

La pantalla OLED de 0.96 pulgadas es más chica que la TFT original (480 por 320), pero la información que muestra una brújula (dirección cardinal, distancia al waypoint, lectura GPS) cabe perfecto en 128 por 64 píxeles si simplificamos el render. Si quieres mantener el TFT a color, en la sección de variantes dejamos esa opción.

Hardware: el corazón del dispositivo

Vista de los módulos principales del proyecto sobre la mesa

Tres bloques funcionales conviven en este aparato:

  • ESP32 DevKit: el cerebro. Tiene dos núcleos, UART libre para el GPS y bus I2C para la IMU más pantalla. Suficiente RAM para mantener una tabla de waypoints en memoria sin tocar la flash. El consumo bajo en deep sleep (cerca de 10 µA) es una bendición para autonomía cuando guardes la brújula en la mochila entre miradas.
  • GPS NEO-6M: módulo ubicuo basado en el chip u-blox NEO-6M. Recibe NMEA por UART a 9600 baudios. La primera fijación (cold start) toma de 30 a 90 segundos a cielo abierto; los siguientes arranques son casi instantáneos gracias a la batería de respaldo interna.
  • IMU MPU9250: incluye acelerómetro, giroscopio y, lo importante para la brújula, magnetómetro AK8963. Lee el campo magnético terrestre en tres ejes; combinando esa lectura con la inclinación del dispositivo (acelerómetro), calculas el rumbo verdadero respecto al norte magnético.

La pantalla SSD1306 va por I2C (mismo bus que la IMU, distinta dirección: 0x3C versus 0x68). Dos pulsadores manejan el menú (uno arriba y selección, otro abajo y atrás). Un switch deslizante corta la alimentación cuando la guardas.

Cableado

Conexiones I2C compartidas (IMU más OLED):

  • SDA a GPIO21
  • SCL a GPIO22
  • VCC a 3.3 V
  • GND a GND

GPS NEO-6M por UART2:

  • TX (del GPS) a GPIO16 (RX2 del ESP32)
  • RX (del GPS) a GPIO17 (TX2 del ESP32)
  • VCC a 5 V (el regulador interno del módulo baja a 3.3 V)
  • GND a GND

Botones (con pull up interno habilitado por software):

  • Botón "arriba y selección" a GPIO4 contra GND
  • Botón "abajo y atrás" a GPIO5 contra GND

Alimentación: la LiPo va al TP4056 (entrada B+ y B-), y desde la salida del TP (OUT+ y OUT-) al pin VIN del ESP32 a través del switch deslizante. El TP4056 maneja la carga cuando enchufas un cable micro USB.

Detalle clave: el regulador AMS1117 del ESP32 DevKit necesita al menos 4.5 V en VIN para sacar 3.3 V estables. Con la LiPo descargada bajo 3.5 V, vas a tener resets inesperados. Si quieres autonomía extendida, conviene poner un step up MT3608 entre la LiPo y el VIN ajustado a 5 V.

Firmware: la lógica del menú

El sketch corre en Arduino IDE con el board manager de ESP32 instalado. Necesitas estas librerías (todas vienen del Library Manager):

  • TinyGPSPlus (Mikal Hart) para parsear las tramas NMEA del NEO-6M
  • Adafruit GFX Library y Adafruit SSD1306 para el render OLED
  • MPU9250 (Hideakitai) para el sensor de movimiento y magnetómetro

El flujo principal es una máquina de estados con cuatro pantallas:

  1. Compass (default): lectura del rumbo más flecha apuntando al waypoint activo
  2. Menu: lista de waypoints guardados, navegación con botones
  3. Save dialog: confirmar guardar la posición actual como waypoint (mantén presionado 2 segundos el botón de selección)
  4. Settings: declinación magnética, unidades, modo claro u oscuro

Los waypoints se guardan en la flash del ESP32 usando la librería Preferences.h (un wrapper sobre la NVS). Cada waypoint son 16 bytes: nombre (8 caracteres) más latitud (float) más longitud (float). Con 2 KB de NVS asignados, caben cerca de 100 puntos sin estrujar.

Menú de selección de waypoint guardado en la pantalla OLED

El cálculo del rumbo viene de la fórmula del rumbo inicial entre dos puntos GPS (great circle bearing). Sin entrar en la trigonometría completa, lo que importa es que la flecha apunta al rumbo absoluto, y luego restas el heading actual de la brújula para que la flecha en pantalla apunte siempre relativa hacia donde te apuntas tú. Si te das vuelta, la flecha rota.

Calibración del magnetómetro

Esta parte es la que más se salta la gente y la que más errores genera. El magnetómetro está expuesto a campos parásitos: el propio cableado, el ESP32, la batería. Sin calibrar, el rumbo puede estar 30° equivocado y la brújula apunta a cualquier parte.

Pantalla mostrando el progreso del proceso de calibración

La calibración se hace una vez, al primer encendido:

  1. Pones la brújula plana y la giras lentamente en horizontal por 30 segundos
  2. La giras en vertical otros 30 segundos (figura ocho lenta en el aire)
  3. El firmware registra los valores máximo y mínimo en X, Y, Z y calcula el offset de hard iron
  4. Los offsets se guardan en NVS, así que no hay que repetir el proceso salvo que cambies de hardware

Para la declinación magnética: en Chile va de aproximadamente +3° en el norte a +8° en el sur. En Santiago son cerca de +5° este (declinación positiva significa que el norte magnético apunta al este del norte verdadero). Edita la constante MAG_DECLINATION en el código según tu ubicación o usa el calculador de NOAA con tu latitud y longitud.

Pantalla del dispositivo mostrando lectura GPS y declinación configurada

Impresión 3D de la carcasa

El proyecto original incluye archivos 3MF y STEP para los huecos exactos de los breakouts Adafruit. Para esta versión con ESP32 más NEO-6M, tienes dos opciones:

  • Recomendada: descargar los 3MF originales y editar en Fusion 360 o OnShape los cortes para que calcen tu ESP32 DevKit (más ancho que el Feather) y el conector del NEO-6M con antena
  • Atajo: usar una caja universal genérica de Thingiverse del tipo "ESP32 enclosure 70x50x25mm" y ventilar con una rejilla impresa para la antena GPS

Ajustes sugeridos para el slicer (BambuStudio o PrusaSlicer):

  • Filamento PLA color a gusto
  • Boquilla 0.4 mm, capa 0.2 mm
  • Relleno 10% giroide
  • Soporte tipo árbol solo donde corresponda
  • Cama 60 °C, extrusor 215 °C

Para el frente de la pantalla OLED, una lámina antirreflejo cortada a medida ayuda mucho con la luz directa al aire libre. Sirve la misma película que vende cualquier tienda fotográfica para protección de cámaras.

Uso en terreno

Brújula GPS en uso al aire libre

Encender, esperar el fix GPS (el indicador parpadea hasta cuadrar) y guardar la posición de partida con un long press del botón de selección. A medida que avanzas, la flecha rota para apuntar de vuelta al origen y el indicador de distancia te dice cuántos metros faltan. Al pasar a un radio de 10 metros del waypoint, el dispositivo vibra (si conectaste un motor háptico) o parpadea la pantalla.

Para senderos con varios puntos (miradores, ríos, refugios) guardas cada uno con un nombre corto al pasar. Desde el menú vuelves a elegir cualquier punto como destino activo. La memoria persiste apagado, así que mañana sigues con los mismos puntos.

Variantes y mejoras

  1. Modo marino con filtro Madgwick: si llevas la brújula en kayak o velero, agregar un filtro complementario sobre la IMU permite estabilizar el rumbo aunque el aparato se mueva con el oleaje. La librería MadgwickAHRS de Arduino hace la integración en menos de 200 líneas y combina giroscopio, acelerómetro y magnetómetro para una orientación que no se sacude con el movimiento.

  2. Pantalla TFT a color 1.8 pulgadas (ST7735): si quieres mantener el feel del tutorial original con gráficos más ricos, reemplaza el SSD1306 por un ST7735 SPI. Tienes que liberar GPIO12, 13, 14 y 15 para el bus SPI y migrar las llamadas a la librería Adafruit_ST7735. El consumo sube cerca de 40 mA, así que ajusta el cálculo de batería.

  3. Logging a tarjeta microSD: agregar un módulo microSD por SPI te permite registrar el track completo en formato GPX. Útil para subir después a Strava, Wikiloc o Google Earth. Cada lectura GPS son cerca de 80 bytes en GPX, así que con una microSD de 2 GB tienes para años de salidas.

Personalización para Chile

En MechatronicStore puedes armar el BOM completo. Lo más relevante para esta versión:

  • Placa ESP32 DevKit V1 (38 pines, conector micro USB)
  • Módulo GPS NEO-6M con antena cerámica activa
  • Sensor MPU9250 9-DoF en breakout I2C
  • Pantalla OLED SSD1306 0.96 pulgadas I2C (blanca o azul)
  • Batería LiPo 3.7 V 2000 mAh con conector JST PH
  • Módulo cargador TP4056 con protección de carga y descarga
  • Pulsadores táctiles 6x6 mm (al menos tres, uno extra de repuesto nunca está de más)
  • Switch deslizante SPDT miniatura
  • Set de jumpers macho hembra 20 cm
  • Cable USB-A a micro USB 1 metro

Equivalencias respecto al tutorial original:

  • El Adafruit Feather RP2350 se reemplaza por el ESP32 DevKit V1. Ambos son microcontroladores de 32 bits con WiFi y BLE; el ESP32 tiene más GPIO disponibles y es mucho más barato en Chile.
  • El GPS PA1010D STEMMA QT se reemplaza por NEO-6M con headers macho. La conexión deja de ser plug and-play (vas a tener que soldar cuatro cables o usar jumpers), pero el rendimiento de fix es comparable.
  • La IMU LSM6DSOX más LIS3MDL (9-DoF de alta precisión) se reemplaza por MPU9250. Para una brújula recreativa, la precisión del MPU9250 tras calibrar (cerca de 1°) es más que suficiente.
  • El TFT FeatherWing 3.5 pulgadas se reemplaza por OLED SSD1306 0.96 pulgadas. La pantalla queda más chica, pero el consumo baja a una décima parte (cerca de 10 mA versus 120 mA) y la legibilidad bajo sol directo es mejor.

Costo estimado del BOM en Chile: entre CLP $35.000 y $45.000 según promociones, sin contar el filamento PLA (que probablemente ya tienes) ni los tornillos M2.5 (vienen en cualquier ferretería).

Recursos

Versión chilena con componentes en stock local en MechatronicStore. Inspirado en el proyecto original de Ruiz Brothers para Adafruit.