Go Down

Topic: [SOLUCIONADO] Elección de GPS (Read 4018 times) previous topic - next topic

_Manu_

Mar 22, 2016, 10:27 am Last Edit: Jul 25, 2016, 10:47 pm by Hector_A
Hola gracias por leer mi consulta.
Voy a realizar un proyecto de adquisición de datos el cual también capture la posición GPS en el momento de realizar las mediciones de ciertas entradas analógicas.
He pensado en usar Arduino Yun ya que tiene almacenamiento SD y puedo acceder a los datos mediante una red creada por el propio Yun para obtener los datos con más rapidez.
La duda la tengo en la elección del GPS, estoy barajando estos dos:

Ublox NEO-6M Uart/IIC GPS

Receptor GPS EM-506 (Shield:Arduino GPS Shield)

Quería saber si estos GPS son compatibles con Arduino Yun.
Gracias
Un saludo.

surbyte

#1
Mar 22, 2016, 01:22 pm Last Edit: Mar 22, 2016, 01:23 pm by surbyte
cualquiera que tenga salida Serie TTL es compatible con YUN, revisa los niveles Seriales si son 5 o 3.3V para compatiblizar con el YUN o tendras que usar adaptadores de niveles.
Te aclaro, no los he mirado porque no has puesto links.
Te dejo la tarea a ti.

_Manu_

Muchas gracias por la respuesta. El Modelo GPS EM-506 en su datasheet me pone claramente que que la salida tiene nivel  TTL (oV-3.3V) así que este no habría problema.

El modelo Ublox NEO-6M Uart/IIC GPS he visto su datasheet y no pone explícitamente que la salida sea TTL, pone:

Serial and I/O Voltages 2.7 - 3.6 V (NEO-6Q/6M)
1.75 - 2.0 V (NEO-6G)

Pero supongo que también vale ya que la salida serial es entre 2.7-3.6 V

Mi nivel de uso de Arduino es bajo solo he trabajado con entradas digitales y analógicas, nunca he trabajado con shields ni comunicación entre Arduinos, por ello me gustaría saber como mirar si es compatible la conexión de la Shield GPS, con el Yun, aparte  como puedo saber si la librería TinyGPS es compatible con el modelo Ublox o si tendría que buscar otra si uso este GPS, el modelo GPS EM-506  si que es compatible he visto un tutorial en bricogeek y parece que va muy bien.
Otra duda es como puedo saber si la Shield Arduino GPS Shield es compatible también con el modelo Ublox, ¿Si tiene el mismo conector es compatible?.

Os dejo los enlaces de los GPS y la Shield.
GPS EM-506

Ublox NEO-6M Uart

Arduino GPS Shield


Gracias por la ayuda.

Un saludo.

_Manu_

Tengo otra pregunta, ¿Es necesario una shield para conectar el GPS al Arduino o solo se usa por comodidad?.

Un saludo.

surbyte

NO es necesario. 
Tu puedes usar cualquier GPS que tenga salida Serial (algunos no son con salida TTL y tienen RS232 lo que requerirá tener RS232 en tu arduino).

_Manu_

Vale gracias por la respuesta, lo mas seguro es que coja  el EM-506, seguro que os tendré que ir preguntando las dudas que me vayan saliendo.
Un saludo.

_Manu_

#6
Apr 16, 2016, 10:59 am Last Edit: Apr 16, 2016, 11:09 am by _Manu_
Hola, lo primero no sabía si seguir aquí o abrir un nuevo post, si eso me decís. Ya he conseguido el GPS EM506, como esperaba no ha sido conectar y que funcionara, por eso os pido una ayuda.
Todavía no me han proporcionado el Yun por lo que estoy probando con un mega de momento.Ahora mismo no encuentro el post pero en este foro había un usuario que usaba el Mega y el EM406, este es código( He cambiado el pin 2 y el 3 por el 0 y el 1 respectivamente ya que son los RX0 y TX0 de mi Arduino. ¿Es correcto?:

Code: [Select]

#include <SoftwareSerial.h>
#include <TinyGPS.h>

/* This sample code demonstrates the normal use of a TinyGPS object.
   It requires the use of NewSoftSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 2(rx) and 3(tx).
*/

TinyGPS gps;
SoftwareSerial nss(0, 1);
 
void gpsdump(TinyGPS &gps);
bool feedgps();
void printFloat(double f, int digits = 2);

void setup()
{

  Serial.begin(115200);
  nss.begin(4800);
 
  Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version());
  Serial.println("by Mikal Hart");
  Serial.println();
  Serial.print("Sizeof(gpsobject) = "); Serial.println(sizeof(TinyGPS));
  Serial.println();
}

void loop()
{
  bool newdata = false;
  unsigned long start = millis();

  // Every 5 seconds we print an update
  while (millis() - start < 5000)
  {
    if (feedgps())
      newdata = true;
  }
 
  if (newdata)
  {
    Serial.println("Acquired Data");
    Serial.println("-------------");
    gpsdump(gps);
    Serial.println("-------------");
    Serial.println();
  }
}

void printFloat(double number, int digits)
{
  // Handle negative numbers
  if (number < 0.0)
  {
     Serial.print('-');
     number = -number;
  }

  // Round correctly so that print(1.999, 2) prints as "2.00"
  double rounding = 0.5;
  for (uint8_t i=0; i<digits; ++i)
    rounding /= 10.0;
 
  number += rounding;

  // Extract the integer part of the number and print it
  unsigned long int_part = (unsigned long)number;
  double remainder = number - (double)int_part;
  Serial.print(int_part);

  // Print the decimal point, but only if there are digits beyond
  if (digits > 0)
    Serial.print(".");

  // Extract digits from the remainder one at a time
  while (digits-- > 0)
  {
    remainder *= 10.0;
    int toPrint = int(remainder);
    Serial.print(toPrint);
    remainder -= toPrint;
  }
}

void gpsdump(TinyGPS &gps)
{
  long lat, lon;
  float flat, flon;
  unsigned long age, date, time, chars;
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned short sentences, failed;

  gps.get_position(&lat, &lon, &age);
  Serial.print("Lat/Long(10^-5 deg): "); Serial.print(lat); Serial.print(", "); Serial.print(lon);
  Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");
 
  feedgps(); // If we don't feed the gps during this long routine, we may drop characters and get checksum errors

  gps.f_get_position(&flat, &flon, &age);
  Serial.print("Lat/Long(float): "); printFloat(flat, 5); Serial.print(", "); printFloat(flon, 5);
  Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");

  feedgps();

  gps.get_datetime(&date, &time, &age);
  Serial.print("Date(ddmmyy): "); Serial.print(date); Serial.print(" Time(hhmmsscc): "); Serial.print(time);
  Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");

  feedgps();

  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  Serial.print("Date: "); Serial.print(static_cast<int>(month)); Serial.print("/"); Serial.print(static_cast<int>(day)); Serial.print("/"); Serial.print(year);
  Serial.print("  Time: "); Serial.print(static_cast<int>(hour)); Serial.print(":"); Serial.print(static_cast<int>(minute)); Serial.print(":"); Serial.print(static_cast<int>(second)); Serial.print("."); Serial.print(static_cast<int>(hundredths));
  Serial.print("  Fix age: ");  Serial.print(age); Serial.println("ms.");
 
  feedgps();

  Serial.print("Alt(cm): "); Serial.print(gps.altitude()); Serial.print(" Course(10^-2 deg): "); Serial.print(gps.course()); Serial.print(" Speed(10^-2 knots): "); Serial.println(gps.speed());
  Serial.print("Alt(float): "); printFloat(gps.f_altitude()); Serial.print(" Course(float): "); printFloat(gps.f_course()); Serial.println();
  Serial.print("Speed(knots): "); printFloat(gps.f_speed_knots()); Serial.print(" (mph): ");  printFloat(gps.f_speed_mph());
  Serial.print(" (mps): "); printFloat(gps.f_speed_mps()); Serial.print(" (kmph): "); printFloat(gps.f_speed_kmph()); Serial.println();

  feedgps();

  gps.stats(&chars, &sentences, &failed);
  Serial.print("Stats: characters: "); Serial.print(chars); Serial.print(" sentences: "); Serial.print(sentences); Serial.print(" failed checksum: "); Serial.println(failed);
}
 
bool feedgps()
{
  while (nss.available())
  {
    if (gps.encode(nss.read()))
      return true;
  }
  return false;
}


Como tenía el error de complicación de "WProgram.h" modifiqué la librería  TinyGPS.h y como me seguía dando el mismo error también la librería TinyGPS.cpp. Haciendo esto he conseguido compilarlo, el GPS se me pone en modo Position fixed(LED rojo parpadeando). Abro el monitor serie (4800 Baudios)y no me aparece lo que tiene que aparecer cada vez que cierro el monitor serie y lo vuelvo abrir me aparece símbolos y letras sin sentido solo una o dos lineas, como este caso:

 
Code: [Select]
$GPGGA,084707.000,4219.84eÃ
Por lo que veo en el código tienen que salir mensajes como Date Time Speed....
¿Que puede haber mal?
PD: ¿La comunicación TX RX es de 0 a 3.3V? porque no he puesto adaptador de tensiones, el GPS usa de 0V a 3.3V.
Gracias.

surbyte

En un dispositivo que tiene un Serial por Hardware usar SoftwareSerial me parece una alternativa solo para cuando no me queden mas puertos fisicos y necesite comunicarme con ellos, pero no puedes asignar pines dedicados a UART en otra por software. Asi que si hubieres elegido otros pines distintos de 0 y 1 eso funcionaría.



Asi que como ves 0 y 1 que tu definiste como SoftwareSerial son en realidad Serial Físico y se usa como Serial1 
Elimina o comenta tu llamado a SoftwareSerial.

y luego remplaza nss por Serial1

_Manu_

Hola gracias por la respuesta. De momento estoy probando con el Arduino Mega hasta que me den el YUN. He hecho lo que me has comentado he cambiado nss por Serial1 y SoftwareSerial lo he comentado.
Code: [Select]

#include <SoftwareSerial.h>
#include <TinyGPS.h>

/* This sample code demonstrates the normal use of a TinyGPS object.
   It requires the use of NewSoftSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 2(rx) and 3(tx).
*/

TinyGPS gps;
//SoftwareSerial nss(0, 1);
 
void gpsdump(TinyGPS &gps);
bool feedgps();
void printFloat(double f, int digits = 2);

void setup()
{

  Serial.begin(115200);
  Serial1.begin(4800);
 
  Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version());
  Serial.println("by Mikal Hart");
  Serial.println();
  Serial.print("Sizeof(gpsobject) = "); Serial.println(sizeof(TinyGPS));
  Serial.println();
}

void loop()
{
  bool newdata = false;
  unsigned long start = millis();

  // Every 5 seconds we print an update
  while (millis() - start < 5000)
  {
    if (feedgps())
      newdata = true;
  }
 
  if (newdata)
  {
    Serial.println("Acquired Data");
    Serial.println("-------------");
    gpsdump(gps);
    Serial.println("-------------");
    Serial.println();
  }
}

void printFloat(double number, int digits)
{
  // Handle negative numbers
  if (number < 0.0)
  {
     Serial.print('-');
     number = -number;
  }

  // Round correctly so that print(1.999, 2) prints as "2.00"
  double rounding = 0.5;
  for (uint8_t i=0; i<digits; ++i)
    rounding /= 10.0;
 
  number += rounding;

  // Extract the integer part of the number and print it
  unsigned long int_part = (unsigned long)number;
  double remainder = number - (double)int_part;
  Serial.print(int_part);

  // Print the decimal point, but only if there are digits beyond
  if (digits > 0)
    Serial.print(".");

  // Extract digits from the remainder one at a time
  while (digits-- > 0)
  {
    remainder *= 10.0;
    int toPrint = int(remainder);
    Serial.print(toPrint);
    remainder -= toPrint;
  }
}

void gpsdump(TinyGPS &gps)
{
  long lat, lon;
  float flat, flon;
  unsigned long age, date, time, chars;
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned short sentences, failed;

  gps.get_position(&lat, &lon, &age);
  Serial.print("Lat/Long(10^-5 deg): "); Serial.print(lat); Serial.print(", "); Serial.print(lon);
  Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");
 
  feedgps(); // If we don't feed the gps during this long routine, we may drop characters and get checksum errors

  gps.f_get_position(&flat, &flon, &age);
  Serial.print("Lat/Long(float): "); printFloat(flat, 5); Serial.print(", "); printFloat(flon, 5);
  Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");

  feedgps();

  gps.get_datetime(&date, &time, &age);
  Serial.print("Date(ddmmyy): "); Serial.print(date); Serial.print(" Time(hhmmsscc): "); Serial.print(time);
  Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");

  feedgps();

  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  Serial.print("Date: "); Serial.print(static_cast<int>(month)); Serial.print("/"); Serial.print(static_cast<int>(day)); Serial.print("/"); Serial.print(year);
  Serial.print("  Time: "); Serial.print(static_cast<int>(hour)); Serial.print(":"); Serial.print(static_cast<int>(minute)); Serial.print(":"); Serial.print(static_cast<int>(second)); Serial.print("."); Serial.print(static_cast<int>(hundredths));
  Serial.print("  Fix age: ");  Serial.print(age); Serial.println("ms.");
 
  feedgps();

  Serial.print("Alt(cm): "); Serial.print(gps.altitude()); Serial.print(" Course(10^-2 deg): "); Serial.print(gps.course()); Serial.print(" Speed(10^-2 knots): "); Serial.println(gps.speed());
  Serial.print("Alt(float): "); printFloat(gps.f_altitude()); Serial.print(" Course(float): "); printFloat(gps.f_course()); Serial.println();
  Serial.print("Speed(knots): "); printFloat(gps.f_speed_knots()); Serial.print(" (mph): ");  printFloat(gps.f_speed_mph());
  Serial.print(" (mps): "); printFloat(gps.f_speed_mps()); Serial.print(" (kmph): "); printFloat(gps.f_speed_kmph()); Serial.println();

  feedgps();

  gps.stats(&chars, &sentences, &failed);
  Serial.print("Stats: characters: "); Serial.print(chars); Serial.print(" sentences: "); Serial.print(sentences); Serial.print(" failed checksum: "); Serial.println(failed);
}
 
bool feedgps()
{
  while (Serial1.available())
  {
    if (gps.encode(Serial1.read()))
      return true;
  }
  return false;
}


He mantenido los pines  de conexión 0 y 1  pero no ha funcionado, sigue sin salir nada coherente.
El código no es mio, lo saqué de un post de este foro, estoy buscando el enlace pero todavía no lo he encontrado.
Gracias.

_Manu_

He probado este otro código que por lo que entiendo imprime por puerto serie la trama de datos que manda el GPS, aun con este código solo recibo dos líneas:
Code: [Select]
0.4,M,51.6,M,2.0,0000*6A
$GPÿ


El código es:
Code: [Select]
void setup()
{
  Serial.begin(4800);
}
void loop()
{
  byte a;
    if ( Serial.available() > 0 )
  {
    a = Serial.read(); // get the byte of data from the GPS
    Serial.write(a);
  }
}

Fuente

El COM3 está a 4800 baudios. Como he comentado no he usado adaptador de tensión y el GPS es de 0V a 3V ¿Puede ser que no detecte bien los bits?. Gracias.
Un saludo.

surbyte

#10
Apr 18, 2016, 02:19 pm Last Edit: Apr 18, 2016, 02:24 pm by surbyte
Los pines del Serial1 estan indicados en el propio MEGA. Lo digo para que no pienses en otros pines que no sean 18 y 19. Mira que representa cada uno. RX = 19 y TX = 18  


Quote
Serial: 0 (RX) and 1 (TX); Serial 1: 19 (RX) and 18 (TX); Serial 2: 17 (RX) and 16 (TX); Serial 3: 15 (RX) and 14 (TX). Used to receive (RX) and transmit (TX) TTL serial data. Pins 0 and 1 are also connected to the corresponding pins of the USB-to-TTL Serial chip.
Ese código que pussiste en el post anterior es para comunicarte con el monitor serie de la PC no para conectarte con el GPS aun cuando lo conectes a 0,1

Veamos, reformulemos el código para usarlo con Serial1.

Code: [Select]
void setup() {
  Serial.begin(9600);   // puerto para el monitor serie. Corregir Baudios según corresponda
  Serial1.begin(4800);  // este es el puerto con el que leo el GPS
}
void loop()
{
  byte a;
    if ( Serial1.available() > 0 ) {  // Hay datos en el GPS?
       a = Serial1.read();            // Leo byte del GPS
       Serial.write(a);
  }
}

Tal vez tu GPS sea 5V tolerante, no lo se. Pero puedes usar este simple arreglo de resistencias para RX que es el que esta comprometido en todo caso

Bueno el esquema muestra un NANO pero usando SoftwareSerial. Cosa que no importa. veamos la idea.
La idea es que el NANO tiene saldias TTL a 5V y el ESP8266 similar a tu GPS en cuanto a que usa 3.3V requiere esos niveles en algun caso.
El único a cuidar es lo que recibe el GPS y es justamente su conexión RX que ya ves tiene un divisor de 1K y 2K.
La salida TX del GPS a 3V no afecta la entrada del MEGA ya que un nivel alto 3V se considera dentro de los niveles HIGH para un TTL 5V.
No olvides unir tambine GND en ambos dispositivos.

_Manu_

#11
Apr 19, 2016, 02:24 pm Last Edit: Apr 19, 2016, 02:35 pm by _Manu_
Gracias por la respuesta. Ahora entiendo con el código que has puesto el funcionamiento no entendía muy bien como iban a funcionar los dos por el mismo puerto.
He hecho el divisor de tensión y no me ha funcionado, he probado dos opciones poner dos resistencias como sugerías, y poner un potenciómetro ajustado para que diera 3V (He conectado todas las masas al mismo punto), con ambas opciones no daba nada el COM3 ajustándolo a 9600 baudios.
He probado a conectarlo sin el divisor, cuando el GPS ha cogido señal (luz roja parpadeando) por el COM3  no aparecía nada pero la barra de desplazamiento inferior de la ventana se desplaza pero no aparecía ningún dato como si el formato de la letra fuera blanco, no se si me entendéis, eso a 9600 baudios. Bajaba la velocidad a 4800 baudios y aparecía símbolos en la misma línea y siempre los mismos símbolos.
Con la conexión directa, el LED TX del Arduino se enciende parpadea muy rápido, osea que emite datos.
Todo conectando el TX Del GPS al 18 y el RX el 19 del Arduino como corresponde para el divisor y cuando eh probado sin el divisor el RX del GPS al Pin 19.
Para comprobar que el GPS está bien ¿Sería factible ver con un osciloscopio las tramas del GPS?.
Gracias.

surbyte

#12
Apr 19, 2016, 02:40 pm Last Edit: Apr 19, 2016, 02:58 pm by surbyte
Espero no hayas cometido este estúpido error!!
Supongo que has conectado el GND del GPS al GND del arduino no?

Ahora te leo que cambias velocidades BAUD como si nada, eso requiere hacer lo propio en el GPS, lo has hecho supongo?



El esquema de este sitio no sugiere adaptaciones de niveles 
Este otro sitio tampoco.

_Manu_

Gracias por la ayuda.  Si si, he conectado la masa del GPS (ambas por si acaso, tiene 2) al Arduino,la conexión está como en la página de wiring que has puesto, pongo como he hecho la conexión:


Cambio los baudios del COM3, era para probar, si cambiaba los baudios del Serial (monitor serie) por ejemplo a 4800 también, no me aparecía nada solo se desplazaba la barra de desplazamiento como ocurría a 9600.

Mi profesor me ha comentado que la salida suele ser de 3.3V, tiene sentido que sea así ya que al aplicar el divisor de tensión se baja la tensión 1.65V e igual no lo detecta, será por eso que se tiene que poner directo.

El GPS forma parte de mi proyecto de fin de grado, estoy haciendo un sistema de telemetría.
Gracias.

Saludos.


surbyte

Noo nooo nooo.
El divisor es para la salida TX del Arduino en 5v y la entrada RX del GPS que admite 3.3V no para otra salida/entrada.
Te lo puse claramente en el esquema.

Go Up