Mostrando entradas con la etiqueta GY-NEO6MV2. Mostrar todas las entradas
Mostrando entradas con la etiqueta GY-NEO6MV2. Mostrar todas las entradas

sábado, 25 de octubre de 2025

ESP8266 con GPS GY-NEO6MV2: Guarda rutas en LittleFS y convierte a KML/GPX

Muy buenas a todos y todas!!!

Seguimos investigando nuevas funciones para el módulo GPS GY-NEO6MV2, un módulo sencillo y económico que podemos implementar en cualquier microcontrolador, desde un Arduino UNO a un ESP32.

Pero como no siempre podemos tener un dispositivo conectado para leer los datos del GPS una solución sencilla es almacenarlos.

En este caso vamos el ESP8266 que será capaz de almacenar los datos relacionados con la posición, velocidad o altitud en su memoria interna, alrededor de 4MB. (Este valor puede variar según el modelo).

Para esta funcionalidad usaremos la libreía LittleFS de la que ya hemos hablado en "ESP8266 Como usar LittleFS para guardar información".

Los datos se almacenan en un archivo con formato JSON al ser uno de los formatos de intercambio de datos sencillo de escribir, ligero y eficiente. Ideal para microcontroladores.

Este archivo con los datos en formato JSON los descargaremos con un programa escrito en Python3 para poder procesarlos posteriormente a diferentes formatos como KML o GPX, muy utilizados por dispositivos deportivos, aplicaciones móviles como GAIA GPS o programas como Google Earth.



Componentes para GPS tracker con Wemos D1 Mini

Para este proyecto solo vamos a necesitar:

  • ESP8266 Wemos D1 Mini (clon)
  • Módulo GPS GY-NEO6MV2
  • Batería

La conexión de los dispositivos GY-NEO6MV2 y Wemos D1 Mini


Librerías necesarias para Wemos D1 Mini

Para programar el Wemos D1 usaremos el IDE de Arduino y las siguiente librerías necesarias para la instalación del sketch:

  • ESP8266Wifi
    Gestiona la conexión WiFi en modo AP o cliente del ESP8266. Para este proyecto usaremos el modo AP.

  • LittleFS
    Sistema de archivos para almacenar datos en la memoria flash (similar a SPIFFS).

  • TinyGPSPlus
    Decodifica datos NMEA del módulo GPS y proporciona métricas (lat, lng, alt, etc.).

  • ESP8266WebServer
    Crea un servidor HTTP para manejar peticiones REST (GET/DELETE).

  • SoftwareSerial
    Permite comunicación serial con hardware no nativo (GPS en este caso).

  • ArduinoJSON Serializa/deserializa datos JSON para la API REST.

Veamos el flujo de trabajo para el ESP8266 Wemos D1 Mini


🖥️ Procesamiento: Wemos D1 Mini

Para que todo el proyecto funcione correctamente necesitaremos algunas librerías externas:

  • Decodificación de datos GPS:
    Convierte el formato NMEA a valores útiles como latitud, longitud, altitud o el número de satélites usando la librería TinyGPSPlus.

  • Formato de datos JSON:
    Serialización y estructura de datos en formato JSON usando la librería ArduinoJson
    
        DynamicJsonDocument doc(200);  // Crea JSON de 200 bytes
        doc["sat"] = String(gps.satellites.value());  // Satélites visibles
        doc["lat"] = gps.location.lat();              // Latitud
        doc["lng"] = gps.location.lng();              // Longitud
        doc["tim"] = gps.time.value();                // Hora (formato hhmmsscc)
        doc["alt"] = gps.altitude.meters();           // Altitud en metros
        doc["spe"] = gps.speed.kmph();                // Velocidad en km/h
    	
        String response;
        serializeJson(doc, response);  // Convierte JSON a String
        

  • Almacenamiento con LittleFS:
    Guarda datos o elimina el archivo en formato JSON en la memoria interna haciendo uso de la librería LittleFS.
  • 
        LittleFS.open("/gps_data.json", "a");	// Abre el archivo "gps_data.json" en el directrorio raíz "/".
        LittleFS.remove("/gps_data.json");  // Elimina el archivo "gps_data.json" en el directrorio raíz "/".
    
      	
  • Servicio Web con 3 endpoints:
    Crearemos un servidor web con la librería ESP8266WebServer que se instala cuando instalamos la placa ESP8266.
    
        ESP8266WebServer server(80);	// Creamos el servidor en el puerto 80.
        server.on("/gps", HTTP_GET, handleGPSData);       // GET /gps → Datos actuales
        
        server.on("/download", HTTP_GET, handleDownload); // GET /download → Archivo JSON
        
        server.on("/clear", HTTP_DELETE, handleClear);    // DELETE /clear → Borra datos
        
        
    Los Endpoints son rutas URL con un metodo HTTP asignado a una función:
    • "/gps", HTTP_GET, handleGPSData:
      Con esta petición obtenemos los datos en tiempo real desde la función: handleGPSData.

    • "/download", HTTP_GET, handleDownload:
      Descarga el historial completo a un archivo con extensión JSON desde la función: handleDownload.

    • "/clear", HTTP_DELETE, handleClear:
      Borra el el archivo con el historial con la función asignada handleClear.

Para comprobar que todo esta correcto podemos abrir el monitor serial y tiene que aparecer una salida similar a la que se muestra a continuación:


Obtención de datos GY-NEO6MV2 desde el navegador

Esta opción es la más sencilla de todas si solo necesitas el archivo JSON. Solo tienes que conectarte con la IP generada por ESP8266, normalmente la 192.168.4.1.

Podemos usar cualquiera de los 3 Endpoints definidos:

  • http://192.168.4.1/gps

  • http://192.168.4.1/download

  • http://192.168.4.1/remove
    con este comando borraremos la memoria del Wemos Mini D1

Obtención de datos desde Python

Otra de las opciones para descargar los datos es el programa que tenemos a continuación:


import requests
import json

# Configuración
IP_WEMOS = "192.168.1.41"  # Reemplaza con la IP de tu Wemos

# 1. Obtener último dato (endpoint /gps)
response = requests.get(f"http://{IP_WEMOS}/gps")
if response.status_code == 200:
    data = response.json()
    print("Última posición:", data["lat"], data["lng"])

# 2. Descargar archivo completo (endpoint /download)
response = requests.get(f"http://{IP_WEMOS}/download")
if response.status_code == 200:
    with open("gps_data.json", "wb") as f:
        f.write(response.content)
    print("Archivo descargado!")


Sencillo pero efectivo, utiliza dos de los EndPoints, /gps y /download que ya hemos visto más arriba y nos proporcionara un archivo llamado gps_data.json.py.

Obtención y procesamiento de datos desde Python

Pero con los datos del JSON "en crudo" es difícil aplicarlos a otras aplicaciones ya que no es un estándar. Para tener una mayor compatibilidad con otros dispositivos existen otros formatos de intercambio de datos como KML y GPX

El formato KML (Keyhole Markup Language)

Es el formato nativo de Google Earth/Google Maps y es ideal para visualización en mapas interactivos y también incluye estilos, colores, iconos personalizables.

  • Excelente para visualización (Google Earth/Maps)
  • Muy usado en aplicaciones web
  • Menos compatible con dispositivos GPS físicos


<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
  <Document>
    <Placemark>
      <name>Zona de Descanso</name>
        <Polygon>
          <extrude>1</extrude>>
          <altitudeMode>absolute</altitudeMode>
          <outerBoundaryIs>
          <LinearRing>
            <coordinates>
              -3.579900,37.707300,1850.0
              -3.580000,37.707300,1850.0
              -3.580000,37.707400,1850.0
              -3.579900,37.707400,1850.0
              -3.579900,37.707300,1850.0
            </coordinates>
          </LinearRing>
        </outerBoundaryIs>
      </Polygon>
    </Placemark>
  </Document>
</kml>


El formato GPX (GPS Exchange Format)

Es el estándar universal para dispositivos GPS, creado específicamente para GPS (no adaptado como KML) y el formato nativo de la mayoría de dispositivos GPS

  • Metadata completa: elevación, tiempo, satélites, etc.
  • Múltiples tracks/routes en un archivo
  • Waypoints (puntos de interés)
  • Estándar abierto y bien documentado


<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.1" creator="WEMOS D1 Mini" 
    xmlns="http://www.topografix.com/GPX/1/1"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
    
  <!-- Punto 1 -->
  <trkpt lat="37.707408" lon="-3.579952">
    <ele>1850.5</ele>
    <time>2024-01-15T08:30:00Z</time>
    <speed>2.5</speed>
    <sat8></sat>
    <extensions>
      <hr>125</hr>
      <cadence>85</cadence>
      <temp>15</temp>
    </extensions>
  </trkpt>
</gpx>


Esta conversión de formato JSON a KML o GPX la podemos realizar de la mano Python y un programa que reúne todo lo que se ha visto hasta ahora. Conexión, descarga, visualización y conversión.

Esta diseñado para su uso en terminal y con el que obtendremos el archivo .json y lo convertirá a uno de los dos formatos, KML y GPX de manera independiente, o a los dos formatos al mismo tiempo.

Estas son las opciones del menú:

  • 1. Descargar datos del WEMOS (JSON)
  • 2. Cargar datos desde archivo JSON
  • 3. Convertir a KML (Google Earth)
  • 4. Convertir a GPX (Dispositivos GPS)
  • 5. Convertir a AMBOS formatos
  • 6. Ver información del WEMOS
  • 0. Salir


Una vez terminado ya tenemos los archivos con las extensiones KML y GPX.



Vamos a utilizar el archivo generado en formato KML para mostrar la ruta en Google Maps:

Abrimos el navegador en la ruta earth.google.com y en la barra lateral izquierda nos aparece un sigo +.

Se abrirá un desplegable y seleccionamos "Importar KML/KMZ"



Y este es el resultado final de la importacion



Conclusión del proyecto:

La comunicación entre el ESP8266 WEMOS D1 Mini y el módulo GPS GY-NEO6MV2 ha demostrado ser una solución funcional y eficiente para la captura de datos de geolocalización.

El sistema constituye una base sólida para proyectos que requieran tracking GPS, pudiendo extenderse hacia aplicaciones de monitorización de flotas, seguimiento deportivo o recopilación de datos para análisis geográfico.

Es un ejemplo que podemos modular el diseño facilitando la incorporación de sensores adicionales como el ADXL345 o el MPU6050.

Archivos para descargar

Los archivos para descargar el ejemplo los podemos encontrar en GitHub en el repositorio ESP8266 GPS tracker KML converter

Espero que os guste el proyecto!! Saludos!!!


Aquí tienes otros enlaces de este blog relacionados con sensores y Arduino:

miércoles, 2 de abril de 2025

Geo6Mv2 GPS para Android: Conecta y visualiza rutas en tu móvil

Muy buenas a todos y todas!!!

En este Blog ya hemos visto usar el módulo GY-NEO6MV2 GPS en dos modos diferentes, NEO6MV2 GPS serial y representando la ubicación en un programa escrito en Python y OpenStreetMaps.

Pero ahora toca salir al exterior y probar el el modulo GY-NEO6Mv2, para esto tenemos Geo6Mv2 for Android un pequeño programa para teléfonos Android con el que nos podemos conectar vía Wifi y ver los datos recibidos en nuestro terminal Android.



Además podemos marcar los puntos que necesitemos y la misma aplicación trazará una linea entre los diferentes puntos.

Configuración de Geo6Mv2:


En su configuración podremos cambiar ciertos parámetros como:

  • Use Marks: Opción para usar marcadores sobre la pantalla.
  • Big Icon mark: Icono de marcación grande o pequeño.
  • Short Mark description: Para cambiar el titulo que aparecera en los marcadores
  • Minimun distance to update: Distancia mínima a la que el sensor actualizará la posición. Ideal para mejorar la precisión entre puntos. Si la última posición es mayor a ese valor se creará un nuevo punto en el mapa.
  • Custom zoom: Zoom con el que se inicia el programa y cualdo se pulse sobre el botón "Centrar.
  • Show data input: Muestra en la pantalla principal los datos que recibe directamente desde el módulo GY-NEO6MV2.
  • Show coordinates with one tap: Para mostrar las coordenadas al pulsar sobre el mapa.
  • Start point: Latitud y longitud en los que aparece el mapa al iniciar el programa.

También podemos copiar esas coordenadas en el portapapeles y copiarlas donde queramos. Para esto haremos una pulsación larga sobre las coordenadas que aparecen en la parte inferior de la pantalla principal:





Con una interfaz sencilla capaz de mostrar todos los datos recibidos por este sensor de posicionamiento.

La librería que se utiliza es "TinyGPSPlus.h" de Mikal. La librería TinyGPSPlus se puede descargar desde el mismo gestor de bibliotecas del que dispone el IDE de Arduino.

Con la librería instalada, descargamos el programa para el ESP8266 geo6mv2-for-android desde GitHub.

En este caso la placa que vamos a utilizar será un NodeMCU 1.0, aunque puede servir cualquier ESP8266 al que le podamos añadir una entrada serial extra con la librería "SoftwareSerial.h". Este es el diagrama de conexiones.

Recuerda que los pines D3(tx) y D4(rx) corresponden a los GPIO 2(tx) y 0(rx). Esto suele crear confusión a la hora de definir los pines. Revisa la hoja de datos de tu placa para evitar posibles errores.

Configuración Geo6mv2-for-android.ino

Unicamente tenemos que configurar la conexión wifi a la que nos vamos a conectar completando los parámetros YOUR_SSID y WIFI_PASSWORD.


const char* ssid = "YOUR_SSID";
const char* password =  "WIFI_PASSWORD";

  • Wifi en red local
  • Android en modo punto de acceso (AP)

Red Local:

Este es el router wifi o punto de acceso que tenemos normalmente en casa, el inconveniente es que solo nos podemos mover en el rango que nos permita el router.En este caso YOUR_SSID y PASSWORD serán las mismas que utilizas para conectar cualquier dispositivo Wifi.

Android en modo punto de acceso (AP):

Geo6Mv2 for Android conexión Wifi

Esta es la mejor opción para exteriores. Se encuentra en la configuración del propio teléfono, su acceso dependerá de la versión de Android que estemos usando.

Ya en la pantalla de configuración nos muestra el SSID y pulsando sobre Hotspot password nos mostrará el password de la red.

Copiamos estos datos en YOUR_SSID y WIFI_PASSWORD y ya tenemos los datos de la red para exteriores.

Nota:

En algunos modelos de Android es necesario desactivar el Wifi "normal" antes de empezar con la conexión con Arduino.

Subir el programa al ESP8266 NodeMCU:

Si ya has configurado la red wifi el último paso es subir el programa al ESP8266 seleccionando el puerto donde este conectado COM X para Windows o /dev/ttyUSBX si usas Linux.

Con la placa y el puerto seleccionado, pulsamos sobre el botón "cargar".

En cualquiera de los dos casos, red local o punto de acceso, cuando abrimos el monitor serial del IDE de Arduino nos aparece la IP a la que nos tenemos que conectar desde el dispositivo Android:



Primera conexión

La primera conexión que realiza el módulo puede demorar más de un minuto dependiendo de la cobertura que tengamos. Recuerda que si estas en un interior poner el módulo cerca de una ventana para mejorar la recepción.

Abrimos el programa que ya tenemos descargado en nuestro dispositivo Android y pulsamos sobre el menú en la opción "Start Wifi y se abrirá la siguiente pantalla: 

 


Y pulsamos sobre el botón "Connect!

Ahora solo hay que esperar a que el módulo GY-Neo6MV2 tenga los suficientes satélites para que podamos fijar la posición.


Como al iniciar el programa aparecemos en Madrid, este valor se puede cambiar para iniciar en la localización que más nos guste. Pulsamos sobre "Add mark" para fijar la posición que recibimos desde el ESP8266 y seguidamente pulsamos "Center" para central la última marcha creada.

Podemos crear todas las marcas que necesitemos y al pulsar sobre ellas si abrirá una ficha con todos los datos de la posición.


Aquí tienes los programas para probar el módulo GY-NEO6MV2 GPS:

Descargar Geo6MV2 GPS for Android desde GitHub Arduino

Descargar Geo6MV2 for Android desde Play Store Android

Saludos!!!

sábado, 2 de noviembre de 2024

ESP8266 con GPS NEO6MV2 y acelerómetro ADXL345: Mapa en tiempo real

Muy Buenas Arduineros y Arduineras

Ahora si, juntamos los proyectos con el sensor ADXL345 y el sistema GPS con NEO6MV2. Esta unión afecta tanto al microrontrolador ESP8266 tanto como al programa para Python.

Si ya has visto las entradas anteriores, Servidor socket adxl345 Servidor AP GPS NEO6MV2 socket interface hacemos un pequeño resumen.

Son interfaces para comunicar mediante Wi-Fi los sensores arriba descritos. En estas interfaces se muestran los datos de posición de los ejes para el ADXL345 y la telemetría de la señal GPS.

Tipo de conexión:

  • Cliente Se conecta a la red local.
  • Como punto de acceso Nos conectamos directamente al microcontrolador.

Ambas opciones funcionan igual de bien y la latencia dependerá más por la distancia que tengamos con respecto al módulo que por la lectura de los sensores.

En el caso que de que estemos usando un portátil la ventaja para la conexión cliente es que como estamos conectados al router de casa seguiremos teniendo internet. No pasa lo mismo con el modo AP, una vez conectado no tendremos acceso a internet a no ser que estemos usando ethernet.

El modo AP en el ESP8266 será muy útil en exteriores como gracias a su conexión directa con la interfaz.

Tener los datos de latitud y longitud esta bien pero es mucho mejor tener una representación visual del recorrido. Además podemos añadir puntos de control que irán construyendo un perímetro con estas referencias. Para lograr tener el mapa en la interfaz hemos recurrido a la librería de Tom Schimansky TkinterMapView.

TkinterMapView

TkinterMapView es una biblioteca de Python que nos permite crear mapas interactivos dentro de aplicaciones que utilicen la interfaz gráfica de usuario (GUI) de Tkinter. En otras palabras, es una herramienta que te facilita la integración de mapas en tus programas.

Entre sus características destacan:

  • Mostrar mapas: Es su función principal, mostrar mapas basados en mosaicos como los que ofrece OpenStreetMap.

  • Interactuar con el mapa: Los mapas que creas con TkinterMapView son interactivos. Los usuarios pueden hacer zoom, desplazarse y, en algunos casos, buscar ubicaciones específicas.

  • Personalización: Puedes seleccionar entre diferentes proveedores de mapas y capas.

  • Agregar marcadores y overlays: También puedes añadir marcadores para señalar puntos de interés en el mapa y superponer diferentes capas de información, como datos geográficos o imágenes.

  • Facilidad de uso: La biblioteca es relativamente sencilla de usar, especialmente si ya estás familiarizado con Tkinter.

  • Integración con Tkinter: Al ser compatible con Tkinter, puedes combinar los mapas con otros elementos de tu interfaz gráfica.

Alguna de las funciones que más usaras son:

  • set_position - (set_position(x_lat, y_lon) Vamos a la posición dada por las coordenadas de latitud y longitud
  • set_marker - (set_marker(x_lat, y_lon) Crea un marcador en el mapa
  • set_zoom - (set_zoom(int)) Aplica zoom sobre el mapa
  • set_address - (set_address("Almeria", marker=True, text="Spain")) Nos sitúa en la ciudad especificada
  • set_polygon - (self.coordinates, name="Route NEO6MV2") con set_polygon crearemos una cerca que sera delimitada por una lista de puntos de latitud y longitud

Ahora que sabemos la novedad en este programa, este es un ejemplo sencillo de su uso con las funciones "set_position" y "set_marker":


import tkinter
import tkintermapview

# create tkinter window
root_tk = tkinter.Tk()
root_tk.geometry(f"{1000}x{700}")
root_tk.title("map_view_simple_example.py")

# Crea el widget con el mapa
map_widget = tkintermapview.TkinterMapView(root_tk, width=1000, height=700, corner_radius=0)
map_widget.pack(fill="both", expand=True)


# Establece la posición por latitud y longitud y aplica zoon 
map_widget.set_position(37.179790, -1.821792, marker=False)  # Garrucha, Almería 
map_widget.set_zoom(17)

# Establece la posición actual según su dirección
# map_widget.set_address("Garrucha, Almeria", marker=False)

def marker_click(marker):
    print(f"marker clicked - text: {marker.text}  position: {marker.position}")

# Establece un marcador, puede tener un color personalizado y comando "onClick"
marker_2 = map_widget.set_marker(37.179790, -1.821792, text="Garrucha Ayto.", command=marker_click)


root_tk.mainloop()



Con esta pequeña introducción a la librería TkinterMapView y como es prácticamente la única función añadida en el programa, ahora si, veamos la interfaz:

Para dar un toque diferente a la interz, le he aplicado una capa visual llamado "Forest ttk theme" alojado en GitHub para romper un poco con la monotonía del apartado visual por defecto.


Como se puede apreciar, la parte superior es la dedicada al sensor ADXL345 y la parte inferior para el GPS NEO6MV2 junto con el mapa.

Para mostrar el mapa necesitamos tener conexión a internet, como explicaba más arriba esto no funcionará si estamos en el modo AP.

Para usar el programa en modo AP no tendremos que realizar ningún cambio en la interfaz, pero si tener cargado el programa adecuado en el microcontrolador.

Conexión ESP8266 como cliente:

Para conectarnos en modo cliente tenemos que averiguar la IP que nos asigna el router, esta información nos la proporciona el programa y la podemos ver en el monitor serial.

Conexión ESP8266 como AP:

Por otra parte si nos conectamos en modo AP, primero tenemos que conectarnos a la red: "gpsServer" y su contraseña es "gps12345". Una vez estemos conectados al ESP8266, la dirección IP por defecto para el modo AP es 192.168.4.1

Espero que os guste y si estáis aprendiendo a programar en Python os puede ayudar con vuestros proyectos Aquí teneís otros enlaces de este blog relacionados con Python:

Programa de ejemplo de este articulo en GitHub

Otras interfaces:

Interfaz de ejemplo con Tkinter de este articulo en GitHub

ADXL Socket Server en GitHub


Aquí tienes otros enlaces de este blog relacionados con Python:

Tienes este y otros proyectos en mi repositorio de GitHub

Espero que os guste el contenido, Saludos!!