Skip to content

Funcionamiento del GPS

Para incluir la funcionalidad del GPS en el dispositivo se utilizará el módulo GPS de Libelium que posee el circutio integrado A1037-A:

Módulo con el A1037-A

También disponen de otro módulo GPS pero que lleva el circuito integrado A1080-B. Es el siguiente, para que se pueda apreciar la diferencia:

Módulo con el A1080-B

En ambos casos es necesario conectarle una antena externa.

El módulo se comunica con el arduino por puerto serie a 4800 bps. Se ha de conectar en los pines 0 y 1, pero como éstos estarán ocupados por el XBee, se utilizarán los pines 8 y 9. Por ello, la lectura se realizará simulando un puerto serie por software. Para leer los datos del GPS se utilizará la libería de Libelium (descargar la mía modificada) creada por D. Cuartielles, que ya provee las funciones necesarias para la comunicación serie por el puerto 8 y 9. A pesar de que las funciones de envío y recepción por el puerto serie virtual son bloqueantes, en nuestro caso es suficiente dado que sólo leeremos los datos cuando nosotros queramos (no necesitamos recibirlos asíncronamente). Además, dado que la lectura del acelerómetro y la comunicación por XBee son asíncronas, no debería haber ningún tipo de problema al utilizar el módulo GPS.

Librería de Libelium

Para instalar la librería de Libelium simplemente hay que copiar la carpeta /LB_GPS del .zip descargado en /arduino/libraries, y de este modo estarán disponible automáticamente en el editor de arduino tanto la librería como los ejemplos.

Librería GPS disponible

Ejemplos de la librería GPS disponibles

La librería de Libelium declara un objeto global GPS cuya clase es LB_GPS.

El GPS se ha de inicializar mediante la función init(), a la que opcionalmente le podemos pasar unas coordenadas y la hora para realizar un “inicio en templado”.

El modo de comunicación con el arduino se configuraría mediante setCommMode(). Las opciones son: por software o por hardware, pero actualmente el módulo sólo funciona por software. Los pines de comunicación se configuran en el fichero LB_GPS.h:

// GPS Software Serial pins
#define GPS_RX 9    // default RX pin for the software serial method
#define GPS_TX 8    // default TX pin for the software serial method

Se puede reiniciar, apagar y dormir el GPS mediante la función setGPSMode(). Cuando se reinicia, el modo de reinicio puede ser en “caliente”, “templado” o “frío”:

  • Inicio en caliente (Hot Start): El receptor GPS recuerda su última posición calculada, qué satélites estaban a la vista, el almanaque utilizado y la hora UTC. Realiza un reset y trata de encontrar los satélites y calcular la nueva posición en base a su información previa. Es el método más rápido de calcular la nueva posición.
  • Inicio en templado (Warm Start): El receptor GPS recuerda su última posición calculada, el almanaque usado y la hora UTC, pero desconoce qué satélites estaban a la vista (efemérides). Realiza el reset y trata de detectar la señal de los satélites y calcular la nueva posición. El receptor tiene una idea general de qué satélites buscar porque conoce su última posición y el almanaque ayuda a identificar qué satélites son visibles en el cielo. Se tarda más que con un inicio en caliente, pero no tanto como en frío.
  • Inicio en frío (Cold Start): El receptor descarta toda la información almacenada, y tras el reseteo trata de encontrar los satélites y calcular su posición. Es el método que más tarda porque no tiene nada de información y el receptor trata de leer información de todos los satélites mediante polling, cosa que lleva mucho más tiempo que saber qué satélites buscar. Este método puede llevar hasta 20 minutos.

La librería no permite cambiar el modo de reinicio, y simplemente presupone que el módulo llevará a cabo un reinicio en caliente. Al establecer el modo ON mediante setGPSMode(), lo que se realiza es un simple reset. Mirar el apartado de bugs y modificaciones más abajo para ver el código añadido.

Para leer la información de posición hay 3 maneras:

  • Leer la información de caché del objeto, mediante los atributos públicos (char*)coordinates, (float) latitude, (float) longitude, (float) speed, (float) altitude, (float) course, que guardan el valor de la última lectura.
  • Leer la información llamando previamente a getLocation(), que actualizará las variables anteriores. Al mismo tiempo, la función dataValid() indicará si los datos leídos mediante getLocation() eran válidos y por lo tanto los atributos han sido actualizados, o no.
  • Establecer el tipo de mensajes a recibir con GPS.setSentences(), leer un mensaje con GPS.getRaw() y parsearlo con GPS.GPSStringExplode(GPS.inBuffer,’,’) de manear que los tokens estarán en el array GPS.arguments[].

Bugs

Atención: la versión 01a de la librería tiene un bug en la defición de la clase , por lo que es recomendable editar el fichero LB_GPS.h y definir el atributo arguments de la siguiente manera:

char arguments[21][12];

El motivo es que inicialmente está definido erróneamente como arguments[13][11] ya que en el firmware A1037-A del módulo GPS de Tyco las sentencias NMEA pueden constar de hasta 21 elementos (el mensaje GGA hasta 15+checksum, pero el GSV consta de 21), y la longitud máxima de cada uno puede ser hasta de 11 caracteres (parámetro 4 del mensaje GGA). Hay que tener en cuenta que también hay que almacenar el byte de fin de cadena.

Atención: la versión 01a de la librería tiene un bug en la función LB_GPS::GPSStringExplode(const char* str, char separator), por lo que es recomendable editar el fichero LB_GPS.cpp y sustituir dicha función por la siguiente:

void LB_GPS::GPSStringExplode(const char* str, char separator){
  int count = 0, index = 0;

  while (*str!=''){   //while(*str!=(char)0){
  if (*str != separator)
  {
    arguments[index][count++] = *str;
  }
  else {
    arguments[index][count] = '';   // arguments[index][count]=(char)0;
    count=0 ;
    index++ ;
  }
  str++;
  }
}

Atención: en la versión 01a, la función LB_GPS::getRaw() no tiene en cuenta que el checksum en los mensajes recibidos es opcional, lo que podría ocasionar que distintos mensajes recibidos se encadenen como si fuera el mismo.

Configuración del modo de reinicio:

La librería no permite establecer el modo de reinicio, así que se han añadido las funciones setWakeMode() y getWakeMode(), y se ha modificado la función setGPSMode():

// set wake mode (HOT, WARM, COLD)
void LB_GPS::setWakeMode(uint8_t mode)
{
  wakeMode = mode ;
}
// get wake mode (HOT, WARM, COLD)
uint8_t LB_GPS::getWakeMode(void)
{
  return wakeMode ;
}
// define the power mode for the device
void LB_GPS::setGPSMode(uint8_t mode)
{
  pwrMode = mode;

 // set the GPS in the defined power mode
  switch (pwrMode)
  {
    case GPS_ON:
      // here there are many different ways of
      // calling the GPS up: COLD, HOT, WARM
      switch(wakeMode)
        {
          case HOT: println("$PSTMHOT") ;
            break;
          case WARM: println("$PSTMWARM") ;
            break;
          case COLD: println("$PSTMCOLD") ;
            break;
          default:
            println("$PSTMGPSRESTART");
        }
      break;

    case GPS_OFF:
      // stop the GPS
      println("$PSTMSTOP");
      break;

    case GPS_SLEEP:
      // sleep and hibernate are the same for us
      // we just call standby
      println("$PSTMSTBY");
      break;

    case GPS_HIBERNATE:
      // sleep and hibernate are the same for us
      // we just call standby
      println("$PSTMSTBY");
      break;

    default:
      break;
  }
}

Completando la librería

Se han implementado las siguientes funciones:

getFirmwareInfo() devuelve la información del firmware que está en el módulo GPS:

const char* LB_GPS::getFirmwareInfo()
{
  println("$PSTMINFOREAD") ;
  getRaw(GPS_BUFFER_SIZE);
  return inBuffer ;
}

En el caso concreto del módulo que estamos utilizando, la respuesta es:

$PSTMVER,GPSLIB_04.30.03+PAL ARM - Jul 28 2006 12:23:26,SW COMMANDS rel.1.0 (Aug 07 2006 09:16:31)*6a

Este dato no se ha obtenido utilizando la función implementada, ya que devuelve basura debido a que la lectura del puerto serie no es asíncrona, y el retardo entre mandar el mensaje y leer la respuesta es demasiado y se pierden bits por el medio.

Soporte de SBAS

La funcionalidad Satellite Based Augmentation Systems permite interpretar las señales de los sistemas WAAS (Wide Area Augmentation System – EEUU, Canadá y Méjico), EGNOS
(European Geostationary Navigation Overlay System – Europa, África y Venezuela) y MSAS (Japón, Australia y Hawaii). Estos sistemas permiten que el GPS adquiera información más rápidamente, simplemente indicando un número de región al módulo.

A pesar de que nuestro módulo posee un firmware que soporta esta funcionalidad, el circuito integrado no lo soporta (deducimos que es posible que, en nuestro caso, lleve uno de los ejemplos X1037-A, y no el de fabricación masiva comercial A1037-A).

Descargar la librería modificada

{ 2 } Comments

  1. Cesar Gonzalez | September 8, 2012 at 2:42 pm | Permalink

    Hola, podrias indicarme donde bajar la libreria, el link esta roto.
    Desde ya muchas gracias

  2. alfonso | September 29, 2012 at 2:40 pm | Permalink

    Hola. Muchas gracias por avisar.
    Ya está corregido el enlace. Como es un enlace a la última versión, he puesto directamente el enlace a todo el código final del proyecto.

Post a Comment

Your email is never published nor shared. Required fields are marked *