GPS con Arduino
Conecta un módulo GPS
Para la realización de éste ejemplo he utilizado un módulo GPS de Parallax que utiliza un interfaz serie. La conexión a establecer para comunicarse con Arduino, según la data sheet del GPS , debe ser una conexión serie asíncrona a 4800 bps (TTL-level interface, 8 data bits, no parity, 1 stop bit, non-inverted).
Figura 1. Módulo GPS de Parallax
El módulo GPS tiene dos modos de funcionamiento en función del valor que introduzcamos por el pin RAW:
- RAW = HIGH –> SMART MODE. Permite escribir comandos al GPS y escuchar la respuesta de este. Es el modo por defecto si el pin RAW se deja desconectado.
- RAW = LOW –> RAW MODE. Modo escucha. El GPS escribe información el puerto serie que debemos interpretar.
En este ejemplo consta de dos partes:
1.- Ejemplo 1: Escucha e interpreta la informaci�n proporcionada por el GPS.
Figura 2. Esquema de conexionado del ejemplo 1.
Código fuente
/*
Ejemplo de conexion de un modulo GPS de Parallax a Arduino
Ejemplo 1: Escucha e interpreta la informacion proporcionada por el GPS.
Igor Gonzaez Martin. 05-04-2007 igor.gonzalez.martin@gmail.com
Lo que hace es interpretar el comando $GPRMC al recibirlo del GPS y sacar el resultado por pantalla.
Ejemplo:
$GPRMC
Recommended minimum specific GPS/Transit data
eg1. $GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62 eg2. $GPRMC,225446,A,4916.45,N,12311.12,W,000.5,054.7,191194,020.3,E*68
225446 Time of fix 22:54:46 UTC A Navigation receiver warning A = Valid position, V = Warning 4916.45,N Latitude 49 deg. 16.45 min. North 12311.12,W Longitude 123 deg. 11.12 min. West 000.5 Speed over ground, Knots 054.7 Course Made Good, degrees true 191194 UTC Date of fix, 19 November 1994 020.3,E Magnetic variation, 20.3 deg. East *68 mandatory checksum
eg3. $GPRMC,220516,A,5133.82,N,00042.24,W,173.8,231.8,130694,004.2,W*70 1 2 3 4 5 6 7 8 9 10 11 12
1 220516 Time Stamp 2 A validity - A-ok, V-invalid 3 5133.82 current Latitude 4 N North/South 5 00042.24 current Longitude 6 W East/West 7 173.8 Speed in knots 8 231.8 True course 9 130694 Date Stamp 10 004.2 Variation 11 W East/West 12 *70 checksum
eg4. for NMEA 0183 version 3.00 active the Mode indicator field is added $GPRMC,hhmmss.ss,A,llll.ll,a,yyyyy.yy,a,x.x,x.x,ddmmyy,x.x,a,m*hh Field # 1 = UTC time of fix 2 = Data status (A=Valid position, V=navigation receiver warning) 3 = Latitude of fix 4 = N or S of longitude 5 = Longitude of fix 6 = E or W of longitude 7 = Speed over ground in knots 8 = Track made good in degrees True 9 = UTC date of fix 10 = Magnetic variation degrees (Easterly var. subtracts from true course) 11 = E or W of magnetic variation 12 = Mode indicator, (A=Autonomous, D=Differential, E=Estimated, N=Data not valid) 13 = Checksum
*/
#include <string.h> #include <ctype.h>
int ledPin = 13; // PIN para test int rxPin = 0; // PIN de TX int txPin = 1; // PIN de TX int byteGPS=-1; char linea[300] = ""; char comandoGPR[7] = "$GPRMC"; int cont=0; int bien=0; int conta=0; int indices[13];
void setup() { pinMode(ledPin, OUTPUT); // Inicializando PIN-es pinMode(rxPin, INPUT); pinMode(txPin, OUTPUT); Serial.begin(4800); for (int i=0;i<300;i++){ // Incializaci�n del buffer de recepci�n linea[i]=' '; } }
void loop() { digitalWrite(ledPin, HIGH); byteGPS=Serial.read(); // Lee un byte del puerto serie if (byteGPS == -1) { // Comprueba si hay algo en el buffer del puerto serie delay(100); } else { linea[conta]=byteGPS; // Si hay algo lo escribe en el buffer de recepci�n. conta++; Serial.print(byteGPS); if (byteGPS==13){ // Si el byte recibido es 13 = Fin de comando digitalWrite(ledPin, LOW); cont=0; bien=0; for (int i=1;i<7;i++){ // Comprueba si el comando recibido es un &GPRMC if (linea[i]==comandoGPR[i-1]){ bien++; } } if(bien==6){ // Si lo es ... procesa la info del comando ... for (int i=0;i<300;i++){ if (linea[i]==','){ // ... busca la posici�n de las "," indices[cont]=i; cont++; } if (linea[i]=='*'){ // ... y del "*" indices[12]=i; cont++; } } Serial.println(""); // ... y escribe la info en el puerto serie. Serial.println(""); Serial.println("---------------"); for (int i=0;i<12;i++){ switch(i){ case 0 :Serial.print("Hora en UTC (HhMmSs): ");break; case 1 :Serial.print("Estado (A=OK,V=KO): ");break; case 2 :Serial.print("Latitud: ");break; case 3 :Serial.print("Direccion (N/S): ");break; case 4 :Serial.print("Longitud: ");break; case 5 :Serial.print("Direccion (E/W): ");break; case 6 :Serial.print("Velocidad sobre superficie (nudos): ");break; case 7 :Serial.print("Direccion del movimiento (grados): ");break; case 8 :Serial.print("Fecha en UTC (DdMmAa): ");break; case 9 :Serial.print("Grados de variacion magnetica: ");break; case 10 :Serial.print("Variacion magnetica (E/W): ");break; case 11 :Serial.print("Modo: ");break; case 12 :Serial.print("Checksum: ");break; } for (int j=indices[i];j<(indices[i+1]-1);j++){ Serial.print(linea[j+1]); } Serial.println(""); } Serial.println("---------------"); } conta=0; // Reinicia el contador de posici�n en el buffer for (int i=0;i<300;i++){ // de recepci�n y el propio buffer linea[i]=' '; } } } }
Si probamos este código, y todo va bien, en el monitor serie deberíamos visualizar información parecida a esta:
A: POSICIÓN NO VÁLIDA: La luz del GPS parpadea.
... ...
$GPGGA,154653,4428.2011,N,00440.5161,W,0,00,,-00044.7,M,051.6,M,,*6C $GPGSA,A,1,,,,,,,,,,,,,,,*1E $GPGSV,3,1,10,02,50,290,003,10,25,24,045,35,27,56,145,00,,,,,,,,*78 $GPRMC,154653,V,4428.2011,N,00440.5161,W,000.5,342.8,050407,,,N*7F
--------------- Hora en UTC (HhMmSs): 154653 Estado (A=OK,V=KO): V Latitud: 4428.2011 Direccion (N/S): N Longitud: 00440.5161 Direccion (E/W): W Velocidad sobre superficie (nudos): 000.5 Direccion del movimiento (grados): 342.8 Fecha en UTC (DdMmAa): 050407 Grados de variacion magnetica: Variacion magnetica (E/W): Modo: N ---------------
... ...
B: POSICIÓN VÁLIDA: El GPS tiene la luz fija.
... ...
$GPGGA,154654,4428.2011,N,00440.5161,W,0,00,,-00044.7,M,051.6,M,,*6B $GPGSA,A,1,,,,,,,,,,,,,,,*1E $GPGSV,3,1,10,02,50,290,00 $GPGGA,154655,4328.1874,N,00340.5185,W,1,03,08.5,-00044.7,M,051.6,M,,*79 $GPGSA,A,2,13,23,25,,,,,,,,,,08.5,08.5,00.9*0E $GPGSV,3,1,10,02,50,290,26,04,60,210,26,08,33,173,29,10,21,296,00*7E $GPGSV,3,2,10,13,58,044,34,16,03,035,00,20,02,109,00,23,26,057,34*7B $GPGSV,3,3,10,25,24,045,35,27,56,145,27,,,,,,,,*7D $GPRMC,154655,A,4428.1874,N,00440.5185,W,000.7,000.0,050407,,,A*6C
--------------- Hora en UTC (HhMmSs): 154655 Estado (A=OK,V=KO): A Latitud: 4428.1874 Direccion (N/S): N Longitud: 00440.5185 Direccion (E/W): W Velocidad sobre superficie (nudos): 000.7 Direccion del movimiento (grados): 000.0 Fecha en UTC (DdMmAa): 050407 Grados de variacion magnetica: Variacion magnetica (E/W): Modo: A ---------------
... ... Fuente: http://www.arduino.cc/es_old/Tutoriales/GPS
Tuitear 8.044 Veces leído 3 comentarios |
18 diciembre 2010 en Electronica | tags: Electronica |
Hola porque hay una posocion valida y la otra no?? de que depende este tipo de situaciones??
No entiendo tu pregunta, puedes especificar mejor?. También puedes consultar la pagina original del post.
Cuando el receptor de gps no accede a los datos satelitales por estar en el interior de un edificio o bajo un techo, por ejemplo, los datos que el dispositivo genera pueden no ser validos o estar equivocados. El mismo receptor nos proporciona esta informacion con el caracter “A” (valido o “V” no valido. Si las condiciones de recepcion son optimas, lo mas normal es recibir siempre “A”.