La importancia de la geolocalización dentro de los proyectos electrónicos relacionados a la captación de data por medio de sensores van ligados a la necesidad de conocer el desplazamiento en detalle dentro de unas coordenadas y las mediciones respectivas sobre puntos específicos. Estas lecturas pueden representar elementos críticos para la toma de decisiones sobre algún particular, por ejemplo, la determinación de niveles de fuego que puedan generar un incendio en algún plano forestal específico.

Es por ello que dentro de nuestras programaciones es importante la generación de un código lo suficientemente preciso en sus cáculos y óptimo en la capacidad global de procesamiento, en combinación con el hardware adecuado para la obtención de la información necesaria de un punto determinado. En este caso, trataremos con detalle uno de los dispositivos del mercado más completos (y también más costosos) con el cual podemos llevar a cabo esta tarea haciendo uso de la plataforma Arduino, en este caso específico con el modelo MEGA 2560, acompañado de una antena adicional para el mejoramiento de la captación de información. Se trata del Shield GPS Ublox NEO-6M.

El módulo en cuestión está basado en el receptor GPS de uBlox NEO-6M, compatible con las placas Arduino en general. Los pines regulares de recepción/transmisión (RX, TX) se conectan a D0-D7 del arduino, además posee soporte de software para la interfaz SerialPort y capacidad para el uso de una tarjeta MicroSD (en Tecno-Fly la hemos probado hasta con 32GB).

Las lecturas GPS las otorga a través del puerto serie, el cual puede ser usada tanto desde el SoftwareSerial (caso Arduino UNO) como cualquiera de los puertos seriales MEGA/DUE. Funciona sin inconvenientes con los voltajes de 3.3V/5V, lo cual permite su compatibilidad con el resto de las placas, aunque si bien su forma le permite estar unido a los Arduinos UNO, MEGA y DUE.

Un vistazo del shield:

Shield GPS Ublox NEO-6M

Desde el punto de vista de software no se presentan inconvenientes, ya que hacemos uso de la libreria TinyGPS++ disponible amablemente desde el siguiente enlace para su descarga:

http://arduiniana.org/libraries/tinygpsplus/

 

La disposición a nivel de código ya optimizado para su uso es la siguiente:

// TECNO-FLY C.A
// CÓDIGO PARA PRUEBAS/USO DEL MÓDULO SHIELD GPS UBLOX NEO 6M.
// CONEXIONES DE HARDWARE: (EN ESTE CASO PARTICULAR CON EL ARDUINO MEGA 2650 R3).
// - PINES REGULADORES DE RECEPCIÓN/TRANSMISIÓN (UART_RX,UART_TX) (3,4).
// - CONEXIÓN SERIAL1 CON PINES: (D7 TOMADO COMO ELEMENTO PARALELO DE UART_RX. RECORDAR SIEMPRE TOMAR EL PARALELO).  
//   * UART_RX ==> RX1 PIN 19 ARDUINO MEGA. 
//   * D7      ==> TX1 PIN 18 ARDUINO MEGA.   
/////////////////////////////////////////////////////////////////// SEPARACIÓN.
// LIBRERIAS DE USO:                                             // MENSAJE. 
#include <TinyGPS++.h>                                           // ESTABLECIMIENTO DE LA LIBRERIA PARA EL USO DEL SHIELD GPS UBLOX NEO 6M.
/////////////////////////////////////////////////////////////////// SEPARACIÓN.
TinyGPSPlus gps;                                                 // DECLARACIÓN DE VARIABLE PARA EL GPS.
/////////////////////////////////////////////////////////////////// SEPARACIÓN.
void setup()                                                     // APERTURA DEL SETUP.
{                                                                // LLAVE DE APERTURA.
   Serial.begin(9600);                                           // INICIALIZACIÓN DEL PUERTO SERIAL, PUES MOSTRAREMOS EN EL COMPUTADOR.
   Serial1.begin(9600);                                          // INICIALIZACIÓN DEL PUERTO SERIAL1, DONDE HEMOS HECHO ENLACE DE CONEXIÓN CON EL SHIELD GPS.
}                                                                // LLAVE DE CIERRE, FIN DEL SETUP.
/////////////////////////////////////////////////////////////////// SEPARACIÓN.
void loop()                                                      // INICIO DEL LOOP.
// EN EL LOOP VAMOS A EJECUTAR EL CÓDIGO DE COMPROBACIÓN QUE     // MENSAJE. 
// PERMITA CONOCER SI EL GPS SE ENCUENTRA ACTIVO, EN CASO DE     // MENSAJE.
// QUE SEA ASÍ ENTONCES LLAMA A LA FUNCIÓN QUE MUESTRA LOS       // MENSAJE.
// VALORES DE LECTURA.                                           // MENSAJE.
{                                                                // LLAVE DE APERTURA.
                                                                 // ESPACIO.
  while (Serial1.available() > 0)                                // MIENTRAS SE ENCUENTRE DISPONIBLE EL CANAL SERIAL1, ENLACE DEL SHIELD...
    if (gps.encode(Serial1.read()))                              // SI LAS LECTURAS SE ENCUENTRAS DISPONIBLES ENTONCES...
      muestraLecturaGPS();                                       // LLAMA A LA FUNCIÓN DE LECTURA DEL GPS.
                                                                 // ESPACIO.
  if (millis() > 30000 && gps.charsProcessed() < 10)             // TEST DE OPERATIVIDAD DEL GPS.
  {                                                              // LLAVE DE APERTURA.
    Serial.println(F("GPS NO DETECTADO, VERIFICAR CONEXIONES")); // MUESTRA POR CANAL SERIAL EN CASO DE QUE NO HAYA DETECCIÓN DEL GPS.
    while(true);                                                 // CONTINUE MIENTRAS SE MANTENGA LA CONDICIÓN. 
  }                                                              // LLAVE DE CIERRE.  
}                                                                // LLAVE DE CIERRE.
////////////////////////////////////////////////////////////////////////////////////////////////////// SEPARACIÓN.      
void muestraLecturaGPS()                                                                            // FUNCIÓN DE LECTURA DE DATOS. 
// POR RAZONES DE EJEMPLO SE MUESTRA POR CANAL SERIAL, PERO ES                                      // MENSAJE.
// PERFECTAMENTE FACTIBLE MOSTRAR VALORES EN OTRAS VIAS, YA                                         // MENSAJE. 
// BIEN SEAN PANTALLAS LCD, VÍA WEB, APLICACIONES MÓVILES AL                                        // MENSAJE.
// COMBINARLO CON ALGÚN ESP8266, ENTRE OTROS.                                                       // MENSAJE.
{                                                                                                   // LLAVE DE APERTURA.
  Serial.print(F("UBICACION: "));                                                                   // MUESTRO POR CANAL SERIAL. 
  if (gps.location.isValid())                                                                       // ¿ES VÁLIDA LA LOCALIZACIÓN? 
  {                                                                                                 // EN CASO DE QUE SI ENTONCES...
    Serial.print("LATITUD: ");                                                                      // LATITUD ACTUAL. 
    Serial.print(gps.location.lat(), 6);                                                            // LATITUD ACTUAL.
    Serial.print("         , " );                                                                   // SEPARACIÓN. 
    Serial.print("LONGITUD: ");                                                                     // LONGITUD ACTUAL.
    Serial.print(gps.location.lng(), 6);                                                            // LONGITUD ACTUAL.
    Serial.println("");                                                                             // PANTALLA SIGUIENTE.   
    Serial.print("//////////////////////////////////////////////////////////////////////////////"); // SEPARACIÓN.  
    delay(1000);                                                                                    // RETARDO PARA MUESTREO.
  }                                                                                                 // LLAVE DE CIERRE.
////////////////////////////////////////////////////////////////////////////////////////////////////// SEPARACIÓN.   
  else                                                                                              // EN CASO CONTRARIO.
  {                                                                                                 // LLAVE DE APERTURA.
    Serial.print(F("EN ESPERA."));                                                                  // MENSAJE DE ESPERA.
  }                                                                                                 // CIERRE, FIN DE CASO CONTRARIO.
////////////////////////////////////////////////////////////////////////////////////////////////////// SEPARACIÓN.  
  Serial.print(F("  FECHA/HORA (GMT): "));                                                          // INDICACIÓN DE MUESTRA DE HORA EN FORMATO GMT.
  if (gps.date.isValid())                                                                           // ES VÁLIDO EL DATO GPS...
  {                                                                                                 // LLAVE DE APERTURA.
    Serial.print(gps.date.month());                                                                 // MES.
    Serial.print(F("/"));                                                                           //
    Serial.print(gps.date.day());                                                                   // DIA.
    Serial.print(F("/"));                                                                           // 
    Serial.print(gps.date.year());                                                                  // AÑO.
  }                                                                                                 // CIERRE, FIN DE DATOS VÁLIDOS.
  else                                                                                              // EN CASO CONTRARIO.
  {                                                                                                 // LLAVE DE APERTURA.
    Serial.print(F("EN ESPERA."));                                                                  // MENSAJE DE ESPERA.
  }                                                                                                 // CIERRE.
////////////////////////////////////////////////////////////////////////////////////////////////////// SEPARACIÓN.  
  Serial.print(F(" "));                                                                             // 
  if (gps.time.isValid())                                                                           // VISUALIZACIÓN DE LA HORA. HH/MM/SS/CS.
  {                                                                                                 // LLAVE DE APERTURA.
    if (gps.time.hour() < 10) Serial.print(F("0"));                                                 // HH
    Serial.print(gps.time.hour());                                                                  // HH
    Serial.print(F(":"));                                                                           //
    if (gps.time.minute() < 10) Serial.print(F("0"));                                               // MM
    Serial.print(gps.time.minute());                                                                // MM
    Serial.print(F(":"));                                                                           //
    if (gps.time.second() < 10) Serial.print(F("0"));                                               // SS
    Serial.print(gps.time.second());                                                                // SS
    Serial.print(F("."));                                                                           //
    if (gps.time.centisecond() < 10) Serial.print(F("0"));                                          // CS
    Serial.print(gps.time.centisecond());                                                           // CS
  }                                                                                                 // FIN DE VISUALIZACIÓN DEL TIEMPO.
  else                                                                                              // DE LO CONTRARIO...
  {                                                                                                 // 
    Serial.print(F("EN ESPERA."));                                                                  // EN ESPERA MIENTRAS VALIDA GPS.
  }                                                                                                 //
////////////////////////////////////////////////////////////////////////////////////////////////////// SEPARACIÓN.  
  Serial.println();                                                                                 // LINEA SIGUIENTE.
}                                                                                                   // FIN.
////////////////////////////////////////////////////////////////////////////////////////////////////// FIN DE FUNCIÓN.    

Código comentado de uso para el Shield GPS Ublox NEO-6M

 

Otorgando el siguiente resultado:

Salida por Serial1 para el Shield GPS Ublox NEO-6M usando un Arduino MEGA 2560 R3

 

Perfecto, hemos obtenido los valores respectivos, que podemos combinar con algún sensor de temperatura/humedad y obtener una estación meteorológica completa (mejor si también le agregamos presión barométrica/altitud con el BMP085 del artículo anterior), también combinables con sensores de vuelo para un UAV (magnetómetros, giroscopios, acelerómetros, entre otros); sin embargo aún no conocemos algo que el fabricante ha pasado por alto: Conexiones del hardware. Lamentablemente, este es un punto no difundido y que, experimentalmente, es necesario obtener ya que no basta con solo ensamblar el shield con la placa, sino que es necesario su conexión serial.

Sencillo, sin mucha complicación. Al principio comentabamos que los pines regulares de recepción / transmisión (RX, TX) se conectan a D0-D7 del arduino, ahora agregamos que deben estar en paralelo, es decir, si tomamo D7 como pin de referencia para TX1 (en el ejemplo usamos el puerto Serial1, pero puede ser cualquier otro de los disponibles) entonces para RX1 tomamos su paralelo  UART_RX. Esto tiene su lógica y razón de ser, pero en vez de comentarlo lo dejamos de tarea para el lector.

A continuación un par de imágenes que muestran lo que hemos narrado en el párrafo anterior:

 

UART_RX ==> RX1 PIN 19 ARDUINO MEGA /  D7 ==> TX1 PIN 18 ARDUINO MEGA

 

Vista superior de conexión paralela

Bien, ya con ello podemos dar uso al shield para los proyectos que tenemos planteados. En lo posible, se recomienda el uso de antenas potenciadoras de señal, las cuales permiten mayor exactitud en la medición latitud/longitud, otorgando así ubicaciones precisas en metros:

 

Shield GPS Ublox NEO-6M con antena adicional

 

Si bien el costo es alto en relación a otros módulos GPS, las opciones que nos entrega en cuanto a la disposición de ranura SD, posibilidad de dos antenas (una de ellas puede estar a distancia prudencial del resto del circuito, lo cual es conveniente para la recepción de señal) y acoplamiento con las placas hacen de este shield una opción a considerar.

En un futuro artículo estaremos comentando su posibilidad de uso con sensores adicionales, así como la transmisión de los valores obtenidos por medio de transceivers.